luerl-1.2.3/0000775000175000017500000000000014677012037013227 5ustar debalancedebalanceluerl-1.2.3/rebar.config0000664000175000017500000000101414677012037015505 0ustar debalancedebalance%% -*- mode: erlang; indent-tabs-mode: nil -*- {erl_opts, [debug_info]}. {deps, []}. {shell, [ % {config, "config/sys.config"}, {apps, [luerl]} ]}. {relx, [{release, {luerl, "1.2.3"}, [kernel, stdlib, sasl, inets, luerl]}, {dev_mode, false}, {include_erts, true}, {extended_start_script, true}]}. {profiles, [ {test, [ {dist_node, [ {setcookie, 'ct'}, {sname, 'ct'} ]}, {ct_opts, [{logdir, "logs"}]} ]} ]}. luerl-1.2.3/src/0000775000175000017500000000000014677012037014016 5ustar debalancedebalanceluerl-1.2.3/src/luerl_sup.erl0000664000175000017500000000351414677012037016537 0ustar debalancedebalance%% Copyright (c) 2013-2021 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. -module(luerl_sup). -behaviour(supervisor). %% API -export([start_link/0]). %% Supervisor callbacks -export([init/1]). -define(SERVER, ?MODULE). %% =================================================================== %% API functions %% =================================================================== start_link() -> supervisor:start_link({local, ?SERVER}, ?MODULE, []). %% =================================================================== %% Supervisor callbacks %% =================================================================== %% sup_flags() = #{strategy => strategy(), % optional %% intensity => non_neg_integer(), % optional %% period => pos_integer()} % optional %% child_spec() = #{id => child_id(), % mandatory %% start => mfargs(), % mandatory %% restart => restart(), % optional %% shutdown => shutdown(), % optional %% type => worker(), % optional %% modules => modules()} % optional init([]) -> SupFlags = #{strategy => one_for_one, intensity => 5, period => 10}, ChildSpecs = [], {ok, {SupFlags, ChildSpecs}}. %% internal functions luerl-1.2.3/src/ttsets.erl0000664000175000017500000002731614677012037016061 0ustar debalancedebalance%% Copyright (c) 2013 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : ttsets.erl %% Author : Robert Virding %% Purpose : Set as a 2-3 tree. %% This implementation uses 2-3 trees. The description of the tree %% restructuring which is used comes from Prof. Lyn Turbak's notes for %% CS230 Data Structures at Wellesley College. -module(ttsets). %% Standard interface. -export([new/0,is_set/1,size/1,to_list/1,from_list/1]). -export([is_element/2,add_element/2,del_element/2]). -export([union/2,union/1,intersection/2,intersection/1]). -export([is_disjoint/2,subtract/2,is_subset/2]). -export([fold/3,filter/2]). %% Extended interface. -export([foreach/2]). -compile({no_auto_import,[size/1]}). %We mean our own size/1 -ifdef(DEBUG). -export([check_depth/1]). -endif. %% Data structure: %% - {Left,Element,Right} %% - {Left,Element,Middle,Element,Right} %% - empty %% %% The term order is an arithmetic total order, so we should not %% test exact equality for the keys. (If we do, then it becomes %% possible that neither `>', `<', nor `=:=' matches.) Testing '<' %% and '>' first is statistically better than testing for %% equality, and also allows us to skip the test completely in the %% remaining case. -type ttset() :: empty | {ttset(),any(),ttset()} | {ttset(),any(),ttset(),any(),ttset()}. -export_type([ttset/0]). -spec new() -> Set::ttset(). %% Return a new empty set. new() -> empty. %The empty set -spec is_set(Set::ttset()) -> boolean(). %% Return 'true' if Set is a set, else 'false'. is_set(empty) -> true; is_set({A,_,B}) -> is_set(A) andalso is_set(B); is_set({A,_,B,_,C}) -> is_set(A) andalso is_set(B) andalso is_set(C); is_set(_) -> false. -spec size(Set::ttset()) -> non_neg_integer(). %% Return the number of elements in Set. size(empty) -> 0; size({A,_,B}) -> size(A) + size(B) + 1; size({A,_,B,_,C}) -> size(A) + size(B) + size(C) + 2. -spec to_list(Set::ttset()) -> [Element::any()]. %% Return the elements in Set as a list. to_list(D) -> to_list(D, []). to_list(empty, Tail) -> Tail; to_list({A,X,B}, Tail) -> to_list(A, [X|to_list(B, Tail)]); to_list({A,X,B,Y,C}, Tail) -> to_list(A, [X|to_list(B, [Y|to_list(C, Tail)])]). -spec from_list([Element::any()]) -> Dict::ttset(). %% Build a set from the elements in list. from_list(List) -> lists:foldl(fun (E, S) -> add_element(E, S) end, new(), List). -spec is_element(Element::any(), Set::ttset()) -> boolean(). %% Return 'true' if Element is an element of Set, else 'false'. is_element(_, empty) -> false; is_element(E, {A,X,_}) when E < X -> is_element(E, A); is_element(E, {_,X,B}) when E > X -> is_element(E, B); is_element(_, {_,_,_}) -> true; is_element(E, {A,X,_,_,_}) when E < X -> is_element(E, A); is_element(E, {_,X,B,Y,C}) when E > X -> if E < Y -> is_element(E, B); %Middle E > Y -> is_element(E, C); %Right true -> true end; is_element(_, {_,_,_,_,_}) -> true. -spec add_element(Element::any(), Set::ttset()) -> Set::ttset(). %% Return Set with Element inserted in it. add_element(E, T) -> %% Store and check for a returned "Up" node. case add_aux(E, T) of {up,Lu,Eu,Ru} -> {Lu,Eu,Ru}; Node -> Node end. add_aux(E, empty) -> {up,empty,E,empty}; %"Up" node add_aux(E, {empty,X,empty}=N) -> %% Special case to avoid creating temporary "up" nodes. %% It helps a little bit, but not much. if E < X -> {empty,E,empty,X,empty}; E > X -> {empty,X,empty,E,empty}; true -> N end; add_aux(E, {A,X,B}=N) -> if E < X -> %Down the left add_up2_l(add_aux(E, A), X, B); E > X -> %Down the right add_up2_r(A, X, add_aux(E, B)); true -> N %Replace current value end; add_aux(E, {A,X,B,Y,C}) when E < X -> add_up3_l(add_aux(E, A), X, B, Y, C); add_aux(E, {A,X,B,Y,C}=N) when E > X -> if E < Y -> %Down the middle add_up3_m(A, X, add_aux(E, B), Y, C); E > Y -> %Down the right add_up3_r(A, X, B, Y, add_aux(E, C)); true -> N end; add_aux(_, {_,_,_,_,_}=N) -> N. %% add_up2_l/r(L, X, R) -> {L,X,M,X,R} | {L,X,R}. add_up2_l({up,Lu,X,Ru}, Y, R) -> {Lu,X,Ru,Y,R}; add_up2_l(L, X, R) -> {L,X,R}. add_up2_r(L, X, {up,Lu,Y,Ru}) -> {L,X,Lu,Y,Ru}; add_up2_r(L, X, R) -> {L,X,R}. %% add_up3_l/m/r(L, X, M, Y, R) -> %% {up,L,X,R} | {L,X,M,Y,R}. add_up3_l({up,Lu,X,Ru}, Y, M, Z, R) -> {up,{Lu,X,Ru},Y,{M,Z,R}}; add_up3_l(L, X, M, Y, R) -> {L,X,M,Y,R}. add_up3_m(L, X, {up,Lu,Y,Ru}, Z, R) -> {up,{L,X,Lu},Y,{Ru,Z,R}}; add_up3_m(L, X, M, Y, R) -> {L,X,M,Y,R}. add_up3_r(L, X, M, Y, {up,Lu,Z,Ru}) -> {up,{L,X,M},Y,{Lu,Z,Ru}}; add_up3_r(L, X, M, Y, R) -> {L,X,M,Y,R}. -spec del_element(Element::any(), Set::ttset()) -> Set::ttset(). %% Return Set but with Element removed. del_element(E, T) -> case del_aux(E, T) of {up,T1} -> T1; T1 -> T1 end. del_aux(_, empty) -> empty; %No element del_aux(E, {empty,X,empty}=N) -> if E < X; E > X -> N; %No element true -> {up,empty} end; del_aux(E, {A,X,B}) -> if E < X -> %Down the left del_up2_l(del_aux(E, A), X, B); E > X -> %Down the right del_up2_r(A, X, del_aux(E, B)); true -> {Bm,B1}= del_min(B), del_up2_r(A, Bm, B1) end; del_aux(E, {empty,X,empty,Y,empty}=N) -> if E < X -> N; %No element E > X -> if E < Y -> N; %No element E > Y -> N; true -> {empty,X,empty} end; true -> {empty,Y,empty} end; del_aux(E, {A,X,B,Y,C}) when E < X -> del_up3_l(del_aux(E, A), X, B, Y, C); del_aux(E, {A,X,B,Y,C}) when E > X -> if E < Y -> del_up3_m(A, X, del_aux(E, B), Y, C); E > Y -> del_up3_r(A, X, B, Y, del_aux(E, C)); true -> {Cm,C1} = del_min(C), del_up3_r(A, X, B, Cm, C1) end; del_aux(_, {A,_,B,Y,C}) -> {Bm,B1} = del_min(B), del_up3_m(A, Bm, B1, Y, C). del_min(T) -> %%io:format("em: ~p\n-> ~p\n", [T,T1]), del_min1(T). del_min1({empty,X,empty}) -> {X,{up,empty}}; del_min1({A,X,B}) -> {Min,A1} = del_min1(A), {Min,del_up2_l(A1, X, B)}; del_min1({empty,X,empty,Y,empty}) -> {X,{empty,Y,empty}}; del_min1({A,X,B,Y,C}) -> {Min,A1} = del_min1(A), {Min,del_up3_l(A1, X, B, Y, C)}. %% del_up2_l/r(L, X, R) -> Node | {up,Node}. %% We use the same naming of nodes and keys as in the text. It makes %% checking the rules easier. del_up2_l({up,L}, X, {M,Y,R}) -> %1.1 {up,{L,X,M,Y,R}}; del_up2_l({up,A}, X, {B,Y,C,Z,D}) -> %2.1 {{A,X,B},Y,{C,Z,D}}; del_up2_l(L, X, R) -> {L,X,R}. del_up2_r({L,X,M}, Y, {up,R}) -> %1.2 {up,{L,X,M,Y,R}}; del_up2_r({A,X,B,Y,C}, Z, {up,D}) -> %2.2 {{A,X,B},Y,{C,Z,D}}; del_up2_r(L, X, R) -> {L,X,R}. %% del_up2_r(L, X, {up,R}) -> del_up2_r1(L, X, R); %% del_up2_r(L, X, R) -> {L,K,V,R}. %% del_up2_r1({L,X,M}, Y, R) -> %1.2 %% {up,{L,X,M,Y,R}}; %% del_up2_r1({A,X,B,Y,C}, Z, D) -> %2.2 %% {{A,X,B},Y,{C,Z,D}}. %% del_up3_l/m/r(L, X, M, Y, R) -> Node | {up,Node}. %% We use the same naming of nodes and keys as in the text. It makes %% checking the rules easier. N.B. there are alternate valid choices %% for the middle case! del_up3_l({up,A}, X, {B,Y,C}, Z, D) -> %3a.1 {{A,X,B,Y,C},Z,D}; del_up3_l({up,A}, W, {B,X,C,Y,D}, Z, E) -> %4a.1 {{A,W,B},X,{C,Y,D},Z,E}; del_up3_l(A, X, B, Y, C) -> {A,X,B,Y,C}. del_up3_m({A,X,B}, Y, {up,C}, Z, D) -> %3a.2 {{A,X,B,Y,C},Z,D}; del_up3_m(A, X, {up,B}, Y, {C,Z,D}) -> %3b.1 {A,X,{B,Y,C,Z,D}}; del_up3_m({A,W,B,X,C}, Y, {up,D}, Z, E) -> %4a.2 {{A,W,B},X,{C,Y,D},Z,E}; del_up3_m(A, W, {up,B}, X, {C,Y,D,Z,E}) -> %4b.1 {A,W,{B,X,C},Y,{D,Z,E}}; del_up3_m(A, X, B, Y, C) -> {A,X,B,Y,C}. del_up3_r(A, X, {B,Y,C}, Z, {up,D}) -> %3b.2 {A,X,{B,Y,C,Z,D}}; del_up3_r(A, W, {B,X,C,Y,D}, Z, {up,E}) -> %4b.2 {A,W,{B,X,C},Y,{D,Z,E}}; del_up3_r(A, X, B, Y, C) -> {A,X,B,Y,C}. -spec union(Set1::ttset(), Set2::ttset()) -> Set::ttset(). %% Return the union of Set1 and Set2. union(S1, S2) -> fold(fun (E, S) -> add_element(E, S) end, S2, S1). -spec union(Sets::[ttset()]) -> Set::ttset(). %% Return the union of the list of sets. union([S1,S2|Ss]) -> %% Do our own unions here to try and fold over smaller set. U0 = union(Ss), U1 = fold(fun (E, S) -> add_element(E, S) end, U0, S2), fold(fun (E, S) -> add_element(E, S) end, U1, S1); union([S]) -> S; union([]) -> empty. -spec intersection(Set1::ttset(), Set2::ttset()) -> Set::ttset(). %% Return the intersection of Set1 and Set2. intersection(S1, S2) -> filter(fun (E) -> is_element(E, S1) end, S2). -spec intersection(Sets::[ttset()]) -> Set::ttset(). %% Return the intersection of the list of sets. intersection([S]) -> S; intersection([S|Ss]) -> lists:foldl(fun (S1, I) -> intersection(S1, I) end, S, Ss). -spec is_disjoint(Set1::ttset(), Set2::ttset()) -> boolean(). %% Check whether Set1 and Set2 are disjoint. is_disjoint(S1, S2) -> fold(fun (E, Dis) -> Dis andalso (not is_element(E, S2)) end, true, S1). -spec subtract(Set1::ttset(), Set2::ttset()) -> Set::ttset(). %% Return all and only the elements in Set1 which are not elements of Set2. subtract(S1, S2) -> filter(fun (E) -> not is_element(E, S2) end, S1). -spec is_subset(Set1::ttset(), Set2::ttset()) -> boolean(). %% Return 'true' when every element of Set1 is also an element of %% Set2, else 'false'. is_subset(S1, S2) -> fold(fun (E, Sub) -> Sub andalso is_element(E, S2) end, true, S1). -spec fold(Fun::fun(), Acc::any(), Set::ttset()) -> any(). %% Apply Fun to each element in Set. Do it left to right, even if %% this is not specified. fold(_, Acc, empty) -> Acc; fold(F, Acc0, {A,X,B}) -> Acc1 = F(X, fold(F, Acc0, A)), fold(F, Acc1, B); fold(F, Acc0, {A,X,B,Y,C}) -> Acc1 = F(X, fold(F, Acc0, A)), Acc2 = F(Y, fold(F, Acc1, B)), fold(F, Acc2, C). -spec filter(Fun::fun(), Set::ttset()) -> Set::ttset(). %% Apply Fun to each element in Dict. Do it left to right, even if %% this is not specified. filter(F, S) -> filter(F, S, new()). filter(_, empty, New) -> New; filter(F, {A,X,B}, New0) -> New1 = filter(F, A, New0), New2 = case F(X) of true -> add_element(X, New1); false -> New1 end, filter(F, B, New2); filter(F, {A,X,B,Y,C}, New0) -> New1 = filter(F, A, New0), New2 = case F(X) of true -> add_element(X, New1); false -> New1 end, New3 = filter(F, B, New2), New4 = case F(Y) of true -> add_element(Y, New3); false -> New3 end, filter(F, C, New4). %% Extended interface. -spec foreach(Fun::fun(), Set::ttset()) -> ok. %% Apply Fun to each element in Set. Do it left to right, even if %% this is not specified. foreach(_, empty) -> ok; foreach(F, {A,X,B}) -> foreach(F, A), F(X), foreach(F, B); foreach(F, {A,X,B,Y,C}) -> foreach(F, A), F(X), foreach(F, B), F(Y), foreach(F, C). -ifdef(DEBUG). %% Check the depth of all the leaves, should all be the same. check_depth(T) -> check_depth(T, 1, orddict:new()). check_depth(empty, D, Dd) -> orddict:update_counter(D, 1, Dd); check_depth({L,_,R}, D, Dd0) -> Dd1 = orddict:update_counter(two, 1, Dd0), Dd2 = check_depth(L, D+1, Dd1), check_depth(R, D+1, Dd2); check_depth({L,_,M,_,R}, D, Dd0) -> Dd1 = orddict:update_counter(three, 1, Dd0), Dd2 = check_depth(L, D+1, Dd1), Dd3 = check_depth(M, D+1, Dd2), check_depth(R, D+1, Dd3). -endif. luerl-1.2.3/src/luerl_heap.erl0000664000175000017500000006716614677012037016662 0ustar debalancedebalance%% Copyright (c) 2020-2024 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_heap.erl %% Author : Robert Virding %% Purpose : Implements the heap section of the Luerl state. %% %% Note that here we only handle the data in the heap and never call %% anything in either Luerl or Erlang. Those cases where this could %% happen we return values informing the caller to do it. For example %% in the set_table_key and get_table_key functions. -module(luerl_heap). -include("luerl.hrl"). -export([init/0]). %% External interface. -export([gc/1, alloc_table/1,alloc_table/2,free_table/2, get_table/2,set_table/3,upd_table/3,chk_table/2, get_global_key/2,set_global_key/3, get_table_key/3,set_table_key/4, raw_get_table_key/3,raw_set_table_key/4, alloc_userdata/2,alloc_userdata/3,free_userdata/2, get_userdata/2,set_userdata/3,upd_userdata/3,chk_userdata/2, set_userdata_data/3,get_userdata_data/2, alloc_funcdef/2,get_funcdef/2,set_funcdef/3, alloc_environment/2,get_env_var/3,set_env_var/4, get_metamethod/3,get_metamethod/4, get_metatable/2, set_metatable/3 ]). -import(luerl_lib, [lua_error/2,badarg_error/3]). %% init() -> State %% %% Initialise the heap section of the state and return the state. init() -> St0 = #luerl{meta=#meta{},tag=make_ref()}, init_tables(St0). init_tables(St) -> %% Initialise the table handling. Tst = init_tstruct(), %% Initialise the environment handling. Est = init_tstruct(), %% Initialise the userdata handling. Ust = init_tstruct(), %% Initialise the function def handling. Fst = init_tstruct(), St#luerl{tabs=Tst,envs=Est,usds=Ust,fncs=Fst}. %% init_tstruct() -> #tstruct{}. %% alloc_tstruct(Val, #tstruct{}) -> {Index,#tstruct{}}. %% set_tstruct(Index, Val, #tstruct{}) -> #tstruct{}. %% upd_tstruct(Index, UpdFun, #tstruct{}) -> #tstruct{}. %% del_tstruct(Index, #tstruct{}) -> #tstruct{}. %% chk_tstruct(Index, #tstruct{}) -> ok | error. %% %% Functions for accessing tstructs. init_tstruct() -> #tstruct{data=?MAKE_TABLE(),free=[],next=0}. alloc_tstruct(Val, #tstruct{data=D0,free=[N|Ns]}=Tstr) -> D1 = ?SET_TABLE(N, Val, D0), {N,Tstr#tstruct{data=D1,free=Ns}}; alloc_tstruct(Val, #tstruct{data=D0,free=[],next=N}=Tstr) -> D1 = ?SET_TABLE(N, Val, D0), {N,Tstr#tstruct{data=D1,next=N+1}}. set_tstruct(N, Val, #tstruct{data=D0}=Tstr) -> D1 = ?SET_TABLE(N, Val, D0), Tstr#tstruct{data=D1}. upd_tstruct(N, Upd, #tstruct{data=D0}=Tstr) -> D1 = ?UPD_TABLE(N, Upd, D0), Tstr#tstruct{data=D1}. del_tstruct(N, #tstruct{data=D0,free=Ns}=Tstr) -> D1 = ?DEL_TABLE(N, D0), Tstr#tstruct{data=D1,free=[N|Ns]}. -compile({inline,[get_tstruct/2]}). %Such a simple function get_tstruct(N, Tstr) -> ?GET_TABLE(N, Tstr#tstruct.data). chk_tstruct(N, Tstr) -> case ?CHK_TABLE(N, Tstr#tstruct.data) of true -> ok; false -> error end. %% alloc_table(State) -> {Tref,State} %% %% Allocate an empty table. alloc_table(St) -> alloc_table([], St). %% alloc_table(InitialTable, State) -> {Tref,State} %% %% The InitialTable is [{Key,Value}] or map, there is no longer any %% need to have it as an orddict. alloc_table(Itab, #luerl{tabs=Tst0}=St) -> Tab = create_table(Itab), {N,Tst1} = alloc_tstruct(Tab, Tst0), {#tref{i=N},St#luerl{tabs=Tst1}}. create_table(Itab) when is_map(Itab) -> create_table(maps:to_list(Itab)); create_table(Itab) -> D0 = ttdict:new(), A0 = array:new([{default,nil}]), %Arrays with 'nil' as default Init = fun ({_,nil}, {D,A}) -> {D,A}; %Ignore nil values ({K,V}, {D,A}) when is_integer(K), K >= 1 -> {D,array:set(K, V, A)}; ({K,V}, {D,A}) when is_float(K) -> case ?IS_FLOAT_INT(K, I) of true when I >= 1 -> {D,array:set(I, V, A)}; _NegFalse -> {ttdict:store(K, V, D),A} end; ({K,V}, {D,A}) -> {ttdict:store(K, V, D),A} end, {D1,A1} = lists:foldl(Init, {D0,A0}, Itab), #table{a=A1,d=D1,meta=nil}. %% free_table(Tref, State) -> State %% %% Delete a table freeing its space. free_table(#tref{i=N}, #luerl{tabs=Tst0}=St) -> Tst1 = del_tstruct(N, Tst0), St#luerl{tabs=Tst1}. %% get_table(Tref, State) -> Table %% %% Get the table referred to by Tref. get_table(#tref{i=N}, #luerl{tabs=Tst}) -> get_tstruct(N, Tst). %% set_table(Tref, Table, State) -> State %% %% Set a new table at the location referred to by Tref %% overwriting the existing one. set_table(#tref{i=N}, Tab, #luerl{tabs=Tst0}=St) -> Tst1 = set_tstruct(N, Tab, Tst0), St#luerl{tabs=Tst1}. %% upd_table(Tref, Fun, State) -> State %% %% Update the table at the location referred to by Tref. upd_table(#tref{i=N}, Upd, #luerl{tabs=Tst0}=St) -> Tst1 = upd_tstruct(N, Upd, Tst0), St#luerl{tabs=Tst1}. %% chk_table(Tref, State) -> ok | error. %% %% Check the table referenced by Tref actually exists. chk_table(#tref{i=N}, #luerl{tabs=Tst}) -> chk_tstruct(N, Tst). %% set_global_key(Key, Value, State) -> %% {value,Value,State} | {meta,Method,Args,State} | {error,Error,State} %% %% Set a key in the global name table _G to value. set_global_key(Key, Val, #luerl{g=G}=St) -> set_table_key(G, Key, Val, St). %% get_global_key(Key, State) -> %% {value,Value,State} | {meta,Method,Args,State} | {error,Error,State} %% %% Get the value of a key in the global name table, _G. get_global_key(Key, #luerl{g=G}=St) -> get_table_key(G, Key, St). %% set_table_key(Table, Key, Val, State) -> %% {value,Value,State} | {meta,Method,Args,State} | {error,Error,State} %% %% We don't make calls to meta methods or generate errors but %% return a value indicating this. Setting a value to 'nil' will clear %% it from the table and the array. We won't add a nil value. set_table_key(#tref{}=Tref, Key, Val, St) when is_integer(Key), Key >= 1 -> set_table_key_int(Tref, Key, Key, Val, St); set_table_key(#tref{}=Tref, Key, Val, St) when is_float(Key) -> case ?IS_FLOAT_INT(Key, I) of true when I >= 1 -> set_table_key_int(Tref, Key, I, Val, St); _NegFalse -> set_table_key_key(Tref, Key, Val, St) end; set_table_key(Tab, nil=Key, _, St) -> {error,{illegal_index,Tab,Key},St}; set_table_key(#tref{}=Tref, Key, Val, St) -> set_table_key_key(Tref, Key, Val, St); set_table_key(Other, Key, Val, St) -> Meta = get_metamethod(Other, <<"__newindex">>, St), %% io:format("stk ~p ~p ~p -> ~p\n", [Other,Key,Val,aMeta]), case Meta of nil -> {error,{illegal_index,Other,Key},St}; Meth when ?IS_FUNCTION(Meth) -> {meta,Meth,[Other,Key,Val],St}; Meth -> %Recurse down the metatable set_table_key(Meth, Key, Val, St) end. set_table_key_key(#tref{i=N}=Tab, Key, Val, #luerl{tabs=Tst0}=St) -> Ts0 = Tst0#tstruct.data, #table{d=Dict0,meta=Meta}=T = ?GET_TABLE(N, Ts0), case ttdict:find(Key, Dict0) of {ok,_} -> %Key exists Dict1 = if Val =:= nil -> ttdict:erase(Key, Dict0); true -> ttdict:store(Key, Val, Dict0) end, Ts1 = ?SET_TABLE(N, T#table{d=Dict1}, Ts0), Tst1 = Tst0#tstruct{data=Ts1}, {value,[],St#luerl{tabs=Tst1}}; error -> %Key does not exist case get_metamethod_tab(Meta, <<"__newindex">>, Ts0) of nil -> %% Only add non-nil value. Dict1 = if Val =:= nil -> Dict0; true -> ttdict:store(Key, Val, Dict0) end, Ts1 = ?SET_TABLE(N, T#table{d=Dict1}, Ts0), Tst1 = Tst0#tstruct{data=Ts1}, {value,[],St#luerl{tabs=Tst1}}; Meth when ?IS_FUNCTION(Meth) -> {meta,Meth,[Tab,Key,Val],St}; Meth -> set_table_key(Meth, Key, Val, St) end end. set_table_key_int(#tref{i=N}=Tab, Key, I, Val, #luerl{tabs=Tst0}=St) -> Ts0 = Tst0#tstruct.data, #table{a=Arr0,meta=Meta}=T = ?GET_TABLE(N, Ts0), case array:get(I, Arr0) of nil -> %Key does not exist case get_metamethod_tab(Meta, <<"__newindex">>, Ts0) of nil -> %% Only add non-nil value, slightly faster (?) Arr1 = if Val =:= nil -> Arr0; true -> array:set(I, Val, Arr0) end, Ts1 = ?SET_TABLE(N, T#table{a=Arr1}, Ts0), Tst1 = Tst0#tstruct{data=Ts1}, {value,[],St#luerl{tabs=Tst1}}; Meth when ?IS_FUNCTION(Meth) -> {meta,Meth,[Tab,Key,Val],St}; Meth -> set_table_key(Meth, Key, Val, St) end; _ -> %Key exists %% Can do this as 'nil' is default value of array. Arr1 = array:set(I, Val, Arr0), Ts1 = ?SET_TABLE(N, T#table{a=Arr1}, Ts0), Tst1 = Tst0#tstruct{data=Ts1}, {value,[],St#luerl{tabs=Tst1}} end. %% get_table_key(Table, Key, State) -> %% {value,Value,State} | {meta,Method,Args,State} | {error,Error,State} %% %% We don't make calls to meta methods or generate errors but %% return value indicating this. get_table_key(#tref{}=Tref, Key, St) when is_integer(Key), Key >= 1 -> get_table_key_int(Tref, Key, Key, St); get_table_key(#tref{}=Tref, Key, St) when is_float(Key) -> case ?IS_FLOAT_INT(Key, I) of true when I >= 1 -> get_table_key_int(Tref, Key, I, St); _NegFalse -> get_table_key_key(Tref, Key, St) end; get_table_key(#tref{}=Tref, Key, St) -> get_table_key_key(Tref, Key, St); get_table_key(Other, Key, St) -> %Just find the metamethod Meta = get_metamethod(Other, <<"__index">>, St), %% io:format("gtk ~p ~p -> ~p\n", [Other,Key,Meta]), case Meta of nil -> {error,{illegal_index,Other,Key},St}; Meth when ?IS_FUNCTION(Meth) -> {meta,Meth,[Other,Key],St}; Meth -> %Recurse down the metatable get_table_key(Meth, Key, St) end. get_table_key_key(#tref{i=N}=Tab, Key, #luerl{tabs=#tstruct{data=Ts}}=St) -> #table{d=Dict,meta=Meta} = ?GET_TABLE(N, Ts), case ttdict:find(Key, Dict) of {ok,Val} -> {value,Val,St}; error -> %% Key not present so try metamethod get_table_key_metamethod(Tab, Meta, Key, Ts, St) end. get_table_key_int(#tref{i=N}=T, Key, I, #luerl{tabs=#tstruct{data=Ts}}=St) -> #table{a=A,meta=Meta} = ?GET_TABLE(N, Ts), %Get the table. case array:get(I, A) of nil -> %% Key not present so try metamethod get_table_key_metamethod(T, Meta, Key, Ts, St); Val -> {value,Val,St} end. get_table_key_metamethod(Tab, Meta, Key, Ts, St) -> case get_metamethod_tab(Meta, <<"__index">>, Ts) of nil -> {value,nil,St}; Meth when ?IS_FUNCTION(Meth) -> {meta,Meth,[Tab,Key],St}; Meth -> %Recurse down the metatable get_table_key(Meth, Key, St) end. %% raw_get_table_key(Table, Key, State) -> Value. %% raw_set_table_key(Table, Key, Value, State) -> State. %% %% Get/set key values in tables without metamethods. raw_get_table_key(#tref{i=N}, Key, #luerl{tabs=Tst}) when is_integer(Key), Key >= 1 -> raw_get_table_key_int(N, Key, Tst); raw_get_table_key(#tref{i=N}, Key, #luerl{tabs=Tst}) when is_float(Key) -> case ?IS_FLOAT_INT(Key, I) of true when I >= 1 -> raw_get_table_key_int(N, I, Tst); _NegFalse -> raw_get_table_key_key(N, Key, Tst) end; raw_get_table_key(#tref{i=N}, Key, #luerl{tabs=Tst}) -> raw_get_table_key_key(N, Key, Tst). raw_get_table_key_key(N, Key, Tst) -> #table{d=Dict} = get_tstruct(N, Tst), case ttdict:find(Key, Dict) of {ok,Val} -> Val; error -> nil end. raw_get_table_key_int(N, Key, Tst) -> #table{a=Arr} = get_tstruct(N, Tst), array:get(Key, Arr). raw_set_table_key(#tref{}=Tref, Key, Val, #luerl{tabs=Tst0}=St) when is_integer(Key), Key >= 1 -> Tst1 = raw_set_table_key_int(Tref, Key, Val, Tst0), St#luerl{tabs=Tst1}; raw_set_table_key(#tref{}=Tref, Key, Val, #luerl{tabs=Tst0}=St) when is_float(Key) -> Tst1 = case ?IS_FLOAT_INT(Key, I) of true when I >= 1 -> raw_set_table_key_int(Tref, I, Val, Tst0); _NegFalse -> raw_set_table_key_key(Tref, Key, Val, Tst0) end, St#luerl{tabs=Tst1}; raw_set_table_key(#tref{}=Tref, Key, Val, #luerl{tabs=Tst0}=St) -> Tst1 = raw_set_table_key_key(Tref, Key, Val, Tst0), St#luerl{tabs=Tst1}. raw_set_table_key_key(#tref{i=N}, Key, Val, Tst0) -> Fun = fun (#table{d=Dict0}=Tab) -> Dict1 = if Val =:= nil -> ttdict:erase(Key, Dict0); true -> ttdict:store(Key, Val, Dict0) end, Tab#table{d=Dict1} end, upd_tstruct(N, Fun, Tst0). raw_set_table_key_int(#tref{i=N}, Key, Val, Tst0) -> Fun = fun (#table{a=Arr0}=Tab) -> %% Default array value is nil. Arr1 = array:set(Key, Val, Arr0), Tab#table{a=Arr1} end, upd_tstruct(N, Fun, Tst0). %% alloc_userdata(Data, State) -> {Usdref,State} %% %% Allocate userdata with empty metadata. alloc_userdata(Data, St) -> alloc_userdata(Data, nil, St). %% alloc_userdata(Data, Meta, State) -> {Usdref,State}. %% %% Allocate userdata setting its metadata. alloc_userdata(Data, Meta, #luerl{usds=Ust0}=St) -> Ud = #userdata{d=Data,meta=Meta}, {N,Ust1} = alloc_tstruct(Ud, Ust0), {#usdref{i=N},St#luerl{usds=Ust1}}. %% free_userdata(Usdref, State) -> State %% %% Delete a table freeing its space. free_userdata(#usdref{i=N}, #luerl{usds=Ust0}=St) -> Ust1 = del_tstruct(N, Ust0), St#luerl{usds=Ust1}. %% get_userdata(Usdref, State) -> {UserData,State} %% %% Get the userdata refered to by Usdref, get_userdata(#usdref{i=N}, #luerl{usds=Ust}=St) -> #userdata{} = Udata = get_tstruct(N, Ust), {Udata,St}. %% set_userdata(Usdref, Data, State) -> State %% %% Set a new userdata at the location referred to by Usdref %% overwriting the existing one. set_userdata(#usdref{i=N}, #userdata{}=Udata, #luerl{usds=Ust0}=St) -> Ust1 = set_tstruct(N, Udata, Ust0), St#luerl{usds=Ust1}. %% upd_userdata(Usdref, Fun, State) -> State %% %% Update the data in the userdata referred to by Usdref. upd_userdata(#usdref{i=N}, Upd, #luerl{usds=Ust0}=St) -> Ust1 = upd_tstruct(N, Upd, Ust0), St#luerl{usds=Ust1}. %% chk_userdata(Usdref, State) -> ok | error. %% %% Check the userdata referenced by Tref actually exists. chk_userdata(#usdref{i=N}, #luerl{usds=Ust}) -> chk_tstruct(N, Ust). %% get_userdata_data(Usdref, State) -> {Data,State} %% %% Get the data form the userdata refered to by Usdref. get_userdata_data(#usdref{i=N}, #luerl{usds=Ust}=St) -> Udata = get_tstruct(N, Ust), {Udata#userdata.d,St}. %% set_userdata_data(Usdref, Data, State) -> State %% %% Set a new userdata at the location referred to by Usdref %% overwriting the existing one. set_userdata_data(#usdref{i=N}, Data, #luerl{usds=Ust0}=St) -> Ust1 = upd_tstruct(N, fun (Ud) -> Ud#userdata{d=Data} end, Ust0), St#luerl{usds=Ust1}. %% make_userdata(Data) -> make_userdata(Data, nil). %% make_userdata(Data, Meta) -> #userdata{d=Data,meta=Meta}. %% alloc_funcdef(Def, State) -> {FunRef,State} alloc_funcdef(Func, #luerl{fncs=Fst0}=St) -> {N,Fst1} = alloc_tstruct(Func, Fst0), {#funref{i=N},St#luerl{fncs=Fst1}}. %% get_funcdef(Funref, State) -> {Fdef,State} %% %% Get the function data referred to by Fref. get_funcdef(#funref{i=N}, #luerl{fncs=Fst}=St) -> Fdef = get_tstruct(N, Fst), {Fdef,St}. %% set_funcdef(Funref, Fdef, State) -> State. %% %% Set the function data referred to by Fref. set_funcdef(#funref{i=N}, Func, #luerl{fncs=Fst0}=St) -> Fst1 = set_tstruct(N, Func, Fst0), St#luerl{fncs=Fst1}. %% get_metamethod(Object, Event, State) -> Method | nil %% get_metamethod(Object1, Object2, Event, State) -> Method | nil %% %% Get the metamethod for object(s). get_metamethod(O1, O2, E, St) -> case get_metamethod(O1, E, St) of nil -> get_metamethod(O2, E, St); M -> M end. get_metamethod(O, E, St) -> Meta = get_metatable(O, St), %Can be nil %% io:format("gm ~p ~p -> ~p\n", [O,E,Meta]), get_metamethod_tab(Meta, E, St#luerl.tabs#tstruct.data). get_metamethod_tab(#tref{i=M}, E, Ts) -> #table{d=Mdict} = ?GET_TABLE(M, Ts), case ttdict:find(E, Mdict) of {ok,Mm} -> Mm; error -> nil end; get_metamethod_tab(_, _, _) -> nil. %Other types have no metatables %% get_metatable(Obj, State) -> MetaTable %% %% Get the metatable of an object or its type metatable. get_metatable(#tref{i=T}, #luerl{tabs=Tst}) -> (get_tstruct(T, Tst))#table.meta; get_metatable(#usdref{i=U}, #luerl{usds=Ust}) -> (get_tstruct(U, Ust))#userdata.meta; get_metatable(nil, #luerl{meta=Meta}) -> Meta#meta.nil; get_metatable(B, #luerl{meta=Meta}) when is_boolean(B) -> Meta#meta.boolean; get_metatable(N, #luerl{meta=Meta}) when is_number(N) -> Meta#meta.number; get_metatable(S, #luerl{meta=Meta}) when is_binary(S) -> Meta#meta.string; get_metatable(_, _) -> nil. %Other types have no metatables %% set_metatable(Obj, MetaTable, State) -> State %% %% Set the metatable of an object or its type metatable. set_metatable(#tref{i=N}, M, #luerl{tabs=Tst0}=St) -> Tst1 = upd_tstruct(N, fun (Tab) -> Tab#table{meta=M} end, Tst0), St#luerl{tabs=Tst1}; set_metatable(#usdref{i=N}, M, #luerl{usds=Ust0}=St) -> Ust1 = upd_tstruct(N, fun (Ud) -> Ud#userdata{meta=M} end, Ust0), St#luerl{usds=Ust1}; set_metatable(nil, M, #luerl{meta=Meta0}=St) -> Meta1 = Meta0#meta{nil=M}, St#luerl{meta=Meta1}; set_metatable(B, M, #luerl{meta=Meta0}=St) when is_boolean(B) -> Meta1 = Meta0#meta{boolean=M}, St#luerl{meta=Meta1}; set_metatable(N, M, #luerl{meta=Meta0}=St) when is_number(N) -> Meta1 = Meta0#meta{number=M}, St#luerl{meta=Meta1}; set_metatable(B, M, #luerl{meta=Meta0}=St) when is_binary(B) -> Meta1 = Meta0#meta{string=M}, St#luerl{meta=Meta1}; set_metatable(_, _, St) -> %Do nothing for the rest St. %% alloc_environment(Size, State) -> {Fref,State} %% %% Allocate the environment in the environment table and return %% its eref. alloc_environment(Size, #luerl{envs=Est0}=St) -> Fr = erlang:make_tuple(Size, nil), {N,Est1} = alloc_tstruct(Fr, Est0), {#eref{i=N},St#luerl{envs=Est1}}. %% get_env_var(Eref, Index, State) -> Value. %% set_env_var(Eref, Index, Val, State) -> State. get_env_var(#eref{i=N}, Index, #luerl{envs=Etab}) -> element(Index, get_tstruct(N, Etab)). %% element(Index, ?GET_TABLE(N, Etab#tstruct.data)). set_env_var(#eref{i=N}, Index, Val, #luerl{envs=Est0}=St) -> Est1 = upd_tstruct(N, fun (Fr) -> setelement(Index, Fr, Val) end, Est0), St#luerl{envs=Est1}. %% gc(State) -> State. %% The garbage collector. Its main job is to reclaim unused tables %% and frames. It is a mark/sweep collector which passes over all %% objects and marks tables and frames which it has seen. All unseen %% tables and frames are then freed and their indexes added to the %% free lists. -record(gct, {t,s}). %Gc table info table, seen gc(#luerl{tabs=#tstruct{data=Tt0,free=Tf0}=Tab0, envs=#tstruct{data=Et0,free=Ef0}=Env0, usds=#tstruct{data=Ut0,free=Uf0}=Usd0, fncs=#tstruct{data=Ft0,free=Ff0}=Fnc0, g=G,stk=Stk,cs=Cs,meta=Meta}=St) -> %% The root set consisting of global table and stack. Root = [Meta#meta.nil,Meta#meta.boolean,Meta#meta.number,Meta#meta.string, G|Stk], %% Mark all seen tables and frames, i.e. return them. GcT = #gct{t=Tt0,s=[]}, GcE = #gct{t=Et0,s=[]}, GcU = #gct{t=Ut0,s=[]}, GcF = #gct{t=Ft0,s=[]}, {SeenT,SeenE,SeenU,SeenF} = mark(Root, [Cs], GcT, GcE, GcU, GcF), %% io:format("gc: ~p\n", [{SeenT,SeenF,SeenU}]), %% Free unseen tables and add freed to free list. {Tf1,Tt1} = filter_tables(SeenT, Tf0, Tt0), {Ef1,Et1} = filter_environment(SeenE, Ef0, Et0), {Uf1,Ut1} = filter_userdata(SeenU, Uf0, Ut0), {Ff1,Ft1} = filter_funcdefs(SeenF, Ff0, Ft0), %% And update the tables. Tab1 = Tab0#tstruct{data=Tt1,free=Tf1}, Env1 = Env0#tstruct{data=Et1,free=Ef1}, Usd1 = Usd0#tstruct{data=Ut1,free=Uf1}, Fnc1 = Fnc0#tstruct{data=Ft1,free=Ff1}, St#luerl{tabs=Tab1,envs=Env1,usds=Usd1,fncs=Fnc1}. %% mark(ToDo, MoreTodo, GcTabs, GcEnv, GcUserdata, GcFuncdefs) -> %% {SeenTabs,SeenFrames,SeenUserdata,SeenFuncdefs}. %% Scan over all live objects and mark seen tables by adding them to %% the seen list. mark([{in_table,_}=_T|Todo], More, GcT, GcE, GcU, GcF) -> %%io:format("gc: ~p\n", [_T]), mark(Todo, More, GcT, GcE, GcU, GcF); mark([#tref{i=T}|Todo], More, #gct{t=Tt,s=Ts0}=GcT, GcE, GcU, GcF) -> case ordsets:is_element(T, Ts0) of true -> %Already done mark(Todo, More, GcT, GcE, GcU, GcF); false -> %Mark it and add to todo Ts1 = ordsets:add_element(T, Ts0), #table{a=Arr,d=Dict,meta=Meta} = ?GET_TABLE(T, Tt), %% Have to be careful when adding Tab and Meta as Tab is %% [{Key,Val}], Arr is array and Meta is %% nil|#tref{i=M}. We want lists. Aes = array:sparse_to_list(Arr), Des = ttdict:to_list(Dict), mark([Meta|Todo], [[{in_table,T}],Des,Aes,[{in_table,-T}]|More], GcT#gct{s=Ts1}, GcE, GcU, GcF) end; mark([#eref{i=F}|Todo], More, GcT, #gct{t=Et,s=Es0}=GcE, GcU, GcF) -> %% io:format("eref0: ~p\ ~p ~pn", [F,Et,Es0]), case ordsets:is_element(F, Es0) of true -> %Already done mark(Todo, More, GcT, GcE, GcU, GcF); false -> %Mark it and add to todo Es1 = ordsets:add_element(F, Es0), Ses = tuple_to_list(?GET_TABLE(F, Et)), %% io:format("eref1: ~p ~p\n", [Et,Es1]), mark(Todo, [Ses|More], GcT, GcE#gct{s=Es1}, GcU, GcF) end; mark([#usdref{i=U}|Todo], More, GcT, GcE, #gct{s=Us0}=GcU, GcF) -> case ordsets:is_element(U, Us0) of true -> %Already done mark(Todo, More, GcT, GcE, GcU, GcF); false -> Us1 = ordsets:add_element(U, Us0), mark(Todo, More, GcT, GcE, GcU#gct{s=Us1}, GcF) end; mark([#funref{i=F,env=Erefs}|ToDo], More, GcT, GcE, GcU, #gct{t=Ft0,s=Fs0}=GcF) -> %% io:format("funref0: ~p ~p ~p\n", [F,Fs0,Erefs]), %% Each funref has its own environments but we only need to add %% the function definition once. case ordsets:is_element(F, Fs0) of true -> mark(ToDo, [Erefs|More], GcT, GcE, GcU, GcF); false -> %% And mark the function definition. Fs1 = ordsets:add_element(F, Fs0), Fdef = ?GET_TABLE(F, Ft0), %% io:format("funref1: ~p ~p ~p\n", [F,Fs1,Erefs]), mark([Fdef|ToDo], [Erefs|More], GcT, GcE, GcU, GcF#gct{s=Fs1}) end; mark([#lua_func{funrefs=Funrefs}|Todo], More, GcT, GcE, GcU, GcF) -> %% io:format("push funrefs ~p\n", [Funrefs]), mark(Todo, [Funrefs|More], GcT, GcE, GcU, GcF); %% The call stack. mark([#call_frame{func=Funref,lvs=Lvs,env=Env}|Todo], More0, GcT, GcE, GcU, GcF) -> %% io:format("cf ~p\n", [Funref]), More1 = [ tuple_to_list(Lv) || Lv <- Lvs, is_tuple(Lv) ] ++ [Env|More0], mark([Funref|Todo], More1, GcT, GcE, GcU, GcF); mark([#loop_frame{lvs=Lvs,stk=Stk,env=Env}|Todo], More0, GcT, GcE, GcU, GcF) -> More1 = [ tuple_to_list(Lv) || Lv <- Lvs, is_tuple(Lv) ] ++ [Stk,Env|More0], mark(Todo, More1, GcT, GcE, GcU, GcF); %% Specifically catch these as they would match table key-value pair. mark([#erl_func{}|Todo], More, GcT, GcE, GcU, GcF) -> mark(Todo, More, GcT, GcE, GcU, GcF); mark([#erl_mfa{}|Todo], More, GcT, GcE, GcU, GcF) -> mark(Todo, More, GcT, GcE, GcU, GcF); mark([#thread{}|Todo], More, GcT, GcE, GcU, GcF) -> mark(Todo, More, GcT, GcE, GcU, GcF); mark([#userdata{meta=Meta}|Todo], More, GcT, GcE, GcU, GcF) -> mark([Meta|Todo], More, GcT, GcE, GcU, GcF); mark([{K,V}|Todo], More, GcT, GcE, GcU, GcF) -> %Table key-value pair %% io:format("mt: ~p\n", [{K,V}]), mark([K,V|Todo], More, GcT, GcE, GcU, GcF); mark([_|Todo], More, GcT, GcE, GcU, GcF) -> %% Can ignore everything else. mark(Todo, More, GcT, GcE, GcU, GcF); mark([], [M|More], GcT, GcE, GcU, GcF) -> mark(M, More, GcT, GcE, GcU, GcF); mark([], [], #gct{s=St}, #gct{s=Se}, #gct{s=Su}, #gct{s=Sf}) -> {St,Se,Su,Sf}. %% filter_tables(Seen, Free, Tables) -> {Free,Tables}. %% filter_environment(Seen, Free, Frames) -> {Free,Frames}. %% filter_userdata(Seen, Free, Frames) -> {Free,Frames}. %% filter_funcdefs(Seen, Free, Frames) -> {Free,Frames}. %% Filter tables/frames/userdata/funcdefs and return updated free %% lists and tables/frames. filter_tables(Seen, Tf0, Tt0) -> %% Update the free list. Tf1 = ?FOLD_TABLES(fun (K, _, Free) -> case ordsets:is_element(K, Seen) of true -> Free; false -> [K|Free] end end, Tf0, Tt0), Tt1 = ?FILTER_TABLES(fun (K, _) -> ordsets:is_element(K, Seen) end, Tt0), {Tf1,Tt1}. filter_environment(Seen, Ef0, Et0) -> %% io:format("env0: ~p ~p ~p\n", [Seen,Ef0,Et0]), %% Update the free list. Ef1 = ?FOLD_TABLES(fun (K, _, Free) -> case ordsets:is_element(K, Seen) of true -> Free; false -> [K|Free] end end, Ef0, Et0), Et1 = ?FILTER_TABLES(fun (K, _) -> ordsets:is_element(K, Seen) end, Et0), %% io:format("env1: ~p ~p\n", [Ef1,Et1]), {Ef1,Et1}. filter_userdata(Seen, Uf0, Ut0) -> %% Update the free list. Uf1 = ?FOLD_TABLES(fun (K, _, Free) -> case ordsets:is_element(K, Seen) of true -> Free; false -> [K|Free] end end, Uf0, Ut0), %% Reclaim free table slots. Ut1 = ?FILTER_TABLES(fun (K, _) -> ordsets:is_element(K, Seen) end, Ut0), {Uf1,Ut1}. filter_funcdefs(Seen, Ff0, Ft0) -> %% Update the free list. Ff1 = ?FOLD_TABLES(fun (K, _, Free) -> case ordsets:is_element(K, Seen) of true -> Free; false -> [K|Free] end end, Ff0, Ft0), Ft1 = ?FILTER_TABLES(fun (K, _) -> ordsets:is_element(K, Seen) end, Ft0), {Ff1,Ft1}. luerl-1.2.3/src/luerl_old.erl0000664000175000017500000000214014677012037016500 0ustar debalancedebalance%% Copyright (c) 2013-2021 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_old.erl %% Authors : Robert Virding, Henning Diedrich %% Purpose : The old basic LUA 5.2 interface. %% This module is just an interface to the older luerl.erl which might %% make it easier to migrate the module names if we decide to do so in %% the future. -module(luerl_old). -export(['$handle_undefined_function'/2]). %% '$handle_undefined_function'(Func, Args) %% We just pass the buck and call the old luerl module. '$handle_undefined_function'(Func, Args) -> apply(luerl, Func, Args). luerl-1.2.3/src/luerl_lib_table.erl0000664000175000017500000004654314677012037017656 0ustar debalancedebalance%% Copyright (c) 2013-2020 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_lib_table.erl %% Author : Robert Virding %% Purpose : The table library for Luerl. %% These functions sometimes behave strangely in the Lua 5.2 %% libraries, but we try to follow them. Most of these functions KNOW %% that a table is a ttdict! We know that the erlang array has default %% value 'nil'. -module(luerl_lib_table). -include("luerl.hrl"). %% The basic entry point to set up the function table. -export([install/1,concat/3,insert/3,pack/3,remove/3,sort/3,unpack/3]). %% Export some functions which can be called from elsewhere. -export([concat/4,concat/5,raw_length/2,length/2,unpack/2]). %% Export some test functions. -export([test_concat/1, test_insert/2,test_insert/3, test_remove/2,test_remove/3]). -import(luerl_lib, [lua_error/2,badarg_error/3]). %Shorten this install(St) -> luerl_heap:alloc_table(table(), St). %% table() -> [{FuncName,Function}]. table() -> [{<<"concat">>,#erl_mfa{m=?MODULE,f=concat}}, {<<"insert">>,#erl_mfa{m=?MODULE,f=insert}}, {<<"pack">>,#erl_mfa{m=?MODULE,f=pack}}, {<<"remove">>,#erl_mfa{m=?MODULE,f=remove}}, {<<"sort">>,#erl_mfa{m=?MODULE,f=sort}}, {<<"unpack">>,#erl_mfa{m=?MODULE,f=unpack}} ]. %% concat - concat the elements of a list into a string. concat(_, As, St0) -> try do_concat(As, St0) catch throw:{error,E,St1} -> lua_error(E, St1); throw:{error,E} -> lua_error(E, St0) end. do_concat([#tref{}=Tref|As], St) -> #table{a=Arr,d=Dict} = luerl_heap:get_table(Tref, St), case luerl_lib:conv_list(concat_args(As), [lua_string,lua_integer,lua_integer]) of [Sep,I] -> {[do_concat(Arr, Dict, Sep, I, length_loop(Arr))],St}; [Sep,I,J] -> {[do_concat(Arr, Dict, Sep, I, J)],St}; _ -> throw({error,{badarg,concat,As},St}) end; do_concat(As, St) -> throw({error,{badarg,concat,As},St}). %% concat(Table, Sep, I, State) -> string(). %% concat(Table, Sep, I, J, State) -> string(). %% Concatenate elements in a list into a string. Callable from %% Erlang. concat(Tref, Sep, I, St) -> #table{a=Arr,d=Dict} = luerl_heap:get_table(Tref, St), J = length_loop(Arr), do_concat(Arr, Dict, Sep, I, J). concat(Tref, Sep, I, J, St) -> #table{a=Arr,d=Dict} = luerl_heap:get_table(Tref, St), do_concat(Arr, Dict, Sep, I, J). test_concat(As) -> concat_args(As). concat_args([]) -> concat_args([<<>>]); concat_args([nil|As]) -> concat_args([<<>>|As]); concat_args([Sep]) -> [Sep,1.0]; concat_args([Sep,nil|As]) -> concat_args([Sep,1.0|As]); concat_args([Sep,I]) -> [Sep,I]; concat_args([Sep,I,nil|_]) -> [Sep,I]; concat_args([Sep,I,J|_]) -> [Sep,I,J]. do_concat(Arr, Dict, Sep, I, J) -> Conc = concat_table(Arr, Dict, I, J), concat_join(Conc, Sep). concat_table(Arr, Dict, I, J) -> concat_tab(Arr, Dict, I, J). %% This and unpack_loop are very similar. %% First scan over table up to 0 then the array. We have the indexes %% and limits as integers and explicitly use '==' to compare with %% float values in table. concat_tab(_, _, N, J) when N > J -> []; %Done concat_tab(Arr, _, N, J) when N > 0 -> %Done with table concat_arr(Arr, N, J); concat_tab(Arr, Dict, N, J) -> case ttdict:find(N, Dict) of {ok,V} -> case luerl_lib:arg_to_list(V) of error -> throw({error,{illegal_value,concat,V}}); S -> [S|concat_tab(Arr, Dict, N+1, J)] end; error -> throw({error,{illegal_value,concat,nil}}) end. concat_arr(_, N, J) when N > J -> []; concat_arr(Arr, N, J) -> V = array:get(N, Arr), case luerl_lib:arg_to_list(V) of error -> throw({error,{illegal_value,concat,V}}); S -> [S|concat_arr(Arr, N+1, J)] end. concat_join([E], _) -> list_to_binary(E); concat_join([E1|Es], Sep) -> iolist_to_binary([E1|[ [Sep,E] || E <- Es ]]); concat_join([], _) -> <<>>. %% insert(Table, [Pos,] Value) -> [] %% Insert an element into a list shifting following elements. insert(_, [Tref,V], St) when ?IS_TREF(Tref) -> #table{a=Arr0} = T = luerl_heap:get_table(Tref, St), Arr1 = do_insert_last(Arr0, V), {[],luerl_heap:set_table(Tref, T#table{a=Arr1}, St)}; insert(_, [Tref,P0,V]=As, St) when ?IS_TREF(Tref) -> #table{a=Arr0} = T = luerl_heap:get_table(Tref, St), Size = length_loop(Arr0), case luerl_lib:arg_to_integer(P0) of P1 when P1 >=1, P1 =< Size+1 -> Arr1 = do_insert(Arr0, P1, V), {[],luerl_heap:set_table(Tref, T#table{a=Arr1}, St)}; _ -> badarg_error(insert, As, St) end; insert(_, As, St) -> badarg_error(insert, As, St). test_insert(A, V) -> do_insert_last(A, V). test_insert(A, N, V) -> do_insert(A, N, V). %% do_insert_last(Array, V) -> Array. %% Get the "length" of the first bit and put value in first slot %% after that. do_insert_last(Arr, V) -> Len = length_loop(Arr), %Get "length" array:set(Len+1, V, Arr). %Set the value %% do_insert(Array, P, V) -> Array. %% We only insert elements inside the "proper" 1..n table. do_insert(Arr, P, V) -> %Go to the array part insert_array(Arr, P, V). insert_array(Arr0, N, Here) -> %Put this at N shifting up case array:get(N, Arr0) of nil -> array:set(N, Here, Arr0); %Just fill hole Next -> %Take value for next slot Arr1 = array:set(N, Here, Arr0), insert_array(Arr1, N+1, Next) end. %% remove(Table [,Pos]) -> Value. %% Remove an element from a list shifting following elements. remove(_, [Tref], St) when ?IS_TREF(Tref) -> #table{a=Arr0,d=Dict0} = T = luerl_heap:get_table(Tref, St), {Ret,Arr1,Dict1} = do_remove_last(Arr0, Dict0), {Ret,luerl_heap:set_table(Tref, T#table{a=Arr1,d=Dict1}, St)}; remove(_, [Tref,P0|_]=As, St) when ?IS_TREF(Tref) -> #table{a=Arr0,d=Dict0} = T = luerl_heap:get_table(Tref, St), case luerl_lib:arg_to_integer(P0) of P1 when P1 =/= nil -> case do_remove(Arr0, Dict0, P1) of {Ret,Arr1,Dict1} -> {Ret, luerl_heap:set_table(Tref, T#table{a=Arr1,d=Dict1}, St)}; badarg -> badarg_error(remove, As, St) end; _ -> badarg_error(remove, As, St) %nil or P < 1 end; remove(_, As, St) -> badarg_error(remove, As, St). test_remove(Arr, Dict) -> do_remove_last(Arr, Dict). test_remove(Arr, Dict, N) -> do_remove(Arr, Dict, N). %% do_remove_last(Array, Dict) -> {Return,Array,Dict}. %% Find the length and remove the last element. Return it even if it %% is nil. do_remove_last(Arr0, Dict0) -> case length_loop(Arr0) of 0 -> do_remove_0(Arr0, Dict0); Size -> Val = array:get(Size, Arr0), Arr1 = array:set(Size, nil, Arr0), {[Val],Arr1,Dict0} end. do_remove_0(Arr, Dict0) -> case ttdict:find(0.0, Dict0) of {ok,Val} -> Dict1 = ttdict:erase(0.0, Dict0), {[Val],Arr,Dict1}; error -> {[nil],Arr,Dict0} end. %% do_remove(Array, Dict, P) -> {Return,Array,Dict} | badarg. %% Don't ask, it tries to emulate the "real" Lua, where we can't %% remove elements elements outside of the "proper" 1..n dict. do_remove(Arr, Dict, P) -> do_remove(Arr, Dict, P, length_loop(Arr)). do_remove(Arr, Dict, 0, 0) -> do_remove_0(Arr, Dict); do_remove(Arr, Dict, 1, 0) -> {[nil],Arr,Dict}; do_remove(Arr0, Dict, P, Size) when P >= 1, P =< Size+1 -> Ret = array:get(P, Arr0), Arr1 = remove_array_1(Arr0, P), {[Ret],Arr1,Dict}; do_remove(_, _, _, _) -> badarg. remove_array_1(Arr0, N) -> There = array:get(N+1, Arr0), %Next value Arr1 = array:set(N, There, Arr0), if There =:= nil -> Arr1; %End if next a nil true -> remove_array_1(Arr1, N+1) end. %% pack - pack arguments in to a table. pack(_, As, St0) -> T = pack_loop(As, 0), %Indexes are integers! {Tab,St1} = luerl_heap:alloc_table(T, St0), {[Tab],St1}. pack_loop([E|Es], N) -> [{N+1,E}|pack_loop(Es, N+1)]; pack_loop([], N) -> [{<<"n">>,N}]. %% unpack - unpack table into return values. unpack(_, [#tref{}=Tref|As], St) -> #table{a=Arr,d=Dict} = luerl_heap:get_table(Tref, St), case luerl_lib:args_to_integers(unpack_args(As)) of [I] -> Unp = do_unpack(Arr, Dict, I, length_loop(Arr)), %% io:fwrite("unp: ~p\n", [{Arr,I,Start,Unp}]), {Unp,St}; [I,J] -> Unp = do_unpack(Arr, Dict, I, J), %% io:fwrite("unp: ~p\n", [{Arr,I,J,Start,Unp}]), {Unp,St}; error -> %Not numbers badarg_error(unpack, [Tref|As], St) end; unpack(_, [], St) -> badarg_error(unpack, [], St). unpack(As, St) -> unpack(nil, As, St). %% unpack_args(Args) -> Args. %% Fix args for unpack getting defaults right and handling 'nil'. unpack_args([]) -> unpack_args([1.0]); %Just start from the beginning unpack_args([nil|As]) -> unpack_args([1.0|As]); unpack_args([I]) -> [I]; %Only one argument unpack_args([I,nil|_]) -> [I]; %Goto the default end unpack_args([I,J|_]) -> [I,J]. %Only use two arguments %% This and concat_table are very similar. %% First scan over table up to 0 then the array. We have the indexes %% and limits as integers and explicitly use '==' to compare with %% float values in table. do_unpack(Arr, Dict, I, J) -> unpack_tab(Arr, Dict, I, J). unpack_tab(_, _, N, J) when N > J -> []; %Done unpack_tab(Arr, _, N, J) when N > 0 -> %Done with table unpack_arr(Arr, N, J); unpack_tab(Arr, Dict, N, J) -> E = case ttdict:find(N, Dict) of {ok,V} -> V; error -> nil end, [E|unpack_tab(Arr, Dict, N+1, J)]. unpack_arr(_, N, J) when N > J -> []; unpack_arr(Arr, N, J) -> [array:get(N, Arr)|unpack_arr(Arr, N+1, J)]. %% length(Table, State) -> {Length,State}. %% raw_length(Table, State) -> Length. %% The length of a table is the number of numeric keys in sequence %% from 1. Except if 1 is nil followed by non-nil. Don't ask! length(#tref{}=T, St0) -> Meta = luerl_heap:get_metamethod(T, <<"__len">>, St0), if ?IS_TRUE(Meta) -> {Ret,St1} = luerl_emul:functioncall(Meta, [T], St0), {luerl_lib:first_value(Ret),St1}; true -> {raw_length(T, St0),St0} end. raw_length(Tref, St) -> #table{a=Arr} = luerl_heap:get_table(Tref, St), length_loop(Arr). length_loop(Arr) -> case {array:get(1, Arr),array:get(2, Arr)} of {nil,nil} -> 0; {nil,_} -> length_loop(3, Arr); {_,nil} -> 1; {_,_} -> length_loop(3, Arr) end. length_loop(I, Arr) -> case array:get(I, Arr) of nil -> I-1; _ -> length_loop(I+1, Arr) end. %% sort(Table [,SortFun]) %% Sort the elements of the list after their values. sort(_, [Tref], St0) when ?IS_TREF(Tref) -> Comp = fun (A, B, St) -> lt_comp(A, B, St) end, St1 = do_sort(Comp, St0, Tref), {[],St1}; sort(_, [Tref,Func|_], St0) when ?IS_TREF(Tref) -> Comp = fun (A, B, St) -> luerl_emul:functioncall(Func, [A,B], St) end, St1 = do_sort(Comp, St0, Tref), {[],St1}; sort(_, As, St) -> badarg_error(sort, As, St). do_sort(Comp, St0, Tref) -> #table{a=Arr0} = T = luerl_heap:get_table(Tref, St0), case array:to_list(Arr0) of [] -> St0; %Nothing to do [E0|Es0] -> %% 1st element index 0, skip it and then prepend it again {Es1,St1} = merge_sort(Comp, St0, Es0), Arr2 = array:from_list([E0|Es1], nil), %% io:fwrite("so: ~p\n", [{Arr0,Arr1,Arr2}]), luerl_heap:set_table(Tref, T#table{a=Arr2}, St1) end. %% lt_comp(O1, O2, State) -> {[Bool],State}. %% Proper Lua '<' comparison. lt_comp(O1, O2, St) when is_number(O1), is_number(O2) -> {[O1 =< O2],St}; lt_comp(O1, O2, St) when is_binary(O1), is_binary(O2) -> {[O1 =< O2],St}; lt_comp(O1, O2, St0) -> case luerl_heap:get_metamethod(O1, O2, <<"__lt">>, St0) of nil -> lua_error({illegal_comp,sort}, St0); Meta -> {Ret,St1} = luerl_emul:functioncall(Meta, [O1,O2], St0), {[luerl_lib:boolean_value(Ret)],St1} end. %% sort(A,B,C) -> sort_up(A,B,C). %% sort_up(A,B,[X,Y|L]) -> %% case X =< Y of %% true -> merge_dn([Y,X], sort_dn(A, B, L), []); %% false -> merge_dn([X,Y], sort_dn(A, B, L), []) %% end; %% sort_up(A,B,[X]) -> [X]; %% sort_up(A,B,[]) -> []. %% sort_dn(A,B,[X,Y|L]) -> %% case X =< Y of %% true -> merge_up([X,Y], sort_up(A, B, L), []); %% false -> merge_up([Y,X], sort_up(A, B, L), []) %% end; %% sort_dn(A,B,[X]) -> [X]; %% sort_dn(A,B,[]) -> []. %% merge(A,B,C) -> %% merge_dn(A,B,C). %% %% merge_up(L1, L2, Acc) %% %% L1, L2 increasing, Acc will be decreasing %% merge_up([X|Xs]=Xs0, [Y|Ys]=Ys0, Acc) -> %% case X =< Y of %% true -> merge_up(Xs, Ys0, [X|Acc]); %% false -> merge_up(Xs0, Ys, [Y|Acc]) %% end; %% merge_up([X|Xs], [], Acc) -> merge_up(Xs, [], [X|Acc]); %% merge_up([], [Y|Ys], Acc) -> merge_up([], Ys, [Y|Acc]); %% merge_up([], [], Acc) -> Acc. %% %% merge_dn(L1, L2, Acc) %% %% L1, L2 decreasing, Acc will be increasing %% merge_dn([X|Xs]=Xs0, [Y|Ys]=Ys0, Acc) -> %% case X =< Y of %% true -> merge_dn(Xs0, Ys, [Y|Acc]); %% false -> merge_dn(Xs, Ys0, [X|Acc]) %% end; %% merge_dn([X|Xs], [], Acc) -> merge_dn(Xs, [], [X|Acc]); %% merge_dn([], [Y|Ys], Acc) -> merge_dn([], Ys, [Y|Acc]); %% merge_dn([], [], Acc) -> Acc. %% merge_sort(CompFun, State, List) -> {SortedList,State}. %% The code here has been taken from the sort/2 code in lists.erl and %% converted to chain State through all calls to the comparison %% function. merge_sort(_, St, []) -> {[],St}; merge_sort(_, St, [_] = L) -> {L,St}; merge_sort(Fun, St0, [X, Y|T]) -> {Ret,St1} = Fun(X, Y, St0), case luerl_lib:boolean_value(Ret) of true -> fsplit_1(Y, X, Fun, St1, T, [], []); false -> fsplit_2(Y, X, Fun, St1, T, [], []) end. %% Ascending. fsplit_1(Y, X, Fun, St0, [Z|L], R, Rs) -> {Ret1,St1} = Fun(Y, Z, St0), case luerl_lib:boolean_value(Ret1) of true -> fsplit_1(Z, Y, Fun, St1, L, [X|R], Rs); false -> {Ret2,St2} = Fun(X, Z, St1), case luerl_lib:boolean_value(Ret2) of true -> fsplit_1(Y, Z, Fun, St2, L, [X|R], Rs); false when R == [] -> fsplit_1(Y, X, Fun, St2, L, [Z], Rs); false -> fsplit_1_1(Y, X, Fun, St2, L, R, Rs, Z) end end; fsplit_1(Y, X, Fun, St, [], R, Rs) -> rfmergel([[Y, X|R]|Rs], [], Fun, St, asc). fsplit_1_1(Y, X, Fun, St0, [Z|L], R, Rs, S) -> {Ret1,St1} = Fun(Y, Z, St0), case luerl_lib:boolean_value(Ret1) of true -> fsplit_1_1(Z, Y, Fun, St1, L, [X|R], Rs, S); false -> {Ret2,St2} = Fun(X, Z, St1), case luerl_lib:boolean_value(Ret2) of true -> fsplit_1_1(Y, Z, Fun, St2, L, [X|R], Rs, S); false -> {Ret3,St3} = Fun(S, Z, St2), case luerl_lib:boolean_value(Ret3) of true -> fsplit_1(Z, S, Fun, St3, L, [], [[Y, X|R]|Rs]); false -> fsplit_1(S, Z, Fun, St3, L, [], [[Y, X|R]|Rs]) end end end; fsplit_1_1(Y, X, Fun, St, [], R, Rs, S) -> rfmergel([[S], [Y, X|R]|Rs], [], Fun, St, asc). %% Descending. fsplit_2(Y, X, Fun, St0, [Z|L], R, Rs) -> {Ret1,St1} = Fun(Y, Z, St0), case luerl_lib:boolean_value(Ret1) of false -> fsplit_2(Z, Y, Fun, St1, L, [X|R], Rs); true -> {Ret2,St2} = Fun(X, Z, St1), case luerl_lib:boolean_value(Ret2) of false -> fsplit_2(Y, Z, Fun, St2, L, [X|R], Rs); true when R == [] -> fsplit_2(Y, X, Fun, St2, L, [Z], Rs); true -> fsplit_2_1(Y, X, Fun, St2, L, R, Rs, Z) end end; fsplit_2(Y, X, Fun, St, [], R, Rs) -> fmergel([[Y, X|R]|Rs], [], Fun, St, desc). fsplit_2_1(Y, X, Fun, St0, [Z|L], R, Rs, S) -> {Ret1,St1} = Fun(Y, Z, St0), case luerl_lib:boolean_value(Ret1) of false -> fsplit_2_1(Z, Y, Fun, St1, L, [X|R], Rs, S); true -> {Ret2,St2} = Fun(X, Z, St1), case luerl_lib:boolean_value(Ret2) of false -> fsplit_2_1(Y, Z, Fun, St2, L, [X|R], Rs, S); true -> {Ret3,St3} = Fun(S, Z, St2), case luerl_lib:boolean_value(Ret3) of false -> fsplit_2(Z, S, Fun, St3, L, [], [[Y, X|R]|Rs]); true -> fsplit_2(S, Z, Fun, St3, L, [], [[Y, X|R]|Rs]) end end end; fsplit_2_1(Y, X, Fun, St, [], R, Rs, S) -> fmergel([[S], [Y, X|R]|Rs], [], Fun, St, desc). fmergel([T1, [H2|T2]|L], Acc, Fun, St0, asc) -> {L1,St1} = fmerge2_1(T1, H2, Fun, St0, T2, []), fmergel(L, [L1|Acc], Fun, St1, asc); fmergel([[H2|T2], T1|L], Acc, Fun, St0, desc) -> {L1,St1} = fmerge2_1(T1, H2, Fun, St0, T2, []), fmergel(L, [L1|Acc], Fun, St1, desc); fmergel([L], [], _Fun, St, _O) -> {L,St}; fmergel([L], Acc, Fun, St, O) -> rfmergel([lists:reverse(L, [])|Acc], [], Fun, St, O); fmergel([], Acc, Fun, St, O) -> rfmergel(Acc, [], Fun, St, O). rfmergel([[H2|T2], T1|L], Acc, Fun, St0, asc) -> {L1,St1} = rfmerge2_1(T1, H2, Fun, St0, T2, []), rfmergel(L, [L1|Acc], Fun, St1, asc); rfmergel([T1, [H2|T2]|L], Acc, Fun, St0, desc) -> {L1,St1} = rfmerge2_1(T1, H2, Fun, St0, T2, []), rfmergel(L, [L1|Acc], Fun, St1, desc); rfmergel([L], Acc, Fun, St, O) -> fmergel([lists:reverse(L, [])|Acc], [], Fun, St, O); rfmergel([], Acc, Fun, St, O) -> fmergel(Acc, [], Fun, St, O). %% merge(Fun, T1, [H2 | T2]) when is_function(Fun, 2) -> %% lists:reverse(fmerge2_1(T1, H2, Fun, T2, []), []); %% merge(Fun, T1, []) when is_function(Fun, 2) -> %% T1. %% Elements from the first list are prioritized. fmerge2_1([H1|T1], H2, Fun, St0, T2, M) -> {Ret,St1} = Fun(H1, H2, St0), case luerl_lib:boolean_value(Ret) of true -> fmerge2_1(T1, H2, Fun, St1, T2, [H1|M]); false -> fmerge2_2(H1, T1, Fun, St1, T2, [H2|M]) end; fmerge2_1([], H2, _Fun, St, T2, M) -> {lists:reverse(T2, [H2|M]),St}. fmerge2_2(H1, T1, Fun, St0, [H2|T2], M) -> {Ret,St1} = Fun(H1, H2, St0), case luerl_lib:boolean_value(Ret) of true -> fmerge2_1(T1, H2, Fun, St1, T2, [H1|M]); false -> fmerge2_2(H1, T1, Fun, St1, T2, [H2|M]) end; fmerge2_2(H1, T1, _Fun, St, [], M) -> {lists:reverse(T1, [H1|M]),St}. %% rmerge(Fun, T1, [H2 | T2]) when is_function(Fun, 2) -> %% lists:reverse(rfmerge2_1(T1, H2, Fun, T2, []), []); %% rmerge(Fun, T1, []) when is_function(Fun, 2) -> %% T1. rfmerge2_1([H1|T1], H2, Fun, St0, T2, M) -> {Ret,St1} = Fun(H1, H2, St0), case luerl_lib:boolean_value(Ret) of true -> rfmerge2_2(H1, T1, Fun, St1, T2, [H2|M]); false -> rfmerge2_1(T1, H2, Fun, St1, T2, [H1|M]) end; rfmerge2_1([], H2, _Fun, St, T2, M) -> {lists:reverse(T2, [H2|M]),St}. rfmerge2_2(H1, T1, Fun, St0, [H2|T2], M) -> {Ret,St1} = Fun(H1, H2, St0), case luerl_lib:boolean_value(Ret) of true -> rfmerge2_2(H1, T1, Fun, St1, T2, [H2|M]); false -> rfmerge2_1(T1, H2, Fun, St1, T2, [H1|M]) end; rfmerge2_2(H1, T1, _Fun, St, [], M) -> {lists:reverse(T1, [H1|M]),St}. luerl-1.2.3/src/luerl_emul.erl0000664000175000017500000014306714677012037016702 0ustar debalancedebalance%% Copyright (c) 2013-2023 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_emul.erl %% Author : Robert Virding %% Purpose : A basic LUA 5.3 machine emulator. %% First version of emulator. Compiler so far only explicitly handles %% local/global variables. %% %% We explicitly mirror the parser rules which generate the AST and do %% not try to fold similar structures into common code. While this %% means we get more code it also becomes more explicit and clear what %% we are doing. It may also allow for specific optimisations. And %% example is that we DON'T fold 'var' and 'funcname' even though they %% are almost the same. %% %% Issues: how should we handle '...'? Now we treat it as any (local) %% variable. -module(luerl_emul). -include("luerl.hrl"). -include("luerl_comp.hrl"). -include("luerl_instrs.hrl"). %% Basic interface. -export([init/0,gc/1]). -export([call/2,call/3,emul/2]). -export([load_chunk/2,load_chunk/3]). -export([functioncall/3,methodcall/4, set_global_key/3,get_global_key/2, get_table_keys/2,get_table_keys/3, set_table_keys/3,set_table_keys/4, get_table_key/3,set_table_key/4 ]). %% Temporary shadow calls. -export([alloc_table/2,set_userdata/3,get_metamethod/3]). %% For testing. -export([pop_vals/2,push_vals/3]). -import(luerl_lib, [lua_error/2,badarg_error/3]). %% -compile(inline). %For when we are optimising %% -compile({inline,[boolean_value/1,first_value/1]}). %% -define(ITRACE_DO(Expr), ok). -define(ITRACE_DO(Expr), begin (get(luerl_itrace) /= undefined) andalso Expr end). %% Temporary shadow calls. gc(St) -> luerl_heap:gc(St). alloc_table(Itab, St) -> luerl_heap:alloc_table(Itab, St). set_userdata(Ref, Data, St) -> luerl_heap:set_userdata(Ref, Data, St). get_metamethod(Obj, Event, St) -> luerl_heap:get_metamethod(Obj, Event, St). %% init() -> State. %% Initialise the basic state. init() -> St1 = luerl_heap:init(), %% Allocate the _G table and initialise the environment {_G,St2} = luerl_lib_basic:install(St1), %Global environment St3 = St2#luerl{g=_G}, %% Now we can start adding libraries. Package MUST be first! St4 = load_lib(<<"package">>, luerl_lib_package, St3), %% Add the other standard libraries. St5 = load_libs([ {<<"bit32">>,luerl_lib_bit32}, {<<"io">>,luerl_lib_io}, {<<"math">>,luerl_lib_math}, {<<"os">>,luerl_lib_os}, {<<"string">>,luerl_lib_string}, {<<"utf8">>,luerl_lib_utf8}, {<<"table">>,luerl_lib_table}, {<<"debug">>,luerl_lib_debug} ], St4), %% Set _G variable to point to it and add it to packages.loaded. St6 = set_global_key(<<"_G">>, _G, St5), set_table_keys([<<"package">>,<<"loaded">>,<<"_G">>], _G, St6). load_libs(Libs, St) -> Fun = fun ({Key,Mod}, S) -> load_lib(Key, Mod, S) end, lists:foldl(Fun, St, Libs). %% load_lib(Key, Module, State) -> State. load_lib(Key, Mod, St0) -> {Tab,St1} = Mod:install(St0), %% Add key to global and to package.loaded. St2 = set_global_key(Key, Tab, St1), set_table_keys([<<"package">>,<<"loaded">>,Key], Tab, St2). %% set_global_key(Key, Value, State) -> State. %% get_global_key(Key, State) -> {[Val],State}. %% Access elements in the global name table, _G. set_global_key(Key, Val, #luerl{g=G}=St) -> set_table_key(G, Key, Val, St). get_global_key(Key, #luerl{g=G}=St) -> get_table_key(G, Key, St). %% get_table_keys(Keys, State) -> {Value,State}. %% get_table_keys(Tab, Keys, State) -> {Value,State}. %% Search down tables which stops when no more tables. get_table_keys(Keys, St) -> get_table_keys(St#luerl.g, Keys, St). get_table_keys(Tab, [K|Ks], St0) -> {Val,St1} = get_table_key(Tab, K, St0), get_table_keys(Val, Ks, St1); get_table_keys(Val, [], St) -> {Val,St}. %% set_table_keys(Keys, Val, State) -> State. %% set_table_keys(Tab, Keys, Val, State) -> State. %% Setter down tables. set_table_keys(Keys, Val, St) -> set_table_keys(St#luerl.g, Keys, Val, St). set_table_keys(Tab, [K], Val, St) -> set_table_key(Tab, K, Val, St); set_table_keys(Tab0, [K|Ks], Val, St0) -> {Tab1,St1} = get_table_key(Tab0, K, St0), set_table_keys(Tab1, Ks, Val, St1). %% set_table_key(Tref, Key, Value, State) -> State. %% get_table_key(Tref, Key, State) -> {Val,State}. %% Access tables, as opposed to the environment (which are also %% tables). Setting a value to 'nil' will clear it from the array but %% not from the table; however, we won't add a nil value. %% NOTE: WE ALWAYS RETURN A SINGLE VALUE! set_table_key(Tref, Key, Val, St0) -> case luerl_heap:set_table_key(Tref, Key, Val, St0) of {value,_Val,St1} -> St1; {meta,Meth,Args,St1} -> {_Ret,St2} = functioncall(Meth, Args, St1), St2; {error,Error,St1} -> lua_error(Error, St1) end. get_table_key(Tref, Key, St0) -> case luerl_heap:get_table_key(Tref, Key, St0) of {value,Val,St1} -> {Val,St1}; {meta,Meth,Args,St1} -> {Ret,St2} = functioncall(Meth, Args, St1), {first_value(Ret),St2}; {error,Error,St1} -> lua_error(Error, St1) end. %% set_local_var(Depth, Index, Var, Frames) -> Frames. %% get_local_var(Depth, Index, Frames) -> Val. set_local_var(1, I, V, [F|Fs]) -> [setelement(I, F, V)|Fs]; set_local_var(D, I, V, [F|Fs]) -> [F|set_local_var(D-1, I, V, Fs)]. get_local_var(1, I, [F|_]) -> element(I, F); get_local_var(D, I, [_|Fs]) -> get_local_var(D-1, I, Fs). %% set_env_var(Depth, Index, Val, EnvStack, State) -> State. %% get_env_var(Depth, Index, EnvStack, State) -> Val. %% We must have the state as the environments are global in the %% state. set_env_var(D, I, Val, Estk, St) -> St1 = set_env_var_1(D, I, Val, Estk, St), %% io:format("******** SEV DONE ~w ~w ********\n", [D,I]), St1. set_env_var_1(1, I, Val, [Eref|_], St) -> luerl_heap:set_env_var(Eref, I, Val, St); set_env_var_1(2, I, Val, [_,Eref|_], St) -> luerl_heap:set_env_var(Eref, I, Val, St); set_env_var_1(D, I, Val, Env, St) -> luerl_heap:set_env_var(lists:nth(D, Env), I, Val, St). get_env_var(D, I, Env, St) -> Val = get_env_var_1(D, I, Env, St), %% io:format("******** GEV DONE ~w ~w ********\n", [D, I]), Val. get_env_var_1(1, I, [Eref|_], St) -> luerl_heap:get_env_var(Eref, I, St); get_env_var_1(2, I, [_,Eref|_], St) -> luerl_heap:get_env_var(Eref, I, St); get_env_var_1(D, I, Env, St) -> luerl_heap:get_env_var(lists:nth(D, Env), I, St). %% load_chunk(FunctionDefCode, State) -> {Function,State}. %% load_chunk(FunctionDefCode, Env, State) -> {Function,State}. %% Load a chunk from the compiler which is a compiled function %% definition whose instructions define everything. Return a callable %% function reference which defines everything and a updated Luerl %% state. load_chunk(Code, St) -> load_chunk(Code, [], St). load_chunk([Code], [], St0) -> {?PUSH_FDEF(Funref),_,St1} = load_chunk_i(Code, [], St0), {Funref,St1}. %% load_chunk_i(Instr, FuncRefs, Status) -> {Instr,FuncRefs,State}. %% load_chunk_is(Instrs, FuncRefs, Status) -> {Instrs,FuncRefs,State}. %% Load chunk instructions. We keep track of the functions refs and %% save the ones directly accessed in each function. This will make %% gc easier as we will not have to step through the function code at %% gc time. load_chunk_is([I0|Is0], Funrs0, St0) -> {I1,Funrs1,St1} = load_chunk_i(I0, Funrs0, St0), {Is1,Funrs2,St2} = load_chunk_is(Is0, Funrs1, St1), {[I1|Is1],Funrs2,St2}; load_chunk_is([], Funrs, St) -> {[],Funrs,St}. %% First the instructions with nested code. %% We include the dymanmic instructions here even though the compiler %% does not generate them. This should make us more future proof. load_chunk_i(?PUSH_FDEF(Anno, Lsz, Esz, Pars, B0), Funrs0, St0) -> {B1,Funrs,St1} = load_chunk_is(B0, [], St0), Fdef = #lua_func{anno=Anno,funrefs=Funrs,lsz=Lsz,esz=Esz,pars=Pars,body=B1}, {Funref,St2} = luerl_heap:alloc_funcdef(Fdef, St1), Funrs1 = ordsets:add_element(Funref, Funrs0), {?PUSH_FDEF(Funref),Funrs1,St2}; load_chunk_i(?BLOCK(Lsz, Esz, B0), Funrs0, St0) -> {B1,Funrs1,St1} = load_chunk_is(B0, Funrs0, St0), {?BLOCK(Lsz, Esz, B1),Funrs1,St1}; load_chunk_i(?REPEAT(B0), Funrs0, St0) -> {B1,Funrs1,St1} = load_chunk_is(B0, Funrs0, St0), {?REPEAT(B1),Funrs1,St1}; load_chunk_i(?REPEAT_LOOP(B0), Funrs0, St0) -> %This is dynamic {B1,Funrs1,St1} = load_chunk_is(B0, Funrs0, St0), {?REPEAT_LOOP(B1),Funrs1,St1}; load_chunk_i(?WHILE(E0, B0), Funrs0, St0) -> {E1,Funrs1,St1} = load_chunk_is(E0, Funrs0, St0), {B1,Funrs2,St2} = load_chunk_is(B0, Funrs1, St1), {?WHILE(E1, B1),Funrs2,St2}; load_chunk_i(?WHILE_LOOP(E0, B0), Funrs0, St0) -> {E1,Funrs1,St1} = load_chunk_is(E0, Funrs0, St0), {B1,Funrs2,St2} = load_chunk_is(B0, Funrs1, St1), {?WHILE_LOOP(E1, B1),Funrs2,St2}; load_chunk_i(?AND_THEN(T0), Funrs0, St0) -> {T1,Funrs1,St1} = load_chunk_is(T0, Funrs0, St0), {?AND_THEN(T1),Funrs1,St1}; load_chunk_i(?OR_ELSE(T0), Funrs0, St0) -> {T1,Funrs1,St1} = load_chunk_is(T0, Funrs0, St0), {?OR_ELSE(T1),Funrs1,St1}; load_chunk_i(?IF_TRUE(T0), Funrs0, St0) -> {T1,Funrs1,St1} = load_chunk_is(T0, Funrs0, St0), {?IF_TRUE(T1),Funrs1,St1}; load_chunk_i(?IF(T0, F0), Funrs0, St0) -> {T1,Funrs1,St1} = load_chunk_is(T0, Funrs0, St0), {F1,Funrs2,St2} = load_chunk_is(F0, Funrs1, St1), {?IF(T1, F1),Funrs2,St2}; load_chunk_i(?NFOR(V, B0), Funrs0, St0) -> {B1,Funrs1,St1} = load_chunk_is(B0, Funrs0, St0), {?NFOR(V, B1),Funrs1,St1}; load_chunk_i(?NFOR_LOOP(N, L, S, B0), Funrs0, St0) -> %This is dynamic {B1,Funrs1,St1} = load_chunk_is(B0, Funrs0, St0), {?NFOR_LOOP(N, L, S, B1),Funrs1,St1}; load_chunk_i(?GFOR(Vs, B0), Funrs0, St0) -> {B1,Funrs1,St1} = load_chunk_is(B0, Funrs0, St0), {?GFOR(Vs, B1),Funrs1,St1}; load_chunk_i(?GFOR_CALL(F, D, V, B0), Funrs0, St0) -> %This is dynamic {B1,Funrs1,St1} = load_chunk_is(B0, Funrs0, St0), {?GFOR_CALL(F, D, V, B1),Funrs1,St1}; load_chunk_i(?GFOR_LOOP(F, D, B0), Funrs0, St0) -> %This is dynamic {B1,Funrs1,St1} = load_chunk_is(B0, Funrs0, St0), {?GFOR_LOOP(F, D, B1),Funrs1,St1}; %% Then the rest which we don't have to worry about. load_chunk_i(I, Funrs, St) -> {I,Funrs,St}. %% call(Function, State) -> {Return,State}. %% call(Function, Args, State) -> {Return,State}. %% functioncall(Function, Args, State) -> {Return,State}. %% methodcall(Object, Method, Args, State) -> {Return,State}. %% These ares called from the outside and expect everything necessary %% to be in the state. call(Func, St) -> call(Func, [], St). call(#funref{}=Funref, Args, St0) -> %Lua function {Ret,St1} = functioncall(Funref, Args, St0), %% Should do GC here. {Ret,St1}; call(#erl_func{}=Func, Args, St0) -> %Erlang function {Ret,St1} = functioncall(Func, Args, St0), %% Should do GC here. {Ret,St1}; call(#erl_mfa{}=Func, Args, St0) -> %Erlang function as MFA triplet {Ret,St1} = functioncall(Func, Args, St0), {Ret,St1}. functioncall(Func, Args, #luerl{stk=Stk}=St0) -> Fr = #call_frame{func=Func,args=Args,lvs=[],env=[],is=[],cont=[]}, Cs0 = [Fr], {_Lvs,[Ret|_],_Env,Cs1,St1} = call_function(Func, Args, Stk, Cs0, St0), {Ret,St1#luerl{stk=Stk,cs=Cs1}}. %Reset the stacks methodcall(Obj, Meth, Args, St0) -> %% Get the function to call from object and method. case get_table_key(Obj, Meth, St0) of {nil,St1} -> %No method lua_error({undefined_method,Obj,Meth}, St1); {Func,St1} -> functioncall(Func, [Obj|Args], St1) end. %% emul(Instrs, State). %% emul(Instrs, Continuation, LocalVariables, Stack, Env, CallStack, State). %% The cost of checking the itrace process variable is very slight %% compared to everything else. emul(Is, St) -> emul(Is, [], {}, [], [], [], St). %% The faster (yeah sure) version. %% emul(Is, Cont, Lvs, Stk, Env, Cs, St) -> %% emul_1(Is, Cont, Lvs, Stk, Env, Cs, St). %% The tracing versions. emul([I|_]=Is, Cont, Lvs, Stk, Env, Cs, St) -> ?ITRACE_DO(begin io:fwrite("Is: ~p\n", [Is]), io:fwrite("Cnt: ~p\n", [Cont]), io:fwrite("Lvs: ~p\n", [Lvs]), io:fwrite("Env: ~p\n", [Env]), io:fwrite("Stk: ~p\n", [Stk]), io:fwrite("Cs: ~p\n", [Cs]), io:fwrite("I: ~p\n", [I]), io:put_chars("--------\n") end), emul_1(Is, Cont, Lvs, Stk, Env, Cs, St); emul([], Cont, Lvs, Stk, Env, Cs, St) -> ?ITRACE_DO(begin io:fwrite("Is: ~p\n", [[]]), io:fwrite("Cnt: ~p\n", [Cont]), io:fwrite("Lvs: ~p\n", [Lvs]), io:fwrite("Env: ~p\n", [Env]), io:fwrite("Stk: ~p\n", [Stk]), io:fwrite("Cs: ~p\n", [Cs]), io:put_chars("--------\n") end), emul_1([], Cont, Lvs, Stk, Env, Cs, St). %% itrace_print(Format, Args) -> %% ?ITRACE_DO(io:fwrite(Format, Args)). %% Expression instructions. emul_1([?PUSH_LIT(L)|Is], Cont, Lvs, Stk, Env, Cs, St) -> emul(Is, Cont, Lvs, [L|Stk], Env, Cs, St); emul_1([?PUSH_LVAR(D, I)|Is], Cont, Lvs, Stk, Env, Cs, St) -> Val = get_local_var(D, I, Lvs), emul(Is, Cont, Lvs, [Val|Stk], Env, Cs, St); emul_1([?PUSH_EVAR(D, I)|Is], Cont, Lvs, Stk, Env, Cs, St) -> Val = get_env_var(D, I, Env, St), emul(Is, Cont, Lvs, [Val|Stk], Env, Cs, St); emul_1([?PUSH_GVAR(Key)|Is], Cont, Lvs, Stk, Env, Cs, St0) -> %% We must handle the metamethod and error here. case luerl_heap:get_global_key(Key, St0) of {value,Val,St1} -> emul(Is, Cont, Lvs, [Val|Stk], Env, Cs, St1); {meta,Meth,Args,St1} -> emul([?FCALL,?SINGLE|Is], Cont, Lvs, [Args,Meth|Stk], Env, Cs, St1); {error,Error,St1} -> lua_error(Error, St1#luerl{stk=Stk,cs=Cs}) end; emul_1([?PUSH_LAST_LIT(L)|Is], Cont, Lvs, Stk, Env, Cs, St) -> emul(Is, Cont, Lvs, [[L]|Stk], Env, Cs, St); emul_1([?PUSH_LAST_LVAR(D, I)|Is], Cont, Lvs, Stk, Env, Cs, St) -> Val = get_local_var(D, I, Lvs), emul(Is, Cont, Lvs, [[Val]|Stk], Env, Cs, St); emul_1([?PUSH_LAST_EVAR(D, I)|Is], Cont, Lvs, Stk, Env, Cs, St) -> Val = get_env_var(D, I, Env, St), emul(Is, Cont, Lvs, [[Val]|Stk], Env, Cs, St); emul_1([?PUSH_LAST_GVAR(Key)|Is], Cont, Lvs, Stk, Env, Cs, St0) -> %% We must handle the metamethod and error here. case luerl_heap:get_global_key(Key, St0) of {value,Val,St1} -> emul(Is, Cont, Lvs, [[Val]|Stk], Env, Cs, St1); {meta,Meth,Args,St1} -> emul([?FCALL|Is], Cont, Lvs, [Args,Meth|Stk], Env, Cs, St1); {error,Error,St1} -> lua_error(Error, St1#luerl{stk=Stk,cs=Cs}) end; emul_1([?STORE_LVAR(D, I)|Is], Cont, Lvs0, [Val|Stk], Env, Cs, St) -> Lvs1 = set_local_var(D, I, Val, Lvs0), emul(Is, Cont, Lvs1, Stk, Env, Cs, St); emul_1([?STORE_EVAR(D, I)|Is], Cont, Lvs, [Val|Stk], Env, Cs, St0) -> St1 = set_env_var(D, I, Val, Env, St0), emul(Is, Cont, Lvs, Stk, Env, Cs, St1); emul_1([?STORE_GVAR(Key)|Is], Cont, Lvs, [Val|Stk], Env, Cs, St0) -> %% We must handle the metamethod and error here. case luerl_heap:set_global_key(Key, Val, St0) of {value,_,St1} -> emul(Is, Cont, Lvs, Stk, Env, Cs, St1); {meta,Meth,Args,St1} -> emul([?FCALL,?POP|Is], Cont, Lvs, [Args,Meth|Stk], Env, Cs, St1); {error,Error,St1} -> lua_error(Error, St1#luerl{stk=Stk,cs=Cs}) end; emul_1([?GET_KEY|Is], Cont, Lvs, [Key,Tab|Stk], Env, Cs, St) -> do_get_key(Is, Cont, Lvs, Stk, Env, Cs, St, Tab, Key); emul_1([?GET_LIT_KEY(Key)|Is], Cont, Lvs, [Tab|Stk], Env, Cs, St) -> %% [?PUSH_LIT(Key),?GET_KEY] do_get_key(Is, Cont, Lvs, Stk, Env, Cs, St, Tab, Key); emul_1([?SET_KEY|Is], Cont, Lvs, [Key,Tab,Val|Stk], Env, Cs, St) -> do_set_key(Is, Cont, Lvs, Stk, Env, Cs, St, Tab, Key, Val); emul_1([?SET_LIT_KEY(Key)|Is], Cont, Lvs, [Tab,Val|Stk], Env, Cs, St) -> %% [?PUSH_LIT(Key),?SET_KEY] do_set_key(Is, Cont, Lvs, Stk, Env, Cs, St, Tab, Key, Val); emul_1([?SINGLE|Is], Cont, Lvs, [Val|Stk], Env, Cs, St) -> emul(Is, Cont, Lvs, [first_value(Val)|Stk], Env, Cs, St); emul_1([?MULTIPLE|Is], Cont, Lvs, [Val|Stk], Env, Cs, St) -> emul(Is, Cont, Lvs, [multiple_value(Val)|Stk], Env, Cs, St); emul_1([?BUILD_TAB(Fc, I)|Is], Cont, Lvs, Stk0, Env, Cs, St0) -> {Tab,Stk1,St1} = build_tab(Fc, I, Stk0, St0), emul(Is, Cont, Lvs, [Tab|Stk1], Env, Cs, St1); emul_1([?FCALL|Is], Cont, Lvs, Stk, Env, Cs, St) -> do_fcall(Is, Cont, Lvs, Stk, Env, Cs, St); emul_1([?TAIL_FCALL|Is], Cont, Lvs, Stk, Env, Cs, St) -> do_tail_fcall(Is, Cont, Lvs, Stk, Env, Cs, St); emul_1([?MCALL(M)|Is], Cont, Lvs, Stk, Env, Cs, St) -> do_mcall(Is, Cont, Lvs, Stk, Env, Cs, St, M); emul_1([?TAIL_MCALL(M)|Is], Cont, Lvs, Stk, Env, Cs, St) -> do_tail_mcall(Is, Cont, Lvs, Stk, Env, Cs, St, M); emul_1([?OP(Op,1)|Is], Cont, Lvs, Stk, Env, Cs, St) -> do_op1(Is, Cont, Lvs, Stk, Env, Cs, St, Op); emul_1([?OP(Op,2)|Is], Cont, Lvs, Stk, Env, Cs, St) -> do_op2(Is, Cont, Lvs, Stk, Env, Cs, St, Op); emul_1([?PUSH_FDEF(Funref)|Is], Cont, Lvs, Stk, Env, Cs, St0) -> %% Update the env field of the function reference with the current %% environment. Funref1 = Funref#funref{env=Env}, emul(Is, Cont, Lvs, [Funref1|Stk], Env, Cs, St0); %% Control instructions. emul_1([?BLOCK(Lsz, Esz, Bis)|Is], Cont, Lvs, Stk, Env, Cs, St) -> do_block(Is, Cont, Lvs, Stk, Env, Cs, St, Lsz, Esz, Bis); emul_1([?BLOCK_OPEN(Lsz, Esz)|Is], Cont, Lvs, Stk, Env, Cs, St) -> do_block_open(Is, Cont, Lvs, Stk, Env, Cs, St, Lsz, Esz); emul_1([?BLOCK_CLOSE|Is], Cont, Lvs, Stk, Env, Cs, St) -> do_block_close(Is, Cont, Lvs, Stk, Env, Cs, St); emul_1([?WHILE(Eis, Wis)|Is], Cont, Lvs, Stk, Env, Cs, St) -> do_while(Is, Cont, Lvs, Stk, Env, Cs, St, Eis, Wis); emul_1([?WHILE_LOOP(Eis, Wis)|Is], Cont, Lvs, Stk, Env, Cs, St) -> do_while_loop(Is, Cont, Lvs, Stk, Env, Cs, St, Eis, Wis); emul_1([?REPEAT(Ris)|Is], Cont, Lvs, Stk, Env, Cs, St) -> do_repeat(Is, Cont, Lvs, Stk, Env, Cs, St, Ris); emul_1([?REPEAT_LOOP(Ris)|Is], Cont, Lvs, Stk, Env, Cs, St) -> do_repeat_loop(Is, Cont, Lvs, Stk, Env, Cs, St, Ris); emul_1([?AND_THEN(Then)|Is], Cont, Lvs, Stk, Env, Cs, St) -> do_and_then(Is, Cont, Lvs, Stk, Env, Cs, St, Then); emul_1([?OR_ELSE(Else)|Is], Cont, Lvs, Stk, Env, Cs, St) -> do_or_else(Is, Cont, Lvs, Stk, Env, Cs, St, Else); emul_1([?IF_TRUE(True)|Is], Cont, Lvs, Stk, Env, Cs, St) -> do_if_true(Is, Cont, Lvs, Stk, Env, Cs, St, True); emul_1([?IF(True, False)|Is], Cont, Lvs, Stk, Env, Cs, St) -> do_if(Is, Cont, Lvs, Stk, Env, Cs, St, True, False); emul_1([?NFOR(V, Fis)|Is], Cont, Lvs, Stk, Env, Cs, St) -> do_numfor(Is, Cont, Lvs, Stk, Env, Cs, St, V, Fis); emul_1([?NFOR_LOOP(N,L,S,Fis)|Is], Cont, Lvs, Stk, Env, Cs, St) -> do_numfor_loop(Is, Cont, Lvs, Stk, Env, Cs, St, N, L, S, Fis); emul_1([?GFOR(Vs, Fis)|Is], Cont, Lvs, Stk, Env, Cs, St) -> do_genfor(Is, Cont, Lvs, Stk, Env, Cs, St, Vs, Fis); emul_1([?GFOR_CALL(Func, Data, Val, Fis)|Is], Cont, Lvs, Stk, Env, Cs, St) -> do_genfor_call(Is, Cont, Lvs, Stk, Env, Cs, St, Func, Data, Val, Fis); emul_1([?GFOR_LOOP(Func, Data, Fis)|Is], Cont, Lvs, Stk, Env, Cs, St) -> do_genfor_loop(Is, Cont, Lvs, Stk, Env, Cs, St, Func, Data, Fis); emul_1([?BREAK|_], _Cont, Lvs, _Stk, _Env, Cs, St) -> do_break(Lvs, Cs, St); emul_1([?RETURN(Ac)|_], _Cont, _Lvs, Stk, _Env, Cs, St) -> do_return(Ac, Stk, Cs, St); %% Stack instructions emul_1([?POP|Is], Cont, Lvs, [_|Stk], Env, Cs, St) -> emul(Is, Cont, Lvs, Stk, Env, Cs, St); emul_1([?POP2|Is], Cont, Lvs, [_,_|Stk], Env, Cs, St) -> emul(Is, Cont, Lvs, Stk, Env, Cs, St); emul_1([?SWAP|Is], Cont, Lvs, [S1,S2|Stk], Env, Cs, St) -> emul(Is, Cont, Lvs, [S2,S1|Stk], Env, Cs, St); emul_1([?DUP|Is], Cont, Lvs, [V|_]=Stk, Env, Cs, St) -> emul(Is, Cont, Lvs, [V|Stk], Env, Cs, St); emul_1([?PUSH_VALS(Vc)|Is], Cont, Lvs, [Vals|Stk0], Env, Cs, St) -> %% Pop value list off the stack and push Vc vals from it. Stk1 = push_vals(Vc, Vals, Stk0), emul(Is, Cont, Lvs, Stk1, Env, Cs, St); emul_1([?POP_VALS(Vc)|Is], Cont, Lvs, Stk0, Env, Cs, St) -> %% Pop Vc vals off the stack, put in a list and push onto the stack. {Vals,Stk1} = pop_vals(Vc, Stk0), emul(Is, Cont, Lvs, [Vals|Stk1], Env, Cs, St); emul_1([?PUSH_ARGS(Al)|Is], Cont, Lvs, [Args|Stk0], Env, Cs, St) -> %% Pop argument list off the stack and push args onto the stack. Stk1 = push_args(Al, Args, Stk0), emul(Is, Cont, Lvs, Stk1, Env, Cs, St); emul_1([?POP_ARGS(Ac)|Is], Cont, Lvs, Stk0, Env, Cs, St) -> %% Pop Ac args off the stack, put in a list and push onto the stack. {Args,Stk1} = pop_vals(Ac, Stk0), emul(Is, Cont, Lvs, [Args|Stk1], Env, Cs, St); emul_1([?COMMENT(_)|Is], Cont, Lvs, Stk, Env, Cs, St) -> %% This just a comment which is ignored. emul(Is, Cont, Lvs, Stk, Env, Cs, St); emul_1([?CURRENT_LINE(Line,File)|Is], Cont, Lvs, Stk, Env, Cs, St) -> do_current_line(Is, Cont, Lvs, Stk, Env, Cs, St, Line, File); emul_1([], [Is|Cont], Lvs, Stk, Env, Cs, St) -> emul(Is, Cont, Lvs, Stk, Env, Cs, St); emul_1([], [], Lvs, Stk, Env, Cs, St) -> {Lvs,Stk,Env,Cs,St}. %% pop_vals(Count, Stack) -> {ValList,Stack}. %% pop_vals(Count, Stack, ValList) -> {ValList,Stack}. %% Pop Count values off the stack and push onto the value list. %% First value is deepest. Always generates list. pop_vals(0, Stk) -> {[],Stk}; pop_vals(C, [Vtail|Stk]) -> %This a list tail pop_vals(C-1, Stk, Vtail). pop_vals(0, Stk, Vs) -> {Vs,Stk}; pop_vals(1, [V|Stk], Vs) -> {[V|Vs],Stk}; pop_vals(2, [V2,V1|Stk], Vs) -> {[V1,V2|Vs],Stk}; pop_vals(C, [V2,V1|Stk], Vs) -> pop_vals(C-2, Stk, [V1,V2|Vs]). %% push_vals(Count, ValList, Stack) -> Stack. %% Push Count values from ValList onto the stack. First value is %% deepest. Fill with 'nil' if not enough values. push_vals(0, _, Stk) -> Stk; push_vals(C, [V|Vs], Stk) -> push_vals(C-1, Vs, [V|Stk]); push_vals(C, [], Stk) -> push_vals(C-1, [], [nil|Stk]). %% push_args(Varlist, ArgList, Stack) -> Stack. %% Use Varlist to push args from ArgList onto the stack. First arg is %% deepest. Tail of VarList determines whether there are varargs. push_args([_V|Vs], [A|As], Stk) -> push_args(Vs, As, [A|Stk]); push_args([_V|Vs], [], Stk) -> push_args(Vs, [], [nil|Stk]); push_args([], _As, Stk) -> Stk; %Drop the rest push_args(_V, As, Stk) -> %Varargs ... save as list [As|Stk]. %% do_set_key(Instrs, LocalVars, Stack, Env, State, Table, Key, Val) -> %% ReturnFromEmul. %% do_get_key(Instrs, LocalVars, Stack, Env, State, Table, Key) -> %% ReturnFromEmul. do_set_key(Is, Cont, Lvs, Stk, Env, Cs, St0, Tab, Key, Val) -> %% We must handle the metamethod and error here. case luerl_heap:set_table_key(Tab, Key, Val, St0) of {value,_,St1} -> emul(Is, Cont, Lvs, Stk, Env, Cs, St1); {meta,Meth,Args,St1} -> emul([?FCALL,?POP|Is], Cont, Lvs, [Args,Meth|Stk], Env, Cs, St1); {error,Error,St1} -> lua_error(Error, St1#luerl{stk=Stk,cs=Cs}) end. do_get_key(Is, Cont, Lvs, Stk, Env, Cs, St0, Tab, Key) -> %% We must handle the metamethod and error here. case luerl_heap:get_table_key(Tab, Key, St0) of {value,Val,St1} -> emul(Is, Cont, Lvs, [Val|Stk], Env, Cs, St1); {meta,Meth,Args,St1} -> emul([?FCALL,?SINGLE|Is], Cont, Lvs, [Args,Meth|Stk], Env, Cs, St1); {error,Error,St1} -> lua_error(Error, St1#luerl{stk=Stk,cs=Cs}) end. %% do_op1(Instrs, LocalVars, Stack, Env, State, Op) -> ReturnFromEmul. %% do_op2(Instrs, LocalVars, Stack, Env, State, Op) -> ReturnFromEmul. do_op1(Is, Cont, Lvs, [A|Stk], Env, Cs, St0, Op) -> %% We must handle the metamethod and error here. case op(Op, A, St0) of {value,Res,St1} -> emul(Is, Cont, Lvs, [Res|Stk], Env, Cs, St1); {meta,Meth,Args,St1} -> emul([?FCALL,?SINGLE|Is], Cont, Lvs, [Args,Meth|Stk], Env, Cs, St1); {error,Error,St1} -> lua_error(Error, St1#luerl{stk=Stk,cs=Cs}) end. do_op2(Is, Cont, Lvs, [A2,A1|Stk], Env, Cs, St0, Op) -> %% We must handle the metamethod and error here. case op(Op, A1, A2, St0) of {value,Res,St1} -> emul(Is, Cont, Lvs, [Res|Stk], Env, Cs, St1); {meta,Meth,Args,St1} -> emul([?FCALL,?SINGLE|Is], Cont, Lvs, [Args,Meth|Stk], Env, Cs, St1); {error,Error,St1} -> lua_error(Error, St1#luerl{stk=Stk,cs=Cs}) end. %% do_break(LocalVars, CallStack, State) -> . do_break(Lvs0, Cs0, St) -> {Bf,Cs1} = find_loop_frame(Cs0, St), #loop_frame{is=Is,cont=Cont,lvs=Lvs1,stk=Stk,env=Env} = Bf, %% Trim the new local variable stack down to original length. Lvs2 = lists:nthtail(length(Lvs0)-length(Lvs1), Lvs0), emul(Is, Cont, Lvs2, Stk, Env, Cs1, St). %% do_return(ArgCount, Stack, Callstack, State) -> . do_return(Ac, Stk0, Cs0, St0) -> {Cf,Cs1} = find_call_frame(Cs0, St0), %Find the first call frame {Ret,Stk1} = pop_vals(Ac, Stk0), %% When tracing bring the state up to date and call the tracer. Tfunc = St0#luerl.trace_func, St1 = if is_function(Tfunc) -> Tfunc(?RETURN(Ret), St0#luerl{stk=Stk1,cs=Cs1}); true -> St0 end, #call_frame{is=Is,cont=Cont,lvs=Lvs,env=Env} = Cf, emul(Is, Cont, Lvs, [Ret|Stk1], Env, Cs1, St1#luerl{cs=Cs1}). find_call_frame([#call_frame{}=Cf|Cs], _St) -> {Cf,Cs}; find_call_frame([_|Cs], St) -> find_call_frame(Cs, St). find_loop_frame([#current_line{}|Cs], St) -> %Skip current line info find_loop_frame(Cs, St); find_loop_frame([#loop_frame{}=Bf|Cs], _St) -> {Bf,Cs}; find_loop_frame(Cs, St) -> lua_error({illegal_op,break}, St#luerl{cs=Cs}). %% do_current_line(Instrs, Continuation, LocalVars, Stack, Env, Stack, State, %% Line, File). do_current_line(Is, Cont, Lvs, Stk, Env, Cs0, St0, Line, File) -> Cs1 = push_current_line(Cs0, Line, File), %Push onto callstack %% When tracing bring the state up to date and call the tracer. Tfunc = St0#luerl.trace_func, St1 = if is_function(Tfunc) -> Tfunc(?CURRENT_LINE(Line, File), St0#luerl{stk=Stk,cs=Cs1}); true -> St0 end, emul(Is, Cont, Lvs, Stk, Env, Cs1, St1). %% push_current_line(CallStack, CurrLine, FileName) -> CallStack. %% Push the current line info on the stack replacing an existing one %% on the top. push_current_line([#current_line{}|Cs], Line, File) -> [#current_line{line=Line,file=File}|Cs]; push_current_line(Cs, Line, File) -> [#current_line{line=Line,file=File}|Cs]. %% do_fcall(Instrs, LocalVars, Stack, Env, State) -> ReturnFromEmul. %% Pop arg list and function from stack and do call. do_fcall(Is, Cont, Lvs, [Args,Func|Stk], Env, Cs, St) -> functioncall(Is, Cont, Lvs, Stk, Env, Cs, St, Func, Args). %% functioncall(Instrs, Cont, LocalVars, Stk, Env, CallStack, State, Func, Args) -> %% %% This is called from within code and continues with Instrs after %% call. It must move everything into State. functioncall(Is, Cont, Lvs, Stk, Env, Cs0, St, Func, Args) -> Fr = #call_frame{func=Func,args=Args,lvs=Lvs,env=Env,is=Is,cont=Cont}, Cs1 = [Fr|Cs0], call_function(Func, Args, Stk, Cs1, St). %% do_tail_fcall(Instrs, Cont, LocalVars, Stack, Env, State) -> %% ReturnFromEmul. do_tail_fcall(_Is, _Cont, _Lvs, [Args,Func|_Stk], _Env, Cs, St) -> error({tail_fcall,Func,Args,Cs,St}). %% do_mcall(Instrs, Cont, LocalVars, Stack, Env, State, Method) -> do_mcall(Is, Cont, Lvs, [Args,Obj|Stk], Env, Cs, St, M) -> methodcall(Is, Cont, Lvs, Stk, Env, Cs, St, Obj, M, Args). %% methodcall(Instrs, Cont, Var, Stk, Env, State, Object, Method, Args) -> %% %% This is called from within code and continues with Instrs after %% call. It must move everything into State. methodcall(Is, Cont, Lvs, Stk, Env, Cs, St0, Obj, Meth, Args) -> %% Get the function to call from object and method. %% We must handle the metamethod and error here. %% io:format("mc1 ~p ~p ~p\n", [Obj,Meth,Args]), case luerl_heap:get_table_key(Obj, Meth, St0) of {value,Func,St1} -> %% io:format("mc2 ~p\n", [Func]), functioncall(Is, Cont, Lvs, Stk, Env, Cs, St1, Func, [Obj|Args]); {meta,Mmeth,Margs,St1} -> %% io:format("mc3 ~p ~p\n", [Mmeth,Margs]), %% Must first meta method to get function and then call it. %% Need to swap to get arguments for call in right order. Is1 = [?FCALL,?SINGLE,?SWAP,?FCALL|Is], emul(Is1, Cont, Lvs, [Margs,Mmeth,[Obj|Args]|Stk], Env, Cs, St1); {error,_Error,St1} -> %No method lua_error({undefined_method,Obj,Meth}, St1#luerl{stk=Stk,cs=Cs}) end. %% do_tail_mcall(Instrs, Cont, LocalVars, Stack, Env, State, Method) -> %% . do_tail_mcall(_Is, _Cont, _Lvs, [Args,Obj|_Stk], _Env, Cs, St, Meth) -> error({tail_mcall,Obj,Meth,Args,Cs,St}). %% call_function(Function, Args, Stack, CallStack, State) -> {Return,State}. %% Setup environment for function and do the actual call. call_function(#funref{env=Env}=Funref, Args, Stk, Cs, St0) -> St1 = trace_call(Funref, Args, Stk, Cs, St0), %% Here we must save the stack in state as function may need it. {Func,St2} = luerl_heap:get_funcdef(Funref, St1#luerl{stk=Stk}), call_luafunc(Func, Args, Stk, Env, Cs, St2); call_function(#erl_func{code=Func}=Funref, Args, Stk, Cs, St0) -> St1 = trace_call(Funref, Args, Stk, Cs, St0), call_erlfunc(Func, Args, Stk, Cs, St1); call_function(#erl_mfa{m=M,f=F,a=A}=Funref, Args, Stk, Cs, St0) -> St1 = trace_call(Funref, Args, Stk, Cs, St0), call_erlmfa({M,F,A}, Args, Stk, Cs, St1); call_function(Func, Args, Stk, Cs, St) -> case luerl_heap:get_metamethod(Func, <<"__call">>, St) of nil -> lua_error({undefined_function,Func}, St#luerl{stk=Stk,cs=Cs}); Meta -> call_function(Meta, [Func|Args], Stk, Cs, St) end. %% trace_call((Function, Args, Stack, CallStack, State) -> State. %% Trace the function call when required. trace_call(Funref, Args, _Stk, _Cs, St) -> %% When tracing bring the state up to date and call the tracer. Tfunc = St#luerl.trace_func, if is_function(Tfunc) -> Tfunc({fcall,Funref,Args}, St); true -> St end. %% call_luafunc(LuaFunc, Args, Stack, Env, CallStack, State) -> {Return,State}. %% Make the local variable and Env frames and push them onto %% respective stacks and call the function. call_luafunc(#lua_func{lsz=Lsz,esz=Esz,pars=_Pars,body=Fis}, Args, Stk0, Env0, Cs, St0) -> L = make_loc_frame(Lsz), {Eref,St1} = make_env_frame(Esz, St0), Lvs = [L], Stk1 = [Args|Stk0], Env1 = [Eref|Env0], %% Tag = St0#luerl.tag, %% io:fwrite("fc: ~p\n", [{Lvs,Env,St0#luerl.env}]), emul(Fis, [], Lvs, Stk1, Env1, Cs, St1). %% call_erlfunc(ErlFunc, Args, Stack, CallStack, State) -> {Return,State}. %% Here we must save the stacks in state as function may need it. %% Note we leave the call frame to the erlang function on the call %% stack. It is popped when we return. call_erlfunc(Func, Args, Stk, Cs0, #luerl{stk=Stk0}=St0) -> case Func(Args, St0#luerl{stk=Stk,cs=Cs0}) of %% {Ret,#luerl{}=St1} when is_list(Ret) -> {Ret,St1} -> [#call_frame{is=Is,cont=Cont,lvs=Lvs,env=Env}|Cs1] = Cs0, emul(Is, Cont, Lvs, [Ret|Stk], Env, Cs1, St1#luerl{stk=Stk0,cs=Cs1}); _Other -> %% Don't include the erl_func in the call stack. lua_error(illegal_return_value, St0#luerl{stk=Stk0,cs=tl(Cs0)}) end. %% call_erlmfa({M,F,A}, Args, Stack, CallStack, State) -> {Return,State}. %% We have two sets of arguments here: the "configured" ones that always %% get passed to the function (A) and the "runtime" ones that are specific %% to this call (Args). For simplicity, we combine them into a list so you %% get a ternary function receiving (A, Args, State). call_erlmfa({M,F,A}, Args, Stk, Cs0, #luerl{stk=Stk0}=St0) -> case apply(M, F, [A, Args, St0#luerl{stk=Stk,cs=Cs0}]) of {Ret,St1} -> [#call_frame{is=Is,cont=Cont,lvs=Lvs,env=Env}|Cs1] = Cs0, emul(Is, Cont, Lvs, [Ret|Stk], Env, Cs1, St1#luerl{stk=Stk0,cs=Cs1}); _Other -> %% Don't include the erl_func in the call stack. lua_error(illegal_return_value, St0#luerl{stk=Stk0,cs=tl(Cs0)}) end. %% do_block(Instrs, LocalVars, Stack, Env, State, %% LocalSize, EnvSize, BlockInstrs) -> . %% Local vars may have been updated so must continue with returned %% version. We also continue with returned stack. There should be no %% changes in the env. do_block(Is, Cont, Lvs, Stk, Env, Cs, St0, Lsz, Esz, Bis) -> L = make_loc_frame(Lsz), {Eref,St1} = make_env_frame(Esz, St0), emul(Bis, [Is|Cont], [L|Lvs], Stk, [Eref|Env], Cs, St1). %% do_block_open(Instrs, LocalVars, Stack, Env, State, %% LocalSize, EnvSize) -> . %% Local vars may have been updated so must continue with returned %% version. We also continue with returned stack. There should be no %% changes in the env. do_block_open(Is, Cont, Lvs, Stk, Env, Cs, St0, Lsz, Esz) -> L = make_loc_frame(Lsz), {Eref,St1} = make_env_frame(Esz, St0), emul(Is, Cont, [L|Lvs], Stk, [Eref|Env], Cs, St1). %% do_block_close(Instrs, LocalVars, Stack, Env, State, %% LocalSize, EnvSize) -> . %% Pop the block local variables and environment variables. do_block_close(Is, Cont, [_|Lvs], Stk, [_|Env], Cs, St) -> emul(Is, Cont, Lvs, Stk, Env, Cs, St). make_env_frame(0, St) -> {not_used,St}; make_env_frame(Esz, St) -> luerl_heap:alloc_environment(Esz, St). %{Eref,St}. make_loc_frame(0) -> not_used; make_loc_frame(Lsz) -> erlang:make_tuple(Lsz, nil). %% do_while(Instrs, Cont, LocalVars, Stack, Env, State, WhileEis, WhileBis) -> %% do_while(Is, Cont, Lvs, Stk, Env, Cs0, St, Eis, Wis) -> %% Add the break frame to the call stack. Fr = #loop_frame{lvs=Lvs,stk=Stk,env=Env,is=Is,cont=Cont}, Cs1 = [Fr|Cs0], emul(Eis, [[?WHILE_LOOP(Eis, Wis)|Is]|Cont], Lvs, Stk, Env, Cs1, St). do_while_loop(Is, Cont, Lvs, [Val|Stk], Env, Cs, St, Eis, Wis) -> case boolean_value(Val) of true -> emul(Wis, [Eis,[?WHILE_LOOP(Eis, Wis)|Is]|Cont], Lvs, Stk, Env, Cs, St); false -> emul([?BREAK|Is], Cont, Lvs, Stk, Env, Cs, St) end. %% do_repeat(Instrs, Cont, LocalVars, Stack, Env, State, RepeatInstrs) -> %% %% We know that at the end of the repear instructions the test value %% is calculated. do_repeat(Is, Cont, Lvs, Stk, Env, Cs0, St, Ris) -> %% Add the break frame to the call stack. Fr = #loop_frame{lvs=Lvs,stk=Stk,env=Env,is=Is,cont=Cont}, Cs1 = [Fr|Cs0], emul(Ris, [[?REPEAT_LOOP(Ris)|Is]|Cont], Lvs, Stk, Env, Cs1, St). do_repeat_loop(Is, Cont, Lvs, [Val|Stk], Env, Cs, St, Ris) -> case boolean_value(Val) of true -> emul([?BREAK|Is], Cont, Lvs, Stk, Env, Cs, St); false -> emul(Ris, [[?REPEAT_LOOP(Ris)|Is]|Cont], Lvs, Stk, Env, Cs, St) end. %% do_and_then(Instrs, Continuation,LocalVars, Stack, Env, State, ThenInstrs) -> %% . %% do_or_else(Instrs, Continuation,LocalVars, Stack, Env, State, ElseInstrs) -> %% . do_and_then(Is, Cont, Lvs, [Val|Stk1]=Stk0, Env, Cs, St, Then) -> %% This is an expression and must always leave a value on stack. case boolean_value(Val) of true -> emul(Then, [Is|Cont], Lvs, Stk1, Env, Cs, St); false -> %% Non true value left on stack. emul(Is, Cont, Lvs, Stk0, Env, Cs, St) end. do_or_else(Is, Cont, Lvs, [Val|Stk1]=Stk0, Env, Cs, St, Else) -> %% This is an expression and must always leave a value on stack. case boolean_value(Val) of true -> %% Non false value left on stack. emul(Is, Cont, Lvs, Stk0, Env, Cs, St); false -> emul(Else, [Is|Cont], Lvs, Stk1, Env, Cs, St) end. %% do_if(Instrs, Continuation, LocalVars, Stack, Env, State, TrueInstrs) -> %% . %% Test value on stack to choose whether to do True instructions. do_if_true(Is, Cont, Lvs, [Val|Stk], Env, Cs, St, True) -> case boolean_value(Val) of true -> emul(True, [Is|Cont], Lvs, Stk, Env, Cs, St); false -> emul(Is, Cont, Lvs, Stk, Env, Cs, St) end. %% do_if(Instrs, LocalVars, Stack, Env, State, TrueInstrs, FalseInstrs) -> %% . %% Test value on stack to choose either True or False instructions. do_if(Is, Cont, Lvs0, [Val|Stk0], Env0, Cs, St0, True, False) -> case boolean_value(Val) of true -> emul(True, [Is|Cont], Lvs0, Stk0, Env0, Cs, St0); false -> emul(False, [Is|Cont], Lvs0, Stk0, Env0, Cs, St0) end. %% do_if(Blocks, Else, Lvs, Stk, Env, St) -> %% do_if_blocks(Blocks, Else, Lvs, Stk, Env, St). %% do_if_blocks([{T,B}|Ts], Else, Lvs0, Stk0, Env0, St0) -> %% {Lvs1,[Val|Stk1],Env1,St1} = emul(T, Lvs0, Stk0, Env0, St0), %% case boolean_value(Val) of %% true -> emul(B, Lvs1, Stk1, Env1, St1); %% false -> do_if_blocks(Ts, Lvs1, Stk1, Env1, St1) %% end; %% do_if_blocks([], Else, Lvs, Stk, Env, St) -> %% emul(Else, Lvs, Stk, Env, St). %% do_if_block([?BLOCK(Lsz, Esz, Bis)], Lvs0, Stk0, Env0, St0, Is) -> %% {Lvs1,Stk1,Env1,St1} = do_block(Bis, Lvs0, Stk0, Env0, St0, Lsz, Esz), %% emul(Is, Lvs1, Stk1, Env1, St1); %% do_if_block(Bis, Lvs0, Stk0, Env0, St0, Is) -> %% {Lvs1,Stk1,Env1,St1} = emul(Bis, Lvs0, Stk0, Env0, St0), %% emul(Is, Lvs1, Stk1, Env1, St1). %% do_numfor(Instrs, LocalVars, Stack, Env, State, Varname, FromInstrs) -> %% do_numfor(Is, Cont, Lvs, [Step,Limit,Init|Stk], Env, Cs0, St, _, Fis) -> %% First check if we have numbers. case luerl_lib:args_to_numbers([Init,Limit,Step]) of [I,L,S] -> %% Add the break frame to the call stack. Fr = #loop_frame{lvs=Lvs,stk=Stk,env=Env,is=Is,cont=Cont}, Cs1 = [Fr|Cs0], do_numfor_loop(Is, Cont, Lvs, Stk, Env, Cs1, St, I, L, S, Fis); error -> badarg_error(loop, [Init,Limit,Step], St#luerl{cs=Cs0}) end. do_numfor_loop(Is, Cont, Lvs, Stk, Env, Cs, St, N, Limit, Step, Fis) -> %% itrace_print("nl: ~p\n", [{N,Stk}]), %% Leave the current counter at the top of the stack for code to get. if Step > 0, N =< Limit -> %Keep going emul(Fis, [[?NFOR_LOOP(N+Step, Limit, Step, Fis)|Is]|Cont], Lvs, [N|Stk], Env, Cs, St); Step < 0, N >= Limit -> %Keep going emul(Fis, [[?NFOR_LOOP(N+Step, Limit, Step, Fis)|Is]|Cont], Lvs, [N|Stk], Env, Cs, St); true -> %Done! emul([?BREAK|Is], Cont, Lvs, Stk, Env, Cs, St) end. %% do_genfor(Instrs, LocalVars, Stack, Env, %% CallStack, State, Vars, FromInstrs) -> %% The top of the stack will contain the return values from the explist. do_genfor(Is, Cont, Lvs, [Val|Stk], Env, Cs0, St, _, Fis) -> case Val of %Sneaky, export Func, Data, Var [Func] -> Data = nil, Var = nil; [Func,Data] -> Var = nil; [Func,Data,Var|_] -> ok; Func -> Data = nil, Var = nil end, %% Add the break frame to the call stack. Fr = #loop_frame{lvs=Lvs,stk=Stk,env=Env,is=Is,cont=Cont}, Cs1 = [Fr|Cs0], do_genfor_call(Is, Cont, Lvs, Stk, Env, Cs1, St, Func, Data, Var, Fis). do_genfor_call(Is, Cont, Lvs, Stk, Env, Cs, St, Func, Data, Val, Fis) -> emul([?FCALL,?GFOR_LOOP(Func, Data, Fis)|Is], Cont, Lvs, [[Data,Val],Func|Stk], Env, Cs, St). do_genfor_loop(Is, Cont, Lvs, [Vals|Stk], Env, Cs, St, Func, Data, Fis) -> case boolean_value(Vals) of true -> emul(Fis, [[?GFOR_CALL(Func,Data,hd(Vals),Fis)|Is]|Cont], Lvs, [Vals|Stk], Env, Cs, St); false -> emul([?BREAK|Is], Cont, Lvs, Stk, Env, Cs, St) end. %% build_tab(FieldCount, Index, Stack, State) -> {TableRef,Stack,State}. %% FieldCount is how many Key/Value pairs are on the stack, Index is %% the index of the next value in the acc. build_tab(Fc, I, [Last|Stk0], St0) -> Fs0 = build_tab_last(I, Last), {Fs1,Stk1} = build_tab_loop(Fc, Stk0, Fs0), %% io:fwrite("bt: ~p\n", [{Fc,I,Acc,Fs0,Fs1}]), {Tref,St1} = luerl_heap:alloc_table(Fs1, St0), {Tref,Stk1,St1}. build_tab_last(I, [V|Vs]) -> [{I,V}|build_tab_last(I+1, Vs)]; build_tab_last(_, []) -> []; build_tab_last(_, Last) -> error({boom,build_tab_acc,Last}). build_tab_loop(0, Stk, Fs) -> {Fs,Stk}; build_tab_loop(C, [V,K|Stk], Fs) -> build_tab_loop(C-1, Stk, [{K,V}|Fs]). %% op(Op, Arg, State) -> OpReturn. %% op(Op, Arg1, Arg2, State) -> OpReturn. %% %% OpReturn = {value,Ret,State} | %% {meta,Method,Args,State} | %% {error,Error,State}. %% %% The built-in operators. Always return a single value! op('-', A, St) -> numeric_op('-', A, St, <<"__unm">>, fun (N) -> -N end); op('not', A, St) -> {value,not ?IS_TRUE(A),St}; op('~', A, St) -> integer_op('~', A, St, <<"__bnot">>, fun (N) -> bnot(N) end); op('#', A, St) -> length_op('#', A, St); op(Op, A, St) -> {error,{badarg,Op,[A]},St}. %% Numeric operators. op('+', A1, A2, St) -> numeric_op('+', A1, A2, St, <<"__add">>, fun (N1,N2) -> N1+N2 end); op('-', A1, A2, St) -> numeric_op('-', A1, A2, St, <<"__sub">>, fun (N1,N2) -> N1-N2 end); op('*', A1, A2, St) -> numeric_op('*', A1, A2, St, <<"__mul">>, fun (N1,N2) -> N1*N2 end); op('/', A1, A2, St) -> numeric_op('/', A1, A2, St, <<"__div">>, fun (N1,N2) -> N1/N2 end); %% The '//' and '%' operators are specially handled to avoid first %% converting integers to floats and potentially lose precision. op('//', A1, A2, St) -> numeric_op('//', A1, A2, St, <<"__idiv">>, fun (N1,N2) when is_integer(N1), is_integer(N2) -> Idiv = N1 div N2, Irem = N1 rem N2, if Irem =:= 0 -> Idiv; Idiv < 0 -> Idiv - 1; true -> Idiv end; (N1,N2) -> 0.0 + floor(N1/N2) end); op('%', A1, A2, St) -> numeric_op('%', A1, A2, St, <<"__mod">>, fun (N1,N2) when is_integer(N1), is_integer(N2) -> Irem = N1 rem N2, if (Irem < 0) and (N2 >= 0) -> Irem + N2; (Irem > 0) and (N2 < 0) -> Irem + N2; true -> Irem end; %% if Irem < 0 -> %% if N2 < 0 -> Irem; %% true -> Irem + N2 %% end; %% Irem > 0 -> %% if N2 < 0 -> Irem + N2; %% true -> Irem %% end; %% true -> 0 %Irem =:= 0 %% end; (N1,N2) -> N1 - floor(N1/N2)*N2 end); op('^', A1, A2, St) -> numeric_op('^', A1, A2, St, <<"__pow">>, fun (N1,N2) -> math:pow(N1, N2) end); %% Bitwise operators. %% The '>>' is an arithmetic shift as a logical shift implies a word %% size which we don't have. op('&', A1, A2, St) -> integer_op('&', A1, A2, St, <<"__band">>, fun (N1,N2) -> N1 band N2 end); op('|', A1, A2, St) -> integer_op('|', A1, A2, St, <<"__bor">>, fun (N1,N2) -> N1 bor N2 end); op('~', A1, A2, St) -> integer_op('~', A1, A2, St, <<"__bxor">>, fun (N1,N2) -> N1 bxor N2 end); op('<<', A1, A2, St) -> integer_op('<<', A1, A2, St, <<"__shl">>, fun (N1,N2) -> N1 bsl N2 end); op('>>', A1, A2, St) -> integer_op('>>', A1, A2, St, <<"__shr">>, fun (N1,N2) -> N1 bsr N2 end); %% Relational operators, getting close. op('==', A1, A2, St) -> eq_op('==', A1, A2, St); op('~=', A1, A2, St) -> neq_op('~=', A1, A2, St); op('<=', A1, A2, St) -> le_op('<=', A1, A2, St); op('>=', A1, A2, St) -> le_op('>=', A2, A1, St); op('<', A1, A2, St) -> lt_op('<', A1, A2, St); op('>', A1, A2, St) -> lt_op('>', A2, A1, St); %% String operator. op('..', A1, A2, St) -> concat_op(A1, A2, St); %% Bad args here. op(Op, A1, A2, St) -> {error,{badarg,Op,[A1,A2]}, St}. -ifndef(HAS_FLOOR). %% floor(Number) -> integer(). %% Floor does not exist before 20 so we need to do it ourselves. floor(N) when is_integer(N) -> N; floor(N) when is_float(N) -> round(N - 0.5). -endif. %% length_op(Op, Arg, State) -> OpReturn. %% numeric_op(Op, Arg, State, Event, Raw) -> OpReturn. %% numeric_op(Op, Arg, Arg, State, Event, Raw) -> OpReturn. %% integer_op(Op, Arg, State, Event, Raw) -> OpReturn. %% integer_op(Op, Arg, Arg, State, Event, Raw) -> OpReturn. %% eq_op(Op, Arg, Arg, State) -> OpReturn. %% neq_op(Op, Arg, Arg, State) -> OpReturn. %% lt_op(Op, Arg, Arg, State) -> OpReturn. %% le_op(Op, Arg, Arg, State) -> OpReturn. %% concat_op(Arg, Arg, State) -> OpReturn. %% %% OpReturn = {value,Ret,State} | %% {meta,Method,Args,State} | %% {error,Error,State}. %% %% Together with their metas straight out of the reference %% manual. Note that: %% - numeric_op string args are always floats %% - eq/neq metamethods here must return boolean values and the tests %% themselves are type dependent length_op(_Op, A, St) when is_binary(A) -> {value,byte_size(A),St}; length_op(_Op, A, St) -> case luerl_heap:get_metamethod(A, <<"__len">>, St) of nil -> if ?IS_TREF(A) -> {value,luerl_lib_table:raw_length(A, St),St}; true -> {error,{badarg,'#',[A]}, St} end; Meth -> {meta,Meth,[A],St} end. numeric_op(Op, A, St, E, Raw) -> case luerl_lib:arg_to_number(A) of error -> numeric_op_meta(Op, A, E, St); N -> do_numeric_op(Op, [N], St, Raw) end. numeric_op(Op, A1, A2, St, E, Raw) -> case luerl_lib:args_to_numbers(A1, A2) of [_N1,_N2] = Ns -> do_numeric_op(Op, Ns, St, Raw); error -> numeric_op_meta(Op, A1, A2, E, St) end. integer_op(Op, A, St, E, Raw) -> case luerl_lib:arg_to_integer(A) of error -> numeric_op_meta(Op, A, E, St); N -> do_numeric_op(Op, [N], St, Raw) end. integer_op(Op, A1, A2, St, E, Raw) -> case luerl_lib:args_to_integers(A1, A2) of [_N1,_N2] = Ns -> do_numeric_op(Op, Ns, St, Raw); error -> numeric_op_meta(Op, A1, A2, E, St) end. %% do_numeric_op(Op, Numbers, State, Raw) -> %% {value,Value,State) | {error,Error,State}. do_numeric_op(Op, Ns, St, Raw) -> try {value,apply(Raw, Ns),St} catch ?CATCH(_, _, _) {error,{badarith,Op,Ns},St} end. numeric_op_meta(Op, A, E, St) -> case luerl_heap:get_metamethod(A, E, St) of nil -> {error,{badarith,Op,[A]}, St}; Meth -> {meta,Meth,[A],St} end. numeric_op_meta(Op, A1, A2, E, St) -> case luerl_heap:get_metamethod(A1, A2, E, St) of nil -> {error,{badarith,Op,[A1,A2]},St}; Meth -> {meta,Meth,[A1,A2],St} end. eq_op(_Op, A1, A2, St) when A1 == A2 -> {value,true,St}; eq_op(_Op, A1, A2, St) when ?IS_TREF(A1), ?IS_TREF(A2) ; ?IS_USDREF(A1), ?IS_USDREF(A2) -> case get_eqmetamethod(A1, A2, St) of nil -> {value,false,St}; Meth -> Func = fun (Args, St0) -> {Ret,St1} = functioncall(Meth, Args, St0), {[boolean_value(Ret)],St1} end, {meta,#erl_func{code=Func},[A1,A2],St} end; eq_op(_, _, _, St) -> {value,false,St}. neq_op(_Op, A1, A2, St) when A1 == A2 -> {value,false,St}; neq_op(_Op, A1, A2, St) when ?IS_TREF(A1), ?IS_TREF(A2) ; ?IS_USDREF(A1), ?IS_USDREF(A2) -> case get_eqmetamethod(A1, A2, St) of nil -> {value,true,St}; Meth -> Func = fun (Args, St0) -> {Ret,St1} = functioncall(Meth, Args, St0), {[not boolean_value(Ret)],St1} end, {meta,#erl_func{code=Func},[A1,A2],St} end; neq_op(_, _, _, St) -> {value,true,St}. get_eqmetamethod(A1, A2, St) -> %% Must have "same" metamethod here. How do we test? case luerl_heap:get_metamethod(A1, <<"__eq">>, St) of nil -> nil; Meth -> case luerl_heap:get_metamethod(A2, <<"__eq">>, St) of Meth -> Meth; %Must be the same method _ -> nil end end. lt_op(_Op, A1, A2, St) when is_number(A1), is_number(A2) -> {value,A1 < A2,St}; lt_op(_Op, A1, A2, St) when is_binary(A1), is_binary(A2) -> {value,A1 < A2,St}; lt_op(Op, A1, A2, St) -> op_meta(Op, A1, A2, <<"__lt">>, St). le_op(_Op, A1, A2, St) when is_number(A1), is_number(A2) -> {value,A1 =< A2,St}; le_op(_Op, A1, A2, St) when is_binary(A1), is_binary(A2) -> {value,A1 =< A2,St}; le_op(Op, A1, A2, St) -> %% Must check for first __le then __lt metamethods. case luerl_heap:get_metamethod(A1, A2, <<"__le">>, St) of nil -> %% Try for not (Op2 < Op1) instead. case luerl_heap:get_metamethod(A1, A2, <<"__lt">>, St) of nil -> {error,{badarg,Op,[A1,A2]}, St}; Meth -> {meta,Meth,[A2,A1],St} end; Meth -> {meta,Meth,[A1,A2],St} end. concat_op(A1, A2, St) -> case luerl_lib:conv_list([A1,A2], [lua_string,lua_string]) of [S1,S2] -> {value,<>,St}; error -> op_meta('..', A1, A2, <<"__concat">>, St) end. %% op_meta(Op, A, E, St) -> %% case luerl_heap:get_metamethod(A, E, St) of %% nil -> {error,{badarg,Op,[A]}, St}; %% Meth -> {meta,Meth,[A],St} %% end. op_meta(Op, A1, A2, E, St) -> case luerl_heap:get_metamethod(A1, A2, E, St) of nil -> {error,{badarg,Op,[A1,A2]},St}; Meth -> {meta,Meth,[A1,A2],St} end. %% boolean_value(Rets) -> boolean(). %% Return the "boolean" value of a value/function return list. boolean_value([nil|_]) -> false; boolean_value([false|_]) -> false; boolean_value([_|_]) -> true; boolean_value([]) -> false; boolean_value(nil) -> false; boolean_value(false) -> false; boolean_value(_) -> true. %% first_value(Rets) -> Value. %% multiple_value(Value) -> [Value]. first_value([V|_]) -> V; first_value([]) -> nil. multiple_value(V) when not is_list(V) -> [V]. luerl-1.2.3/src/luerl_lib_utf8.erl0000664000175000017500000001147314677012037017447 0ustar debalancedebalance%% Copyright (c) 2013-2020 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_lib_utf8.erl %% Author : Robert Virding %% Purpose : The utf8 library for Luerl. -module(luerl_lib_utf8). -include("luerl.hrl"). -export([install/1,utf8_char/3,codes/3,codepoint/3,utf8_len/3,offset/3]). -import(luerl_lib, [lua_error/2,badarg_error/3]). %Shorten these install(St) -> luerl_heap:alloc_table(table(), St). table() -> [{<<"char">>,#erl_mfa{m=?MODULE,f=utf8_char}}, {<<"charpattern">>,<<"[\0-\x7F\xC2-\xF4][\x80-\xBF]*">>}, {<<"codes">>,#erl_mfa{m=?MODULE,f=codes}}, {<<"codepoint">>,#erl_mfa{m=?MODULE,f=codepoint}}, {<<"len">>,#erl_mfa{m=?MODULE,f=utf8_len}}, {<<"offset">>,#erl_mfa{m=?MODULE,f=offset}} ]. %% char(...) -> String. %% Receives zero or more integers, converts each one to its %% corresponding UTF-8 byte sequence and returns a string with the %% concatenation of all these sequences. utf8_char(_, As, St) -> case luerl_lib:args_to_integers(As) of Is when is_list(Is) -> Ss = << <> || I <- Is >>, {[Ss],St}; error -> badarg_error(char, As, St) end. %% len(...) -> Integer. %% Returns the number of UTF-8 characters in string s that start %% between positions i and j (both inclusive). The default for i is 1 %% and for j is -1. If it finds any invalid byte sequence, returns a %% false value plus the position of the first invalid byte. utf8_len(_, As, St) -> {Str,I,J} = string_args(As, len, St), StrLen = byte_size(Str), Ret = if I > J -> [0]; %Do the same as Lua true -> Bin = binary_part(Str, I - 1, StrLen - I + 1), case bin_len(Bin, StrLen - J, 0) of {ok,Size} -> [Size]; {error,Rest} -> [nil,StrLen - byte_size(Rest) + 1] end end, {Ret,St}. bin_len(Bin, Last, N) when byte_size(Bin) =< Last -> {ok,N}; bin_len(Bin0, Last, N) -> try <<_/utf8,Bin1/binary>> = Bin0, bin_len(Bin1, Last, N+1) catch _:_ -> {error,Bin0} end. %% codepoint(...) -> [Integer]. %% Returns the codepoints (as integers) from all characters in s that %% start between byte position i and j (both included). The default %% for i is 1 and for j is i. It raises an error if it meets any %% invalid byte sequence. codepoint(_, As, St) -> {Str,I,J} = string_args(As, codepoint, St), StrLen = byte_size(Str), Ret = if I > J -> []; %Do the same as Lua true -> Bin = binary_part(Str, I - 1, StrLen - I + 1), case bin_codepoint(Bin, StrLen - J, []) of {ok,Cps} -> Cps; {error,_} -> badarg_error(codepoint, As, St) end end, {Ret,St}. bin_codepoint(Bin, Last, Cps) when byte_size(Bin) =< Last -> {ok,lists:reverse(Cps)}; bin_codepoint(Bin0, Last, Cps) -> try <> = Bin0, bin_codepoint(Bin1, Last, [C|Cps]) catch _:_ -> {error,Bin0} end. %% codes(String) -> [Fun,String,P]. codes(_, As, St) -> case luerl_lib:conv_list(As, [lua_string]) of error -> badarg_error(codes, As, St); [Str|_] -> {[#erl_func{code=fun codes_next/2},Str,0],St} end. codes_next([A], St) -> codes_next([A,0], St); codes_next([Str,P|_], St) when byte_size(Str) =< P -> {[nil],St}; codes_next([Str,P|_], St) when is_binary(Str) -> <<_:P/binary,C/utf8,Rest/binary>> = Str, P1 = byte_size(Str) - byte_size(Rest), {[P1,C],St}. %% offset(String, N, ...) -> Integer. -spec offset(_, [_], any()) -> no_return(). offset(_, As, St) -> _ = string_args(As, offset, St), %% We don't do anything yet. lua_error({'NYI',offset}, St). %% string_args(Args, Op, St) -> {String,I,J}. %% Return the string, i and j values from the arguments. Generate a %% badarg error on bad values. string_args(As, Op, St) -> %% Get the args. Args = luerl_lib:conv_list(As, [lua_string,lua_integer,lua_integer]), case Args of %Cunning here, export A1,A2,A3 [A1,A2,A3|_] -> ok; [A1,A2] -> A3 = byte_size(A1); [A1] -> A2 = 1, A3 = byte_size(A1); error -> A1 = A2 = A3 = ok, badarg_error(Op, As, St) end, StrLen = byte_size(A1), %% Check args and return Str, I, J. Str = A1, I = if A2 > 0, A2 =< StrLen -> A2; A2 < 0, A2 >= -StrLen -> StrLen + A2 + 1; true -> badarg_error(Op, As, St) end, J = if A3 > 0, A3 =< StrLen -> A3; A3 < 0, A3 >= -StrLen -> StrLen + A3 + 1; true -> badarg_error(Op, As, St) end, {Str,I,J}. luerl-1.2.3/src/luerl_util.erl0000664000175000017500000001100214677012037016674 0ustar debalancedebalance%% Copyright (c) 2019 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_util.erl %% Purpose : Utility functions for Luer. -module(luerl_util). -export([errname_info/1]). %% Convert error names to errnos and strings. errname_info(Name) -> #{errno => get_errno(Name), errstr => erl_posix_msg:message(Name)}. %% Made using the following command (`errno' from the moreutils package): %% `errno -l | sort -k2 -n | awk '{print "get_errno("tolower($1)") -> "$2";"}'' get_errno(eperm) -> 1; get_errno(enoent) -> 2; get_errno(esrch) -> 3; get_errno(eintr) -> 4; get_errno(eio) -> 5; get_errno(enxio) -> 6; get_errno(e2big) -> 7; get_errno(enoexec) -> 8; get_errno(ebadf) -> 9; get_errno(echild) -> 10; get_errno(eagain) -> 11; get_errno(ewouldblock) -> 11; get_errno(enomem) -> 12; get_errno(eacces) -> 13; get_errno(efault) -> 14; get_errno(enotblk) -> 15; get_errno(ebusy) -> 16; get_errno(eexist) -> 17; get_errno(exdev) -> 18; get_errno(enodev) -> 19; get_errno(enotdir) -> 20; get_errno(eisdir) -> 21; get_errno(einval) -> 22; get_errno(enfile) -> 23; get_errno(emfile) -> 24; get_errno(enotty) -> 25; get_errno(etxtbsy) -> 26; get_errno(efbig) -> 27; get_errno(enospc) -> 28; get_errno(espipe) -> 29; get_errno(erofs) -> 30; get_errno(emlink) -> 31; get_errno(epipe) -> 32; get_errno(edom) -> 33; get_errno(erange) -> 34; get_errno(edeadlk) -> 35; get_errno(edeadlock) -> 35; get_errno(enametoolong) -> 36; get_errno(enolck) -> 37; get_errno(enosys) -> 38; get_errno(enotempty) -> 39; get_errno(eloop) -> 40; get_errno(enomsg) -> 42; get_errno(eidrm) -> 43; get_errno(echrng) -> 44; get_errno(el2nsync) -> 45; get_errno(el3hlt) -> 46; get_errno(el3rst) -> 47; get_errno(elnrng) -> 48; get_errno(eunatch) -> 49; get_errno(enocsi) -> 50; get_errno(el2hlt) -> 51; get_errno(ebade) -> 52; get_errno(ebadr) -> 53; get_errno(exfull) -> 54; get_errno(enoano) -> 55; get_errno(ebadrqc) -> 56; get_errno(ebadslt) -> 57; get_errno(ebfont) -> 59; get_errno(enostr) -> 60; get_errno(enodata) -> 61; get_errno(etime) -> 62; get_errno(enosr) -> 63; get_errno(enonet) -> 64; get_errno(enopkg) -> 65; get_errno(eremote) -> 66; get_errno(enolink) -> 67; get_errno(eadv) -> 68; get_errno(esrmnt) -> 69; get_errno(ecomm) -> 70; get_errno(eproto) -> 71; get_errno(emultihop) -> 72; get_errno(edotdot) -> 73; get_errno(ebadmsg) -> 74; get_errno(eoverflow) -> 75; get_errno(enotuniq) -> 76; get_errno(ebadfd) -> 77; get_errno(eremchg) -> 78; get_errno(elibacc) -> 79; get_errno(elibbad) -> 80; get_errno(elibscn) -> 81; get_errno(elibmax) -> 82; get_errno(elibexec) -> 83; get_errno(eilseq) -> 84; get_errno(erestart) -> 85; get_errno(estrpipe) -> 86; get_errno(eusers) -> 87; get_errno(enotsock) -> 88; get_errno(edestaddrreq) -> 89; get_errno(emsgsize) -> 90; get_errno(eprototype) -> 91; get_errno(enoprotoopt) -> 92; get_errno(eprotonosupport) -> 93; get_errno(esocktnosupport) -> 94; get_errno(enotsup) -> 95; get_errno(eopnotsupp) -> 95; get_errno(epfnosupport) -> 96; get_errno(eafnosupport) -> 97; get_errno(eaddrinuse) -> 98; get_errno(eaddrnotavail) -> 99; get_errno(enetdown) -> 100; get_errno(enetunreach) -> 101; get_errno(enetreset) -> 102; get_errno(econnaborted) -> 103; get_errno(econnreset) -> 104; get_errno(enobufs) -> 105; get_errno(eisconn) -> 106; get_errno(enotconn) -> 107; get_errno(eshutdown) -> 108; get_errno(etoomanyrefs) -> 109; get_errno(etimedout) -> 110; get_errno(econnrefused) -> 111; get_errno(ehostdown) -> 112; get_errno(ehostunreach) -> 113; get_errno(ealready) -> 114; get_errno(einprogress) -> 115; get_errno(estale) -> 116; get_errno(euclean) -> 117; get_errno(enotnam) -> 118; get_errno(enavail) -> 119; get_errno(eisnam) -> 120; get_errno(eremoteio) -> 121; get_errno(edquot) -> 122; get_errno(enomedium) -> 123; get_errno(emediumtype) -> 124; get_errno(ecanceled) -> 125; get_errno(enokey) -> 126; get_errno(ekeyexpired) -> 127; get_errno(ekeyrevoked) -> 128; get_errno(ekeyrejected) -> 129; get_errno(eownerdead) -> 130; get_errno(enotrecoverable) -> 131; get_errno(erfkill) -> 132; get_errno(ehwpoison) -> 133; get_errno(_) -> 0. luerl-1.2.3/src/NOTES0000664000175000017500000001335514677012037014640 0ustar debalancedebalance Copyright (c) 2013 Robert Virding Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Implementation Notes -------------------- Syntax ------ We are almost able to represent the Lua syntax as an LALR(1) grammar. The only place this doesn't work is when a statement can be a function call as it clashes when it can also be a varlist. We get around this by using the more general prefixexp and doing a post-test to check that it is a functioncall. This works together with the varlist. Data ---- For the Lua data types we internally use the corresponding Erlang: nil - nil true/false - true/false strings - binaries numbers - floats tables - #table{} with array for keys 1..n, ordict for rest userdata - #userdata{} function - #function{} or {function,Fun} thread - #thread{} See luerl.hrl for the field names of the records. All tables are combinations of ttdicts and arrays. In each table an array is used for integer keys >= 1 while an ttdict is used for all other keys. We use this information when building/processing tables. Seems like Lua internally stores elements as a (unordered) sequence of key-value elements, except maybe for the table part. Some tests show that using ttdicts for all elements results the system being 10-20% slower and using more memory. So using the array module for positive integer keys seems a reasonable choice. Direct read/write access is fast, but "shifting" access for example in table.insert/remove is not that efficient. Most table functions work after a fashion even in the "undefined" case all the elements don't have keys only in 1..n, but it seems like the order in which elements were added affects the outcome. We don't have any such information available. We do try to do something reasonable that sort of mirrors the Lua functions. Should we or should we be strict? The table table can be either an ordict, an array, use the process dictionary, or an ETS table; these are accessed through macros. To use ETS would need a bigger change as copying the whole table for each access would be very inefficient. Either use bags and have one per table or use sets and have the ETS key as {Tab,Key}. Machine ------- The VM is a hybrid. It uses normal Erlang function calls for Luerl calls and blocks and has a small instruction set for operations inside a block. This should make it not too difficult to compile down to straight Erlang in the future. Blocks keep variables in tuples. There are two variable types depending on how they are defined: - Local variables that are used in this block and sub-blocks, but not used in any functions defined in the blocks. These are kept in a stack of tuples, the LocalVars or Lvs, and referenced by offset in stack and offset in tuple. - Environment variables that are defined in functions which are defined in this block or in sub-blocks. This mean they must be kept around as long as the functions are alive and are stored in the global heap as each invocation can modify them. They are kept in a stack of references, the EnvironmentVars or Evs, to tuples in the global heap and referenced by offset in stack and offset in tuple. A function contains a reference to the stack of environment variables which existed when it was created. Note that the mutable nature of Lua data means that these can be modified and the changes must be visible to every function which references them. There is also a stack containing arguments and temporary values. This is stack is "global" in the sense that it is passed through all calls and blocks. It is also passed as an argument into functions implemented in Erlang. This is so that event of a Lua/Luerl GC the collector uses the stack to determine which data in the global heap is to be saved. The VM is a pure stack machine. To handle multiple return values we always return a list of values. The only place this is not done is in luerl_eval.erl when getting values from the environment where we can only have one value. This means a lot of calls to first_value/1 in luerl_emul.erl, but the consistency is worth it. Similarly all the arguments in a function call are passed in a list. The function then unpacks the list into its arguments, including '...'. All of the predefined libraries have an install/1 function. This is called when initialising Luerl; it does any library specific initialisation necessary and returns a table containing the functions in the library. We create a unique tag which is saved in the environment. This is used so we can implement 'break' with a simple throw. The thrown value includes the tag so we can uniquely catch it and not get confused with a throw/error/exit from the erlang code. Compiler -------- The compiler has state at different levels: - In luerl_comp there is #comp{} containing code, options and errors. - In the #cst{} between the compiler modules for data outside the code. This empty so far. - Inside and local to the compiler modules. All the compiler modules are written so that they chain a status argument through their code, even if it not used. When they are not used we just send the atom 'nil' through and check it comes out "the other end". Lua implementation "features" ----------------------------- When "integers" are wanted then float input values are often "rounded" to the correct float value. So 1.3 --> 1.0 and 3.7 --> 4.0. luerl-1.2.3/src/luerl_instrs.hrl0000664000175000017500000000602014677012037017250 0ustar debalancedebalance%% Copyright (c) 2019 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_instrs.hrl %% Author : Robert Virding %% Purpose : Internal LUA 5.3 instructions. %% Expression instructions. -define(PUSH_LIT(L), {push_lit,L}). -define(PUSH_LVAR(D,I), {push_lvar,D,I}). -define(PUSH_EVAR(D, I), {push_evar,D,I}). -define(PUSH_GVAR(K), {push_gvar,K}). -define(PUSH_LAST_LIT(L), {push_last_lit,L}). %[?PUSH_LIT,?MULTIPLE] -define(PUSH_LAST_LVAR(D,I), {push_last_lvar,D,I}). -define(PUSH_LAST_EVAR(D, I), {push_last_evar,D,I}). -define(PUSH_LAST_GVAR(K), {push_last_gvar,K}). -define(STORE_LVAR(D, I), {store_lvar,D,I}). -define(STORE_EVAR(D, I), {store_evar,D,I}). -define(STORE_GVAR(K), {store_gvar,K}). -define(GET_KEY, get_key). %Acc = Stk[Acc] -define(GET_LIT_KEY(K), {get_lit_key,K}). %[?PUSH_LIT(K),?GET_KEY] -define(SET_KEY, set_key). %Stk[ -define(SET_LIT_KEY(K), {set_lit_key,K}). %[?PUSH_LIT(K),?SET_KEY] -define(SINGLE, single). %Ensure single value -define(MULTIPLE, multiple). %Ensure multiple value -define(BUILD_TAB(Fc, I), {build_tab,Fc,I}). -define(FCALL, fcall). -define(TAIL_FCALL, tail_fcall). -define(MCALL(M), {mcall,M}). -define(TAIL_MCALL(M), {tail_mcall,M}). -define(OP(Op,Ac), {op,Op,Ac}). -define(PUSH_FDEF(Anno, Lsz, Esz, Pars, Is), {push_fdef,Anno,Lsz,Esz,Pars,Is}). -define(PUSH_FDEF(FnRef), {push_fdef,FnRef}). %% Control instructions. -define(BLOCK(Lsz, Esz, Is), {block,Lsz,Esz,Is}). -define(BLOCK_OPEN(Lsz, Esz), {block_open,Lsz,Esz}). -define(BLOCK_CLOSE, block_close). -define(WHILE(E, B), {while,E,B}). -define(WHILE_LOOP(Eis, Wis), {while_loop,Eis,Wis}). -define(REPEAT(B), {repeat,B}). -define(REPEAT_LOOP(B), {repeat_loop,B}). -define(AND_THEN(T), {and_then,T}). -define(OR_ELSE(T), {or_else,T}). -define(IF_TRUE(T), {if_true,T}). -define(IF(T, F), {'if',T,F}). -define(NFOR(V, B), {nfor,V,B}). -define(NFOR_LOOP(N, Limit, Step, Fis), {nfor_loop,N,Limit,Step,Fis}). -define(GFOR(Vs, B), {gfor,Vs,B}). -define(GFOR_CALL(Func, Data, Val, Fis), {gfor_call,Func,Data,Val,Fis}). -define(GFOR_LOOP(Func, Data, Fis), {gfor_loop,Func,Data,Fis}). -define(BREAK, break). -define(RETURN(Ac), {return,Ac}). %% Stack instructions. -define(PUSH, push). -define(POP, pop). -define(POP2, pop2). -define(SWAP, swap). -define(DUP, dup). -define(PUSH_VALS(Vc), {push_vals,Vc}). -define(POP_VALS(Vc), {pop_vals,Vc}). -define(POP_ARGS(Ac), {pop_args,Ac}). -define(PUSH_ARGS(Al), {push_args,Al}). %% Comment and line instructions. -define(COMMENT(C), {comment,C}). -define(CURRENT_LINE(L, File), {current_line,L,File}). luerl-1.2.3/src/luerl_comp_env.erl0000664000175000017500000002777314677012037017553 0ustar debalancedebalance%% Copyright (c) 2013 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_comp_env.erl %% Author : Robert Virding %% Purpose : A basic LUA 5.3 compiler for Luerl. %% Does variable and stack analysis in the compiler -module(luerl_comp_env). -include("luerl.hrl"). -include("luerl_comp.hrl"). -export([chunk/2]). -import(ordsets, [is_element/2,intersection/2,subtract/2]). %% Local state. -record(c_env, {lfs=[], %Variable frames efs=[], %Environment frames vars=none, fs=[], locv=false, %Local variables locf %Local frame }). %% chunk(Code, CompInfo) -> {ok,Code}. chunk(Code0, #cinfo{opts=Opts}=_Ci) -> St0 = #c_env{}, %Local state {Code1,_} = functiondef(Code0, St0), luerl_comp:debug_print(Opts, "ce: ~p\n", [Code1]), {ok,Code1}. %% alloc_frame(State) -> State. %% pop_frame(State) -> State. %% get_frame(State) -> Frame. alloc_frame(#c_env{vars=#vars{},fs=Fs}=St) -> F = new_frame(), St#c_env{fs=[F|Fs]}. pop_frame(#c_env{fs=[_|Fs]}=St) -> St#c_env{fs=Fs}. get_frame(#c_env{fs=[F|_]}) -> F. %% new_frame(LocalSize, EnvSize) -> Frame. %% We know frame will be tuples which we index from 1. Also Lua has %% the feature that every time you add a local variable you get a new %% version of it which shadows the old one. We handle this by keeping %% them in reverse order and always pushing variable to front of %% list. %% %% We get the size from the index of the last variable of each type added. %% %% NOTE: We can have empty frames here. The emulator knows about this %% and can handle it. %% %% Frame :: {LocalIndex,EnvIndex,Vars} %% Var :: {Name,Type,Index} new_frame() -> {0,0,[]}. find_frame_var(N, {_,_,Fs}) -> find_frame_var_1(N, Fs). find_frame_var_1(N, [{N,Type,I}|_]) -> {yes,Type,I}; find_frame_var_1(N, [_|F]) -> find_frame_var_1(N, F); find_frame_var_1(_, []) -> no. frame_local_size({Li,_,_}) -> Li. frame_env_size({_,Ei,_}) -> Ei. add_frame_local_var(N, {Li,Ei,Fs}) -> {Li+1,Ei,[{N,lvar,Li+1}|Fs]}. add_frame_env_var(N, {Li,Ei,Fs}) -> {Li,Ei+1,[{N,evar,Ei+1}|Fs]}. %% find_fs_var(Name, FrameStack) -> {yes,Type,Depth,Index} | no. %% Find a variable in the frame stack returning its depth and %% index. find_fs_var(N, Fs) -> find_fs_var(N, Fs, 1, 1). find_fs_var(N, [F|Fs], Ld, Ed) -> case find_frame_var(N, F) of {yes,lvar,Li} -> {yes,lvar,Ld,Li}; {yes,evar,Ei} -> {yes,evar,Ed,Ei}; no -> Ld1 = Ld + 1, Ed1 = Ed + 1, find_fs_var(N, Fs, Ld1, Ed1) end; find_fs_var(_, [], _, _) -> no. %% add_var(Var, State) -> State. %% get_var(Var, State) -> #lvar{} | #evar{} | #gvar{}. add_var(#var{name=N}, St) -> case var_type(N, St) of local -> add_local_var(N, St); env -> add_env_var(N, St) end. add_env_var(V, #c_env{fs=[F0|Fs]}=St) -> F1 = add_frame_env_var(V, F0), St#c_env{fs=[F1|Fs]}. add_local_var(N, #c_env{fs=[F0|Fs]}=St) -> F1 = add_frame_local_var(N, F0), St#c_env{fs=[F1|Fs]}. get_var(#var{l=Line,name=N}, #c_env{fs=Fs}) -> case find_fs_var(N, Fs) of {yes,lvar,Ld,Li} -> #lvar{l=Line,n=N,d=Ld,i=Li}; {yes,evar,Ed,Ei} -> #evar{l=Line,n=N,d=Ed,i=Ei}; no -> #gvar{l=Line,n=N} end. var_type(N, #c_env{vars=#vars{fused=Fused}}) -> case is_element(N, Fused) of true -> env; false -> local end. %% stmt(Stmts, State) -> {Stmts,State}. stmts([S0|Ss0], St0) -> {S1,St1} = stmt(S0, nul, St0), %% io:format("ss1: ~p\n", [{Loc0,Free0,Used0}]), {Ss1,St2} = stmts(Ss0, St1), {[S1|Ss1],St2}; stmts([], St) -> {[],St}. %% stmt(Stmt, State) -> {Stmt,State}. stmt(#assign_stmt{}=A, _, St) -> assign_stmt(A, St); stmt(#call_stmt{}=C, _, St) -> call_stmt(C, St); stmt(#return_stmt{}=R, _, St) -> return_stmt(R, St); stmt(#break_stmt{}=B, _, St) -> {B,St}; stmt(#block_stmt{}=B, _, St) -> block_stmt(B, St); stmt(#while_stmt{}=W, _, St) -> while_stmt(W, St); stmt(#repeat_stmt{}=R, _, St) -> repeat_stmt(R, St); stmt(#if_stmt{}=I, _, St) -> if_stmt(I, St); stmt(#nfor_stmt{}=F, _, St) -> numfor_stmt(F, St); stmt(#gfor_stmt{}=F, _, St) -> genfor_stmt(F, St); stmt(#local_assign_stmt{}=L, _, St) -> local_assign_stmt(L, St); stmt(#local_fdef_stmt{}=L, _, St) -> local_fdef_stmt(L, St); stmt(#expr_stmt{}=E, _, St) -> expr_stmt(E, St). %% assign_stmt(Assign, State) -> {Assign,State}. assign_stmt(#assign_stmt{vars=Vs0,exps=Es0}=A, St0) -> {Vs1,St1} = assign_loop(Vs0, St0), {Es1,St2} = explist(Es0, St1), {A#assign_stmt{vars=Vs1,exps=Es1},St2}. assign_loop([V0|Vs0], St0) -> {V1,St1} = var(V0, St0), {Vs1,St2} = assign_loop(Vs0, St1), {[V1|Vs1],St2}; assign_loop([], St) -> {[],St}. var(#dot{exp=Exp0,rest=Rest0}=D, St0) -> {Exp1,St1} = prefixexp_first(Exp0, St0), {Rest1,St2} = var_rest(Rest0, St1), {D#dot{exp=Exp1,rest=Rest1},St2}; var(#var{}=V0, St) -> V1 = get_var(V0, St), {V1,St}. var_rest(#dot{exp=Exp0,rest=Rest0}=D, St0) -> {Exp1,St1} = prefixexp_element(Exp0, St0), {Rest1,St2} = var_rest(Rest0, St1), {D#dot{exp=Exp1,rest=Rest1},St2}; var_rest(Exp, St) -> var_last(Exp, St). var_last(#key{key=Exp0}=K, St0) -> {Exp1,St1} = exp(Exp0, St0), {K#key{key=Exp1},St1}. %% call_stmt(Call, State) -> {Call,State}. call_stmt(#call_stmt{call=Exp0}=C, St0) -> {Exp1,St1} = exp(Exp0, St0), {C#call_stmt{call=Exp1},St1}. %% return_stmt(Return, State) -> {Return,State}. return_stmt(#return_stmt{exps=Es0}=R, St0) -> {Es1,St1} = explist(Es0, St0), {R#return_stmt{exps=Es1},St1}. %% block_stmt(Block, State) -> {Block,State}. block_stmt(#block_stmt{body=Ss0,vars=Vars}=B, St0) -> Do = fun(S) -> stmts(Ss0, S) end, {Ss1,Fr,St1} = with_block(Do, Vars, St0), Lsz = frame_local_size(Fr), Esz = frame_env_size(Fr), {B#block_stmt{body=Ss1,lsz=Lsz,esz=Esz},St1}. %% do_block(Block, State) -> {Block,State}. do_block(#block{body=Ss0,vars=Vars}=B, St0) -> Do = fun(S) -> stmts(Ss0, S) end, {Ss1,Fr,St1} = with_block(Do, Vars, St0), Lsz = frame_local_size(Fr), Esz = frame_env_size(Fr), {B#block{body=Ss1,lsz=Lsz,esz=Esz},St1}. %% with_block(Do, Vars, State) -> {Ret,State}. %% with_block(Do, Env, Vars, State) -> {Ret,State}. %% Do a block initialising/clearing frames. We always push a local %% frame even if it not used. with_block(Do, Vars, #c_env{vars=OldVars}=St0) -> St1 = alloc_frame(St0#c_env{vars=Vars}), {Ret,St2} = Do(St1), Fr = get_frame(St2), St3 = pop_frame(St2), {Ret,Fr,St3#c_env{vars=OldVars}}. %% while_stmt(While, State) -> {While,State}. while_stmt(#while_stmt{exp=E0,body=B0}=W, St0) -> {E1,St1} = exp(E0, St0), {B1,St2} = do_block(B0, St1), {W#while_stmt{exp=E1,body=B1},St2}. %% repeat_stmt(Repeat, State) -> {Repeat,State}. repeat_stmt(#repeat_stmt{body=B0}=R, St0) -> {B1,St1} = do_block(B0, St0), {R#repeat_stmt{body=B1},St1}. %% if_stmt(If, State) -> {If,State}. if_stmt(#if_stmt{tests=Ts0,else_block=E0}=I, St0) -> {Ts1,St1} = if_tests(Ts0, St0), {E1,St2} = do_block(E0, St1), {I#if_stmt{tests=Ts1,else_block=E1},St2}. if_tests([{E0,B0}|Ts0], St0) -> {E1,St1} = exp(E0, St0), {B1,St2} = do_block(B0, St1), {Ts1,St3} = if_tests(Ts0, St2), {[{E1,B1}|Ts1],St3}; if_tests([], St) -> {[],St}. %% numfor_stmt(For, State) -> {For,State}. numfor_stmt(#nfor_stmt{var=V0,init=I0,limit=L0,step=S0,body=B0}=F, St0) -> {[I1,L1,S1],St1} = explist([I0,L0,S0], St0), {[V1],B1,St2} = for_block([V0], B0, St1), {F#nfor_stmt{var=V1,init=I1,limit=L1,step=S1,body=B1},St2}. %% genfor_stmt(For, State) -> {For,State}. genfor_stmt(#gfor_stmt{vars=Vs0,gens=Gs0,body=B0}=F, St0) -> {Gs1,St1} = explist(Gs0, St0), {Vs1,B1,St2} = for_block(Vs0, B0, St1), {F#gfor_stmt{vars=Vs1,gens=Gs1,body=B1},St2}. for_block(Vs0, #block{body=Ss0,vars=Vars}=B, St0) -> Do = fun (S0) -> Fun = fun (V, Sa) -> Sb = add_var(V, Sa), {get_var(V, Sb),Sb} end, {Vs1,S1} = lists:mapfoldl(Fun, S0, Vs0), {Ss1,S2} = stmts(Ss0, S1), {{Vs1,Ss1},S2} end, {{Vs1,Ss1},Fr,St1} = with_block(Do, Vars, St0), Lsz = frame_local_size(Fr), Esz = frame_env_size(Fr), {Vs1,B#block{body=Ss1,lsz=Lsz,esz=Esz},St1}. %% local_assign_stmt(Local, State) -> {Local,State}. local_assign_stmt(#local_assign_stmt{vars=Vs0,exps=Es0}=L, St0) -> %% io:fwrite("las: ~p\n", [{Es0,St0}]), {Es1,St1} = explist(Es0, St0), %% io:fwrite("las> ~p\n", [{Es1,St1}]), AddVar = fun (V, S0) -> S1 = add_var(V, S0), {get_var(V, S1),S1} end, {Vs1,St2} = lists:mapfoldl(AddVar, St1, Vs0), %% io:fwrite("las> ~p\n", [{Vs1,St2}]), {L#local_assign_stmt{vars=Vs1,exps=Es1},St2}. %% local_fdef_stmt(Local, State) -> {Local,State}. %% Add function name first in case of recursive call. local_fdef_stmt(#local_fdef_stmt{var=V,func=F0}=L, St0) -> St1 = add_var(V, St0), {F1,St2} = functiondef(F0, St1), V1 = get_var(V, St2), %% io:fwrite("lf: ~p\n", [St0]), %% io:fwrite("lf: ~p\n", [St1]), %% io:fwrite("lf: ~p\n", [St2]), {L#local_fdef_stmt{var=V1,func=F1},St2}. %% expr_stmt(Expr, State) -> {Call,State}. %% The expression pseudo statement. This will return a single value. expr_stmt(#expr_stmt{exp=Exp0}=E, St0) -> {Exp1,St1} = exp(Exp0, St0), {E#expr_stmt{exp=Exp1},St1}. %% explist(Exprs, State) -> {Exprs,State}. %% exp(Expr, State) -> {Expr,State}. %% prefixexp(Expr, State) -> {Expr,State}. explist([E0|Es0], St0) -> {E1,St1} = exp(E0, St0), {Es1,St2} = explist(Es0, St1), {[E1|Es1],St2}; explist([], St) -> {[],St}. %No expressions at all exp(#lit{}=L, St) -> {L,St}; %Nothing to do exp(#fdef{}=F, St) -> functiondef(F, St); exp(#op{args=Es0}=Op, St0) -> {Es1,St1} = explist(Es0, St0), {Op#op{args=Es1},St1}; exp(#tabcon{fields=Fs0}=T, St0) -> {Fs1,St1} = tableconstructor(Fs0, St0), {T#tabcon{fields=Fs1},St1}; exp(E, St) -> prefixexp(E, St). prefixexp(#dot{exp=Exp0,rest=Rest0}=D, St0) -> {Exp1,St1} = prefixexp_first(Exp0, St0), {Rest1,St2} = prefixexp_rest(Rest0, St1), {D#dot{exp=Exp1,rest=Rest1},St2}; prefixexp(Exp, St) -> prefixexp_first(Exp, St). prefixexp_first(#single{exp=E0}=S, St0) -> {E1,St1} = exp(E0, St0), {S#single{exp=E1},St1}; prefixexp_first(#var{}=V0, St) -> V1 = get_var(V0, St), {V1,St}. prefixexp_rest(#dot{exp=Exp0,rest=Rest0}=D, St0) -> {Exp1,St1} = prefixexp_element(Exp0, St0), {Rest1,St2} = prefixexp_rest(Rest0, St1), {D#dot{exp=Exp1,rest=Rest1},St2}; prefixexp_rest(Exp, St) -> prefixexp_element(Exp, St). prefixexp_element(#key{key=E0}=K, St0) -> {E1,St1} = exp(E0, St0), {K#key{key=E1},St1}; prefixexp_element(#fcall{args=As0}=F, St0) -> {As1,St1} = explist(As0, St0), {F#fcall{args=As1},St1}; prefixexp_element(#mcall{args=As0}=M, St0) -> {As1,St1} = explist(As0, St0), {M#mcall{args=As1},St1}. %% functiondef(Func, State) -> {Func,State}. functiondef(#fdef{pars=Ps0,body=Ss0,vars=Vars}=F, St0) -> Do = fun (S0) -> Fun = fun (V, Sa) -> Sb = add_var(V, Sa), {get_var(V, Sb),Sb} end, {Ps1,S1} = lists:mapfoldl(Fun, S0, Ps0), {Ss1,S2} = stmts(Ss0, S1), {{Ps1,Ss1},S2} end, {{Ps1,Ss1},Fr,St1} = with_block(Do, Vars, St0), Lsz = frame_local_size(Fr), Esz = frame_env_size(Fr), {F#fdef{pars=Ps1,body=Ss1,lsz=Lsz,esz=Esz},St1}. %% tableconstructor(Fields, State) -> {Fields,State}. tableconstructor(Fs0, St0) -> Fun = fun (#efield{val=V0}=F, S0) -> {V1,S1} = exp(V0, S0), {F#efield{val=V1},S1}; (#kfield{key=K0,val=V0}=F, S0) -> {K1,S1} = exp(K0, S0), {V1,S2} = exp(V0, S1), {F#kfield{key=K1,val=V1},S2} end, {Fs1,St1} = lists:mapfoldl(Fun, St0, Fs0), {Fs1,St1}. luerl-1.2.3/src/luerl_anno.erl0000664000175000017500000000502214677012037016657 0ustar debalancedebalance%% Copyright (c) 2019 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_anno.erl %% Author : Robert Virding %% Purpose : Handle annotations in the Luerl abstract code. %% We keep the same standard as in the Erlang AST: %% %% - annotations with just the line number can be just the integer. %% - in an aonnotation list the line number is just an integer while %% all other annotations have the format {Key,Value}. -module(luerl_anno). -export([new/0,new/1,new/2,set_line/2,line/1,set/3,get/2]). %% new() -> Anno. %% new(Line) -> Anno. %% new(Key, Val) -> Anno. %% Create an empty annotation, one containing Line and one containing %% a general Key/Val. new() -> []. new(Line) -> Line. new(Key, Val) -> set(Key, Val, new()). %% set_line(Line, Anno) -> Anno. %% line(Anno) -> Line | undefined. %% Specific functions for accessing line numbers in the anno. set_line(Line, Anno) when is_integer(Anno) -> Line; set_line(Line, Anno) -> set_line1(Line, Anno). set_line1(Line, [Old|Anno]) when is_integer(Old) -> [Line|Anno]; set_line1(Line, [A|Anno]) -> [A|set_line1(Line, Anno)]; set_line1(Line, []) -> [Line]. line(Anno) when is_integer(Anno) -> Anno; line(Anno) -> line1(Anno). line1([Line|_]) when is_integer(Line) -> Line; line1([_|Anno]) -> line1(Anno); line1([]) -> undefined. %% set(Key, Value, Anno) -> Anno. %% get(Key, Anno) -> Value | undefined. %% Generic accessing functions for the anno. set(line, Val, Anno) -> set_line(Val, Anno); set(Key, Val, Anno) when is_integer(Anno) -> [Anno,{Key,Val}]; set(Key, Val, Anno) -> set1(Key, Val, Anno). set1(Key, Val, [{Key,_Old}|Anno]) -> [{Key,Val}|Anno]; set1(Key, Val, [A|Anno]) -> [A|set1(Key, Val, Anno)]; set1(Key, Val, []) -> [{Key,Val}]. get(line, Anno) -> line(Anno); %This is untagged get(_Key, Anno) when is_integer(Anno) -> %This is untagged so not Key undefined; get(Key, Anno) -> get1(Key, Anno). get1(Key, [{Key,Val}|_Anno]) -> Val; get1(Key, [_|Anno]) -> get1(Key, Anno); get1(_Key, []) -> undefined. luerl-1.2.3/src/Elixir.Luerl.erl0000664000175000017500000000760014677012037017043 0ustar debalancedebalance%% Copyright (c) 2013-2021 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_ex.erl %% Authors : Cees de Groot %% Purpose : Elixir-style wrappers for luerl.erl %% This module just contains functions that forward to luerl.erl, but place %% the VM State arguments in the first position rather than the last. This %% better matches Elixir conventions and allows for using the Elixir pipe %% operator '|>' to chain Luerl function calls. -module('Elixir.Luerl'). -export([eval/2,evalfile/2, do/2,dofile/2, load/2,load/3, loadfile/2,loadfile/3, path_loadfile/2,path_loadfile/3,path_loadfile/4, load_module/3,load_module1/3, call/3,call_chunk/3, call_function/3,call_function1/3,function_list/2, call_method/3,call_method1/3,method_list/2, get_table/2,get_table1/2,set_table/3,set_table1/3,set_table1/4, init/0,stop/1,gc/1, set_trace_func/2,clear_trace_func/1, set_trace_data/2,get_trace_data/1, get_stacktrace/1 ]). %% Encoding and decoding. -export([encode/2,encode_list/2,decode/2,decode_list/2]). %%Helping with storing VM state -export([externalize/1,internalize/1]). eval(St, Chunk) -> luerl:eval(Chunk, St). evalfile(St, Path) -> luerl:evalfile(Path, St). do(St, S) -> luerl:do(S, St). dofile(St, Path) -> luerl:dofile(Path, St). load(St, Bin) -> luerl:load(Bin, St). load(St, Bin, Opts) -> luerl:load(Bin, Opts, St). loadfile(St, Name) -> luerl:loadfile(Name, St). loadfile(St, Name, Opts) -> luerl:loadfile(Name, Opts, St). path_loadfile(St, Name) -> luerl:path_loadfile(Name, St). path_loadfile(St, Dirs, Name) -> luerl:path_loadfile(Dirs, Name, St). path_loadfile(St, Dir, Name, Opts) -> luerl:path_loadfile(Dir, Name, Opts, St). load_module(St, Fp, Mod) -> luerl:load_module(Fp, Mod, St). load_module1(St, Fp, Mod) -> luerl:load_module1(Fp, Mod, St). init() -> luerl:init(). call(St, C, As) -> luerl:call(C, As, St). call_chunk(St, C, As) -> luerl:call_chunk(C, As, St). call_function(St, Fp, As) -> luerl:call_function(Fp, As, St). call_function1(St, Lfp, Las) -> luerl:call_function1(Lfp, Las, St). function_list(St, Ks) -> luerl:function_list(Ks, St). call_method(St, Fp, As) -> luerl:call_method(Fp, As, St). call_method1(St, Fp, Las) -> luerl:call_method1(Fp, Las, St). method_list(St, Ks) -> luerl:method_list(Ks, St). get_table(St, Fp) -> luerl:get_table(Fp, St). get_table1(St, Fp) -> luerl:get_table1(Fp, St). set_table(St, Fp, V) -> luerl:set_table(Fp, V, St). set_table1(St, Lfp, Lv) -> luerl:set_table1(Lfp, Lv, St). set_table1(St, Tab, Key, Lv) -> luerl:set_table1(Tab, Key, Lv, St). stop(St) -> luerl:stop(St). gc(St) -> luerl:gc(St). set_trace_func(St, Func) -> luerl:set_trace_func(Func, St). clear_trace_func(St) -> luerl:clear_trace_func(St). get_trace_data(St) -> luerl:get_trace_data(St). set_trace_data(St, Tdata) -> luerl:set_trace_data(Tdata, St). get_stacktrace(St) -> luerl:get_stacktrace(St). encode_list(St, Ts) -> luerl:encode_list(Ts, St). encode(St, V) -> luerl:encode(V, St). decode_list(St, Lts) -> luerl:decode_list(Lts, St). decode(St, V) -> luerl:decode(V, St). externalize(St) -> luerl_new:externalize(St). internalize(St) -> luerl_new:internalize(St). luerl-1.2.3/src/luerl_lib_string.erl0000664000175000017500000006072614677012037020074 0ustar debalancedebalance%% Copyright (c) 2013-2021 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_lib_string.erl %% Author : Robert Virding %% Purpose : The string library for Luerl. -module(luerl_lib_string). -include("luerl.hrl"). %% The basic entry point to set up the function table. -export([install/1,byte/3,char/3,dump/3,find/3,format/3,gmatch/3,gsub/3,len/3,lower/3, match/3,rep/3,reverse/3,sub/3,upper/3]). %% Export some test functions. -export([test_gsub/3,test_match_pat/3,test_pat/1, test_byte/3,test_do_find/4,test_sub/2,test_sub/3]). -import(luerl_lib, [lua_error/2,badarg_error/3]). %Shorten this %%-compile([bin_opt_info]). %For when we are optimising install(St0) -> {T,St1} = luerl_heap:alloc_table(table(), St0), {M,St2} = luerl_heap:alloc_table(metatable(T), St1), Meta0 = St2#luerl.meta, Meta1 = Meta0#meta{string=M}, {T,St2#luerl{meta=Meta1}}. %% metatable(Table) -> [{TableName,Table}]. %% table() -> [{FuncName,Function}]. metatable(T) -> %String type metatable [{<<"__index">>,T}]. table() -> %String table [{<<"byte">>,#erl_mfa{m=?MODULE,f=byte}}, {<<"char">>,#erl_mfa{m=?MODULE,f=char}}, {<<"dump">>,#erl_mfa{m=?MODULE,f=dump}}, {<<"find">>,#erl_mfa{m=?MODULE,f=find}}, {<<"format">>,#erl_mfa{m=?MODULE,f=format}}, {<<"gmatch">>,#erl_mfa{m=?MODULE,f=gmatch}}, {<<"gsub">>,#erl_mfa{m=?MODULE,f=gsub}}, {<<"len">>,#erl_mfa{m=?MODULE,f=len}}, {<<"lower">>,#erl_mfa{m=?MODULE,f=lower}}, {<<"match">>,#erl_mfa{m=?MODULE,f=match}}, {<<"rep">>,#erl_mfa{m=?MODULE,f=rep}}, {<<"reverse">>,#erl_mfa{m=?MODULE,f=reverse}}, {<<"sub">>,#erl_mfa{m=?MODULE,f=sub}}, {<<"upper">>,#erl_mfa{m=?MODULE,f=upper}} ]. %% byte(String [, I [, J]] ) -> [Code] %% Return numerical codes of string between I and J. byte(_, As, St) -> case luerl_lib:conv_list(As, [lua_string,lua_integer,lua_integer]) of [S|Is] -> Bs = do_byte(S, byte_size(S), Is), {Bs,St}; _ -> badarg_error(byte, As, St) %nil or [] end. test_byte(S, I, J) -> do_byte(S, byte_size(S), I, J). do_byte(_, 0, _) -> [nil]; do_byte(S, Len, []) -> do_byte(S, Len, 1, 1); do_byte(S, Len, [I]) -> do_byte(S, Len, I, I); do_byte(S, Len, [I,J]) -> do_byte(S, Len, I, J). do_byte(S, Len, I0, J0) -> %The same as for sub I1 = do_sub_m(Len, I0), J1 = do_sub_m(Len, J0), do_byte_ij(S, Len, I1, J1). do_byte_ij(S, Len, I, J) when I < 1 -> do_byte_ij(S, Len, 1, J); do_byte_ij(S, Len, I, J) when J > Len -> do_byte_ij(S, Len, I, Len); do_byte_ij(_, _, I, J) when I > J -> [nil]; do_byte_ij(S, _, I, J) -> [ N || N <- binary_to_list(S, I, J) ]. %% char(...) -> String %% Return string of the numerical arguments. char(_, [nil], St) -> {[<<>>],St}; char(_, As, St) -> case luerl_lib:args_to_integers(As) of error -> badarg_error(char, As, St); Bs -> String = list_to_binary(Bs), {[String],St} end. %% dump(Function) -> String. %% Return a string with binary representation of Function. -spec dump(_, [_], _) -> no_return(). dump(_, As, St) -> badarg_error(dump, As, St). %% find(String, Pattern [, Init [, Plain]]) -> [Indice]. %% Return first occurrence of Pattern in String. find(_, As, St0) -> try do_find(As, St0) catch throw:{error,E,St1} -> lua_error(E, St1); throw:{error,E} -> lua_error(E, St0) end. do_find([A1,A2], St) -> do_find([A1,A2,1.0], St); do_find([A1,A2,A3], St) -> do_find([A1,A2,A3,nil], St); do_find(As, St) -> case luerl_lib:conv_list(As, [lua_string,lua_string,lua_integer,lua_bool]) of [S,P,I,Pl] -> {do_find(S, byte_size(S), P, I, Pl),St}; _ -> throw({error,{badarg,find,As},St}) %nil, [_] or [] end. test_do_find(S, Pat, I, Pl) -> do_find(S, byte_size(S), Pat, I, Pl). %% do_find(String, Length, Pattern, Start, Plain) -> [Return]. %% Adjust the starting index and find the string. do_find(_, L, _, I, _) when I > L+1 -> [nil]; do_find(S, L, Pat, I, Pl) when I < -L -> do_find(S, L, Pat, 1, Pl); do_find(S, L, Pat, I, Pl) when I < 0 -> do_find(S, L, Pat, L+I+1, Pl); do_find(S, L, Pat, 0, Pl) -> do_find(S, L, Pat, 1, Pl); do_find(S, L, Pat, I, true) -> %Plain text search string case binary:match(S, Pat, [{scope,{I-1,L-I+1}}]) of {Fs,Fl} -> [Fs+1,Fs+Fl]; nomatch -> [nil] end; do_find(S, L, Pat0, I, false) -> %Pattern search string case pat(binary_to_list(Pat0)) of {ok,{Pat1,_},_} -> L1 = L - I + 1, %Length of substring S1 = binary_part(S, I-1, L1), %Start searching from I case match_loop(S1, L1, Pat1, 1) of [{_,P,Len}|Cas] -> %Matches P1 = P + I - 1, %Position in original string [P1,P1+Len-1|match_caps(Cas, S, I)]; [] -> [nil] %No match end; {error,E} -> throw({error,E}) end. %% format(Format, ...) -> [String]. %% Format a string. All errors are badarg errors. %% Do all the work in luerl_string_format but generate errors here. format(_, [F|As], St0) -> try luerl_lib_string_format:format(F, As, St0) catch %% If we have a specific error, default is badarg. throw:{error,E,St1} -> lua_error(E, St1); throw:{error,E} -> lua_error(E, St0); _:_ -> badarg_error(format, [F|As], St0) end; format(_, As, St) -> badarg_error(format, As, St). -spec gmatch(_, [_], _) -> no_return(). %To keep dialyzer quiet %% gmatch(String, Pattern) -> [Function]. gmatch(_, As, St) -> badarg_error(gmatch, As, St). %% gsub(String, Pattern, Repl [, N]) -> [String] gsub(_, As, St0) -> try do_gsub(As, St0) catch throw:{error,E,St1} -> lua_error(E, St1); throw:{error,E} -> lua_error(E, St0) end. do_gsub(As, St) -> case luerl_lib:conv_list(As, [lua_string,lua_string,lua_any,lua_integer]) of [S,P,R,N] when N > 0 -> do_gsub(S, byte_size(S), P, R, N, St); [S,P,R] -> %'all' bigger than any number do_gsub(S, byte_size(S), P, R, all, St); _ -> throw({error,{badarg,gsub,As},St}) end. test_gsub(S, P, N) -> {ok,{Pat,_},_} = pat(binary_to_list(P)), gsub_match_loop(S, byte_size(S), Pat, 1, 1, N). do_gsub(S, L, Pat0, R, N, St0) -> case pat(binary_to_list(Pat0)) of {ok,{Pat1,_},_} -> Fs = gsub_match_loop(S, L, Pat1, 1, 1, N), {Ps,St1} = gsub_repl_loop(Fs, S, 1, L, R, St0), {[iolist_to_binary(Ps),length(Fs)],St1}; {error,E} -> throw({error,E}) end. %% gsub_match_loop(S, L, Pat, I, C, N) -> [Cas]. %% Return the list of Cas's for each match. gsub_match_loop(_, _, _, _, C, N) when C > N -> []; gsub_match_loop(<<>>, _, Pat, I, _, _) -> %It can still match at end! case match_pat(<<>>, Pat, I) of {match,Cas,_,_} -> [Cas]; nomatch -> [] end; gsub_match_loop(S0, L, Pat, I0, C, N) -> case match_pat(S0, Pat, I0) of {match,Cas,_,I0} -> %Zero length match S1 = binary_part(S0, 1, L-I0), [Cas|gsub_match_loop(S1, L, Pat, I0+1, C+1, N)]; {match,Cas,S1,I1} -> [Cas|gsub_match_loop(S1, L, Pat, I1, C+1, N)]; nomatch -> S1 = binary_part(S0, 1, L-I0), gsub_match_loop(S1, L, Pat, I0+1, C, N) end. %% gsub_repl_loop([Cas], String, Index, Length, Reply, State) -> %% {iolist,State}. %% Build the return string as an iolist processing each match and %% filling in with the original string. gsub_repl_loop([[{_,F,Len}|_]=Cas|Fs], S, I, L, R, St0) -> %% io:fwrite("grl: ~p\n", [{Cas,S,R}]), {Rep,St1} = gsub_repl(Cas, S, R, St0), %% io:fwrite("grl->~p\n", [{Rep}]), {Ps,St2} = gsub_repl_loop(Fs, S, F+Len, L, R, St1), {[binary_part(S, I-1, F-I),Rep|Ps],St2}; gsub_repl_loop([], S, I, L, _, St) -> {[binary_part(S, I-1, L-I+1)],St}. gsub_repl(Cas, S, #tref{}=T, St0) -> case Cas of %Export both Ca and Key [Ca] -> Key = match_cap(Ca, S); [Ca,Ca1|_] -> Key = match_cap(Ca1, S) end, {R,St1} = luerl_emul:get_table_key(T, Key, St0), {[gsub_repl_val(S, R, Ca)],St1}; gsub_repl(Cas0, S, Repl, St0) when ?IS_FUNCTION(Repl) -> case Cas0 of %Export both Ca and Args [Ca] -> Args = [match_cap(Ca, S)]; [Ca|Cas] -> Args = match_caps(Cas, S) end, {Rs,St1} = luerl_emul:functioncall(Repl, Args, St0), {[gsub_repl_val(S, luerl_lib:first_value(Rs), Ca)],St1}; gsub_repl(Cas, S, Repl, St) -> %Replace string case luerl_lib:arg_to_list(Repl) of error -> {[],St}; R -> {gsub_repl_str(Cas, S, R),St} end. gsub_repl_str(Cas, S, [$%,$%|R]) -> [$%|gsub_repl_str(Cas, S, R)]; gsub_repl_str(Cas, S, [$%,$0|R]) -> Cstr = luerl_lib:arg_to_string(match_cap(hd(Cas), S)), %Force to string! [Cstr|gsub_repl_str(Cas, S, R)]; gsub_repl_str(Cas, S, [$%,C|R]) when C >= $1, C =< $9 -> case lists:keysearch(C-$0, 1, Cas) of {value,Ca} -> Cstr = luerl_lib:arg_to_string(match_cap(Ca, S)), %Force to string! [Cstr|gsub_repl_str(Cas, S, R)]; false -> throw({error,{illegal_index,capture,C-$0}}) end; gsub_repl_str(Cas, S, [C|R]) -> [C|gsub_repl_str(Cas, S, R)]; gsub_repl_str(_, _, []) -> []. %% Return string or original match. gsub_repl_val(S, Val, Ca) -> case luerl_lib:arg_to_string(Val) of error -> match_cap(Ca, S); %Use original match Str -> Str end. %% len(String) -> Length. len(_, [A|_], St) when is_binary(A) -> {[byte_size(A)],St}; len(_, [A|_], St) when is_number(A) -> {[length(luerl_lib:number_to_list(A))],St}; len(_, As, St) -> badarg_error(len, As, St). %% lower(String) -> String. lower(_, As, St) -> case luerl_lib:conv_list(As, [erl_list]) of [S] -> {[list_to_binary(string:to_lower(S))],St}; _ -> badarg_error(lower, As, St) %nil or [] end. %% match(String, Pattern [, Init]) -> [Match]. match(_, As, St0) -> try do_match(As, St0) catch throw:{error,E,St1} -> lua_error(E, St1); throw:{error,E} -> lua_error(E, St0) end. do_match([A1,A2], St) -> do_match([A1,A2,1.0], St); do_match(As, St) -> case luerl_lib:conv_list(As, [lua_string,lua_string,lua_integer]) of [S,P,I] -> {do_match(S, byte_size(S), P, I),St}; _ -> throw({error,{badarg,match,As},St}) end. %% do_match(String, Length, Pattern, Start) -> [Return]. %% Adjust the starting index and find the match. do_match(_, L, _, I) when I > L -> [nil]; %Shuffle values do_match(S, L, Pat, I) when I < -L -> do_match(S, L, Pat, 1); do_match(S, L, Pat, I) when I < 0 -> do_match(S, L, Pat, L+I+1); do_match(S, L, Pat, 0) -> do_match(S, L, Pat, 1); do_match(S, L, Pat0, I) -> case pat(binary_to_list(Pat0)) of %"Compile" the pattern {ok,{Pat1,_},_} -> L1 = L - I + 1, %Length of substring S1 = binary_part(S, I-1, L1), %Start searching from I case match_loop(S1, L1, Pat1, 1) of [{_,P,Len}] -> %Only top level match P1 = P + I - 1, %Position in original string [binary_part(S, P1-1, Len)]; [_|Cas] -> %Have sub matches match_caps(Cas, S1); [] -> [nil] %No match end; {error,E} -> throw({error,E}) end. %% match_loop(String, Length, Pattern, Index) -> Cas | []. %% Step down the string trying to find a match. match_loop(S, L, Pat, I) when I > L -> %It can still match at end! case match_pat(S, Pat, I) of {match,Cas,_,_} -> Cas; nomatch -> [] %Now we haven't found it end; match_loop(S0, L, Pat, I) -> case match_pat(S0, Pat, I) of {match,Cas,_,_} -> Cas; nomatch -> S1 = binary_part(S0, 1, L-I), match_loop(S1, L, Pat, I+1) end. %% match_cap(Capture, String [, Init]) -> Capture. %% match_caps(Captures, String [, Init]) -> Captures. %% Get the captures. The string is the whole string not just from %% Init. match_cap(Ca, S) -> match_cap(Ca, S, 1). match_cap({_,P,Len}, _, I) when Len < 0 -> %Capture position P+I-1; match_cap({_,P,Len}, S, I) -> %Capture binary_part(S, P+I-2, Len). %Binaries count from 0 match_caps(Cas, S) -> match_caps(Cas, S, 1). match_caps(Cas, S, I) -> [ match_cap(Ca, S, I) || Ca <- Cas ]. %% rep(String, N [, Separator]) -> [String]. rep(_, [A1,A2], St) -> rep(nil, [A1,A2,<<>>], St); rep(_, [_,_,_|_]=As, St) -> case luerl_lib:conv_list(As, [lua_string,lua_integer,lua_string]) of [S,I,Sep] -> Part = [Sep,S], if I > 100 -> %% For many repetitions. I1 = (I-1) div 100, I2 = (I-1) rem 100, D100 = iolist_to_binary(lists:duplicate(100, Part)), {[iolist_to_binary([S, lists:duplicate(I1, D100), lists:duplicate(I2, Part)])], St}; I > 0 -> {[iolist_to_binary([S|lists:duplicate(I-1, Part)])],St}; true -> {[<<>>],St} end; error -> %Error or bad values badarg_error(rep, As, St) end; rep(_, As, St) -> badarg_error(rep, As, St). %% reverse([String], State) -> {[Res],St}. reverse(_, [A|_], St) when is_binary(A) ; is_number(A) -> S = luerl_lib:arg_to_list(A), {[list_to_binary(lists:reverse(S))],St}; reverse(_, As, St) -> badarg_error(reverse, As, St). %% sub([String, I [, J]], State) -> {[Res],State}. sub(_, As, St) -> case luerl_lib:conv_list(As, [lua_string,lua_integer,lua_integer]) of [S,I|Js] -> Len = byte_size(S), Sub = do_sub(S, Len, I, Js), %Just I, or both I and J {[Sub],St}; _ -> badarg_error(sub, As, St) %nil, [_] or [] end. test_sub(S, I) -> do_sub(S, byte_size(S), I, []). test_sub(S, I, J) -> do_sub(S, byte_size(S), I, [J]). do_sub(S, _, 0, []) -> S; %Special case this do_sub(S, Len, I, []) -> do_sub_1(S, Len, I, Len); do_sub(S, Len, I, [J]) -> do_sub_1(S, Len, I, J). do_sub_1(S, Len, I0, J0) -> I1 = do_sub_m(Len, I0), J1 = do_sub_m(Len, J0), do_sub_ij(S, Len, I1, J1). do_sub_m(Len, I) when I < 0 -> Len+I+1; %Negative count from end do_sub_m(_, I) -> I. do_sub_ij(S, Len, I, J) when I < 1 -> do_sub_ij(S, Len, 1, J); do_sub_ij(S, Len, I, J) when J > Len -> do_sub_ij(S, Len, I, Len); do_sub_ij(_, _, I, J) when I > J -> <<>>; do_sub_ij(S, _, I, J) -> binary:part(S, I-1, J-I+1). %Zero-based, yuch! upper(_, [A|_], St) when is_binary(A) ; is_number(A) -> S = luerl_lib:arg_to_list(A), {[list_to_binary(string:to_upper(S))],St}; upper(_, As, St) -> badarg_error(upper, As, St). %% This is the pattern grammar used. It may actually be overkill to %% first parse the pattern as the pattern is relativey simple and we %% should be able to do it in one pass. %% %% pat -> seq : '$1'. %% seq -> single seq : ['$1'|'$2']. %% seq -> single : '$1'. %% single -> "(" seq ")" . %% single -> "[" class "]" : {char_class,char_class('$2')} %% single -> "[" "^" class "]" : {comp_class,char_class('$3')} %% single -> char "*" . %% single -> char "+" . %% single -> char "-" . %% single -> char "?" . %% single -> char . %% char -> "%" class . %% char -> "." . %% char -> char . %% The actual parser is a recursive descent implementation of the %% grammar. We leave ^ $ as normal characters and handle them %% specially in matching. pat(Cs0) -> case catch seq(Cs0, 0, 1, []) of {error,E} -> {error,E}; {P,0,Sn} -> {ok,{P,0},Sn}; {_,_,_} -> {error,invalid_capture} end. test_pat(P) -> pat(P). seq([$^|Cs], Sd, Sn, P) -> single(Cs, Sd, Sn, ['^'|P]); seq([_|_]=Cs, Sd, Sn, P) -> single(Cs, Sd, Sn, P); seq([], Sd, Sn, P) -> {lists:reverse(P),Sd,Sn}. single([$(|Cs], Sd, Sn, P) -> single(Cs, Sd+1, Sn+1, [{'(',Sn}|P]); single([$)|_], 0, _, _) -> throw({error,invalid_capture}); single([$)|Cs], Sd, Sn, P) -> single(Cs, Sd-1, Sn, [')'|P]); single([$[|Cs], Sd, Sn, P) -> char_set(Cs, Sd, Sn, P); single([$.|Cs], Sd, Sn, P) -> singlep(Cs, Sd, Sn, ['.'|P]); single([$%|Cs], Sd, Sn, P) -> char_class(Cs, Sd, Sn, P); single([$$], Sd, Sn, P) -> {lists:reverse(P, ['\$']),Sd,Sn}; single([C|Cs], Sd, Sn, P) -> singlep(Cs, Sd, Sn, [C|P]); single([], Sd, Sn, P) -> {lists:reverse(P),Sd,Sn}. singlep([$*|Cs], Sd, Sn, [Char|P]) -> single(Cs, Sd, Sn, [{kclosure,Char}|P]); singlep([$+|Cs], Sd, Sn, [Char|P]) -> single(Cs, Sd, Sn, [{pclosure,Char}|P]); singlep([$-|Cs], Sd, Sn, [Char|P]) -> single(Cs, Sd, Sn, [{mclosure,Char}|P]); singlep([$?|Cs], Sd, Sn, [Char|P]) -> single(Cs, Sd, Sn, [{optional,Char}|P]); singlep(Cs, Sd, Sn, P) -> single(Cs, Sd, Sn, P). char_set([$^|Cs], Sd, Sn, P) -> char_set(Cs, Sd, Sn, P, comp_set); char_set(Cs, Sd, Sn, P) -> char_set(Cs, Sd, Sn, P, char_set). char_set(Cs0, Sd, Sn, P, Tag) -> case char_set(Cs0) of {Set,[$]|Cs1]} -> singlep(Cs1, Sd, Sn, [{Tag,Set}|P]); {_,_} -> throw({error,invalid_char_set}) end. char_set([$]|Cs]) -> char_set(Cs, [$]]); %Must special case this char_set(Cs) -> char_set(Cs, []). char_set([$]|_]=Cs, Set) -> {Set,Cs}; %We are at the end char_set([$%,C|Cs], Set) -> char_set(Cs, [char_class(C)|Set]); char_set([C1,$-,C2|Cs], Set) when C2 =/= $] -> char_set(Cs, [{C1,C2}|Set]); char_set([C|Cs], Set) -> char_set(Cs, [C|Set]); char_set([], Set) -> {Set,[]}. %We are at the end %% char_class([$f,$[|Cs], Sd, Sn, P) -> %% char_set(Cs, Sd, Sn, [frontier|P]); char_class([$f|_], _, _, _) -> throw({error,invalid_pattern}); char_class([$b,L,R|Cs], Sd, Sn, P) -> singlep(Cs, Sd, Sn, [{balance,L,R}|P]); char_class([C|Cs], Sd, Sn, P) -> singlep(Cs, Sd, Sn, [char_class(C)|P]); char_class([], _, _, _) -> throw({error,invalid_pattern}). char_class($a) -> 'a'; char_class($A) -> 'A'; char_class($c) -> 'c'; char_class($C) -> 'C'; char_class($d) -> 'd'; char_class($D) -> 'D'; char_class($g) -> 'g'; char_class($G) -> 'G'; char_class($l) -> 'l'; char_class($L) -> 'L'; char_class($p) -> 'p'; char_class($P) -> 'P'; char_class($s) -> 's'; char_class($S) -> 'S'; char_class($u) -> 'u'; char_class($U) -> 'U'; char_class($w) -> 'w'; char_class($W) -> 'W'; char_class($x) -> 'x'; char_class($X) -> 'X'; char_class($z) -> 'z'; %Deprecated char_class($Z) -> 'Z'; char_class(C) -> %Only non-alphanum allowed case is_w_char(C) of true -> throw({error,{invalid_char_class,C}}); false -> C end. test_match_pat(S, P, I) -> {ok,{Pat,_},_} = pat(P), io:fwrite("tdm: ~p\n", [{Pat}]), match_pat(S, Pat, I). %% match_pat(String, Pattern, Index) -> {match,[Capture],Rest,Index} | nomatch. %% Try and match the pattern with the string *at the current %% position*. No searching. match_pat(S0, P0, I0) -> case match_pat(P0, S0, I0, [{0,I0}], []) of {match,S1,I1,_,Cas} ->{match,Cas,S1,I1}; {nomatch,_,_,_,_,_} -> nomatch end. match_pat(['\$']=Ps, Cs, I, Ca, Cas) -> %Match only end of string case Cs of <<>> -> match_pat([], <<>>, I, Ca, Cas); _ -> {nomatch,Ps,Cs,I,Ca,Cas} end; match_pat(['^'|Ps]=Ps0, Cs, I, Ca, Cas) -> %Match beginning of string if I =:= 1 -> match_pat(Ps, Cs, 1, Ca, Cas); true -> {nomatch,Ps0,Cs,I,Cs,Cas} end; match_pat([{'(',Sn},')'|P], Cs, I, Ca, Cas) -> match_pat(P, Cs, I, Ca, save_cap(Sn, I, -1, Cas)); match_pat([{'(',Sn}|P], Cs, I, Ca, Cas) -> match_pat(P, Cs, I, [{Sn,I}|Ca], Cas); match_pat([')'|P], Cs, I, [{Sn,S}|Ca], Cas) -> match_pat(P, Cs, I, Ca, save_cap(Sn, S, I-S, Cas)); match_pat([{kclosure,P}=K|Ps], Cs, I, Ca, Cas) -> %%io:fwrite("dm: ~p\n", [{[P,K|Ps],Cs,I,Ca,Cas}]), case match_pat([P,K|Ps], Cs, I, Ca, Cas) of %First try with it {match,_,_,_,_}=M -> M; {nomatch,_,_,_,_,_} -> %Else try without it match_pat(Ps, Cs, I, Ca, Cas) end; match_pat([{pclosure,P}|Ps], Cs, I, Ca, Cas) -> %The easy way match_pat([P,{kclosure,P}|Ps], Cs, I, Ca, Cas); match_pat([{mclosure,P}=K|Ps], Cs, I, Ca, Cas) -> case match_pat(Ps, Cs, I, Ca, Cas) of %First try without it {match,_,_,_,_}=M -> M; {nomatch,_,_,_,_,_} -> %Else try with it match_pat([P,K|Ps], Cs, I, Ca, Cas) end; match_pat([{optional,P}|Ps], Cs, I, Ca, Cas) -> case match_pat([P|Ps], Cs, I, Ca, Cas) of %First try with it {match,_,_,_,_}=M -> M; {nomatch,_,_,_,_,_} -> %Else try without it match_pat(Ps, Cs, I, Ca, Cas) end; match_pat([{char_set,Set}|Ps]=Ps0, <>=Cs0, I, Ca, Cas) -> case match_char_set(Set, C) of true -> match_pat(Ps, Cs, I+1, Ca, Cas); false -> {nomatch,Ps0,Cs0,I,Ca,Cas} end; match_pat([{comp_set,Set}|Ps]=Ps0, <>=Cs0, I, Ca, Cas) -> case match_char_set(Set, C) of true -> {nomatch,Ps0,Cs0,I,Ca,Cas}; false -> match_pat(Ps, Cs, I+1, Ca, Cas) end; match_pat([{balance,L,R}|Ps]=Ps0, <>=Cs0, I0, Ca, Cas) -> case balance(Cs1, I0+1, L, R, 1) of {ok,Cs2,I1} -> match_pat(Ps, Cs2, I1, Ca, Cas); error -> {nomatch,Ps0,Cs0,I0,Ca,Cas} end; match_pat(['.'|Ps], <<_,Cs/binary>>, I, Ca, Cas) -> %Matches anything match_pat(Ps, Cs, I+1, Ca, Cas); match_pat([A|Ps]=Ps0, <>=Cs0, I, Ca, Cas) when is_atom(A) -> case match_class(A, C) of true -> match_pat(Ps, Cs, I+1, Ca, Cas); false -> {nomatch,Ps0,Cs0,I,Ca,Cas} end; match_pat([C|Ps], <>, I, Ca, Cas) -> match_pat(Ps, Cs, I+1, Ca, Cas); match_pat([], Cs, I, [{Sn,S}|Ca], Cas) -> {match,Cs,I,Ca,[{Sn,S,I-S}|Cas]}; match_pat(Ps, Cs, I, Ca, Cas) -> {nomatch,Ps,Cs,I,Ca,Cas}. %% save_cap(N, Position, Length, Captures) -> Captures. %% Add a new capture to the list in the right place, ordered. save_cap(N, P, L, [{N1,_,_}=Ca|Cas]) when N > N1 -> [Ca|save_cap(N, P, L, Cas)]; save_cap(N, P, L, Cas) -> [{N,P,L}|Cas]. %% MUST first check for right char, this in case of L == R! balance(<>, I, L, R, D) -> if D =:= 1 -> {ok,Cs,I+1}; true -> balance(Cs, I+1, L, R, D-1) end; balance(<>, I, L, R, D) -> balance(Cs, I+1, L, R, D+1); balance(<<_,Cs/binary>>, I, L, R, D) -> balance(Cs, I+1, L, R, D); balance(<<>>, _, _, _, _) -> error. match_class('a', C) -> is_a_char(C); match_class('A', C) -> not is_a_char(C); match_class('c', C) -> is_c_char(C); match_class('C', C) -> not is_c_char(C); match_class('d', C) -> is_d_char(C); match_class('D', C) -> not is_d_char(C); match_class('g', C) -> is_g_char(C); match_class('G', C) -> not is_g_char(C); match_class('l', C) -> is_l_char(C); match_class('L', C) -> not is_l_char(C); match_class('p', C) -> is_p_char(C); match_class('P', C) -> not is_p_char(C); match_class('s', C) -> is_s_char(C); match_class('S', C) -> not is_s_char(C); match_class('u', C) -> is_u_char(C); match_class('U', C) -> not is_u_char(C); match_class('w', C) -> is_w_char(C); match_class('W', C) -> not is_w_char(C); match_class('x', C) -> is_x_char(C); match_class('X', C) -> not is_x_char(C); match_class('z', C) -> is_z_char(C); %Deprecated match_class('Z', C) -> not is_z_char(C). match_char_set([{C1,C2}|_], C) when C >= C1, C=< C2 -> true; match_char_set([A|Set], C) when is_atom(A) -> match_class(A, C) orelse match_char_set(Set, C); match_char_set([C|_], C) -> true; match_char_set([_|Set], C) -> match_char_set(Set, C); match_char_set([], _) -> false. %% Test for various character types. is_a_char(C) -> %All letters is_l_char(C) orelse is_u_char(C). is_c_char(C) when C >= 0, C =< 31 -> true; %All control characters is_c_char(C) when C >= 128, C =< 159 -> true; is_c_char(_) -> false. is_d_char(C) -> (C >= $0) and (C =< $9). %All digits is_g_char(C) when C >= 33, C =< 126 -> true; %All printable characters is_g_char(C) when C >= 161, C =< 255 -> true; is_g_char(_) -> false. is_l_char(C) when C >= $a, C =< $z -> true; %All lowercase letters is_l_char(C) when C >= 224, C =< 246 -> true; is_l_char(C) when C >= 248, C =< 255 -> true; is_l_char(_) -> false. is_p_char(C) when C >= 33, C =< 47 -> true; %All punctutation characters is_p_char(C) when C >= 58, C =< 63 -> true; is_p_char(C) when C >= 91, C =< 96 -> true; is_p_char(126) -> true; is_p_char(C) when C >= 161, C =< 191 -> true; is_p_char(215) -> true; is_p_char(247) -> true; is_p_char(_) -> false. is_s_char(C) when C >= 9, C =< 13 -> true; %Space characters is_s_char(32) -> true; is_s_char(160) -> true; is_s_char(_) -> false. is_u_char(C) when C >= $A, C =< $Z -> true; %All uppercase letters is_u_char(C) when C >= 192, C =< 214 -> true; is_u_char(C) when C >= 216, C =< 223 -> true; is_u_char(_) -> false. is_w_char(C) -> %All alphanumeric characters is_a_char(C) orelse is_d_char(C). is_x_char(C) when C >= $a, C =< $f -> true; %All hexadecimal characters is_x_char(C) when C >= $A, C =< $F -> true; is_x_char(C) -> is_d_char(C). is_z_char(C) -> C =:= 0. %The zero character, deprecated %% match_class('a', C) -> (char_table(C) band ?_A) =/= 0; %% match_class('A', C) -> (char_table(C) band ?_A) =:= 0. %% char_table(C) when C >= 0, C =< 31 -> ?_C; %% char_table(C) when C >= 65, C =< 91 -> ?_U bor ?_A; %% char_table(C) when C >= 97, C =< 123 -> ?_L; luerl-1.2.3/src/luerl_lib_bit32.erl0000664000175000017500000001424614677012037017505 0ustar debalancedebalance%% Copyright (c) 2014-2018 Åukasz Biedrycki %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_lib_bit32.erl %% Author : Åukasz Biedrycki %% Purpose : The bit32 library for Luerl. %% This library has been deprecated in 5.3 but we still keep it. -module(luerl_lib_bit32). -include("luerl.hrl"). -export([install/1,fband/3,fbnot/3,fbor/3,fbtest/3,fbxor/3,flshift/3,frshift/3, farshift/3,flrotate/3,frrotate/3,fextract/3,freplace/3]). -import(luerl_lib, [badarg_error/3]). %Shorten this -define(MOST_SIGNIFICANT, 16#80000000). -define(LEAST_SIGNIFICANT, 16#00000001). -define(DEFAULT_BAND, 4294967295). -define(DEFAULT_BOR, 0). -define(DEFAULT_BXOR, 0). install(St) -> luerl_heap:alloc_table(table(), St). table() -> [{<<"band">>,#erl_mfa{m=?MODULE,f=fband}}, {<<"bnot">>,#erl_mfa{m=?MODULE,f=fbnot}}, {<<"bor">>,#erl_mfa{m=?MODULE,f=fbor}}, {<<"btest">>,#erl_mfa{m=?MODULE,f=fbtest}}, {<<"bxor">>,#erl_mfa{m=?MODULE,f=fbxor}}, {<<"lshift">>,#erl_mfa{m=?MODULE,f=flshift}}, {<<"rshift">>,#erl_mfa{m=?MODULE,f=frshift}}, {<<"arshift">>,#erl_mfa{m=?MODULE,f=farshift}}, {<<"lrotate">>,#erl_mfa{m=?MODULE,f=flrotate}}, {<<"rrotate">>,#erl_mfa{m=?MODULE,f=frrotate}}, {<<"extract">>,#erl_mfa{m=?MODULE,f=fextract}}, {<<"replace">>,#erl_mfa{m=?MODULE,f=freplace}} ]. fband(_, As, St) -> case luerl_lib:args_to_integers(As) of L when is_list(L) -> {[aband(L)], St}; error -> badarg_error('band', As, St) end. aband([]) -> ?DEFAULT_BAND; aband([X|T]) -> aband(T, checkint32(X)). aband([], A) -> float(A); aband([X|T], A) -> aband(T, checkint32(X) band A). fbnot(_, As, St) -> case luerl_lib:args_to_integers(As) of [N|_] -> NotN = bnot checkint32(N), {[float(NotN)], St}; error -> badarg_error('bnot', As, St) end. fbor(_, As, St) -> case luerl_lib:args_to_integers(As) of L when is_list(L) -> {[abor(L)], St}; error -> badarg_error('bor', As, St) end. abor([]) -> ?DEFAULT_BOR; abor([X|T]) -> abor(T, checkint32(X)). abor([], A) -> float(A); abor([X|T], A) -> abor(T, checkint32(X) bor A). fbtest(_, As, St) -> case luerl_lib:args_to_integers(As) of L when is_list(L) -> {[aband(L) /= 0], St}; error -> badarg_error('btest', As, St) end. fbxor(_, As, St) -> case luerl_lib:args_to_integers(As) of L when is_list(L) -> {[abxor(L)], St}; error -> badarg_error('bxor', As, St) end. abxor([]) -> ?DEFAULT_BXOR; abxor([X|T]) -> abxor(T, checkint32(X)). abxor([], A) -> float(A); abxor([X|T], A) -> abxor(T, checkint32(X) bxor A). flshift(_, As, St) -> case luerl_lib:args_to_integers(As) of [X,Y|_] -> {[float(checkint32(X) bsl trunc(Y))], St}; _ -> badarg_error('lshift', As, St) end. frshift(_, As, St) -> case luerl_lib:args_to_integers(As) of [X,Y|_] -> {[float(checkint32(X) bsr trunc(Y))], St}; _ -> badarg_error('rshift', As, St) end. farshift(_, As, St) -> case luerl_lib:args_to_integers(As) of [X,Y|_] -> Disp = trunc(Y), case Disp > 0 of true -> {[float(checkint32(X) bsr trunc(Y))], St}; false -> {[float(checkint32(X) bsl abs(trunc(Y)))], St} end; _ -> badarg_error('arshift', As, St) end. flrotate(_, As, St) -> case luerl_lib:args_to_integers(As) of [X,Y|_] -> {[float(lrotate(checkint32(X), trunc(Y)))], St}; _ -> badarg_error('lrotate', As, St) end. frrotate(_, As, St) -> case luerl_lib:args_to_integers(As) of [X,Y|_] -> {[float(rrotate(checkint32(X), trunc(Y)))], St}; _ -> badarg_error('rrotate', As, St) end. fextract(_, As, St) -> case luerl_lib:args_to_integers(As) of [N,Field,Width|_] -> {[float(extract(N, Field, Width, As, St))], St}; [N,Field|_] -> {[float(extract(N, Field, 1, As, St))], St}; _ -> badarg_error('extract', As, St) end. freplace(_, As, St) -> case luerl_lib:args_to_integers(As) of [N,V,Field,Width|_] -> {[float(replace(N, V, Field, Width, As, St))], St}; [N,V,Field|_] -> {[float(replace(N, V, Field, 1, As, St))], St}; _ -> badarg_error('replace', As, St) end. %% Internal lrotate(X, Y) when Y < 0 -> rrotate(X, abs(Y)); lrotate(X, Y) when Y == 0 -> X; lrotate(X1, Y) -> Most = X1 band ?MOST_SIGNIFICANT, X2 = uint32(X1 bsl 1), X3 = X2 bor (Most bsr 31), lrotate(X3, Y - 1). rrotate(X, Y) when Y < 0 -> lrotate(X, abs(Y)); rrotate(X, Y) when Y == 0 -> X; rrotate(X1, Y) -> Least = X1 band ?LEAST_SIGNIFICANT, X2 = X1 bsr 1, X3 = X2 bor (Least bsl 31), rrotate(X3, Y - 1). uint32(N) -> <> = <>, Res. checkint32(N) -> uint32(trunc(N)). ge0(N, Where, As, St) -> case N >= 0 of true -> N; false -> badarg_error(Where, As, St) end. gt0(N, Where, As, St) -> case N > 0 of true -> N; false -> badarg_error(Where, As, St) end. le(N, V, Where, As, St) -> case N =< V of true -> N; false -> badarg_error(Where, As, St) end. extract(N1, Field1, Width1, As, St) -> N2 = checkint32(N1), Field2 = trunc(Field1), Width2 = trunc(Width1), _ = ge0(Field2, 'extract', As, St), _ = gt0(Width2, 'extract', As, St), _ = le(Field2 + Width2, 32, 'extract', As, St), trunc(N2 / math:pow(2, Field2)) rem trunc(math:pow(2, Width2)). replace(N1, V1, Field1, Width1, As, St) -> N2 = checkint32(N1), V2 = checkint32(V1), Field2 = trunc(Field1), Width2 = trunc(Width1), _ = ge0(Field2, 'replace', As, St), _ = gt0(Width2, 'replace', As, St), _ = le(Field2 + Width2, 32, 'extract', As, St), Field3 = trunc(math:pow(2, Field2)), Width3 = trunc(math:pow(2, Width2)), FW = Field3 * Width3, (N2 rem Field3) + (V2 rem Width3) * Field3 + trunc(N2 div FW) * FW. luerl-1.2.3/src/luerl.app.src0000664000175000017500000000226414677012037016435 0ustar debalancedebalance%% -*- mode: erlang; indent-tabs-mode: nil -*- %% Copyright (c) 2013-2024 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. {application, luerl, [{description, "Luerl - an implementation of Lua on Erlang"}, {vsn, "1.2.3"}, {modules, []}, {registered, []}, {applications, [kernel, stdlib]}, {env, []}, {mod, {luerl_app, []}}, %% Project metadata {licenses, ["Apache-2.0"]}, {links, [{"Github", "https://github.com/rvirding/luerl"}]}, %% This is used for hex packages. {files, ["README.md", "LICENSE", "VERSION", "src", "doc", "ebin/luerl.app", "include", "rebar.*", "*akefile", "*.escript"]}, {exclude_files, ["priv/images/*"]} ]}. luerl-1.2.3/src/luerl_comp_normalise.erl0000664000175000017500000003255514677012037020746 0ustar debalancedebalance%% Copyright (c) 2019 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_comp_normalise.erl %% Author : Robert Virding %% Purpose : A basic LUA 5.3 compiler for Luerl. %% Here we normalise the code and convert it to an internal form. -module(luerl_comp_normalise). -include("luerl.hrl"). -include("luerl_comp.hrl"). -export([chunk/2]). %% chunk(Code, CompInfo) -> {ok,Code} | {error,Reason}. chunk(Code0, #cinfo{opts=Opts}=Ci0) -> %% The chunk is a function. {Code1,_Ci1} = functiondef(Code0, Ci0), luerl_comp:debug_print(Opts, "cn: ~p\n", [Code1]), {ok,Code1}. %% stmts([{local,L,{functiondef,_,Name,_,_}=F}|Ss], St) -> %% %% Need to split this to handle recursive definitions. %% stmts([{local,L,{assign,L,[Name],[{nil,L}]}},F|Ss], St); stmts([{';',_}|Ss], St) -> stmts(Ss, St); %No-op so we drop it stmts([S0|Ss0], St0) -> {S1,St1} = stmt(S0, St0), {Ss1,St2} = stmts(Ss0, St1), {[S1|Ss1],St2}; stmts([], St) -> {[],St}. %% stmt(Statement, State) -> {CStat,State}. %% Do a statement. The ';' statement will caught and removed in stmts/2. stmt({assign,Line,Vs,Es}, St) -> assign_stmt(Line, Vs, Es, St); stmt({return,Line,Es}, St) -> return_stmt(Line, Es, St); stmt({break,L}, St) -> %Interesting {#break_stmt{l=L},St}; stmt({block,Line,B}, St) -> block_stmt(Line, B, St); stmt({while,Line,Exp,B}, St) -> while_stmt(Line, Exp, B, St); stmt({repeat,Line,B,Exp}, St) -> repeat_stmt(Line, B, Exp, St); stmt({'if',Line,Tests,Else}, St) -> if_stmt(Line, Tests, Else, St); stmt({for,Line,V,I,L,B}, St) -> %Default step of 1 numfor_stmt(Line, V, I, L, {'NUMERAL',Line,1}, B, St); stmt({for,Line,V,I,L,S,B}, St) -> numfor_stmt(Line, V, I, L, S, B, St); stmt({for,Line,Ns,Gs,B}, St) -> genfor_stmt(Line, Ns, Gs, B, St); stmt({functiondef,Line,Fname,Ps,B}, St) -> fdef_stmt(Line, Fname, Ps, B, St); stmt({local,Line,Local}, St) -> local_stmt(Line, Local, St); stmt(Exp, St) -> %This is really just a call Line = element(2, Exp), call_stmt(Line, Exp, St). %% assign_stmt(Line, Vars, Exps, State) -> {Assign,State}. assign_stmt(Line, Vs, Es, St0) -> {Ces,St1} = explist(Es, St0), {Cvs,St2} = assign_loop(Vs, St1), Anno = line_file_anno(Line, St2), {#assign_stmt{l=Anno,vars=Cvs,exps=Ces},St2}. assign_loop([V|Vs], St0) -> {Cv,St1} = var(V, St0), {Cvs,St2} = assign_loop(Vs, St1), {[Cv|Cvs],St2}; assign_loop([], St) -> {[],St}. %% var(VarExp, State) -> {VarExp,State}. %% Step down the prefixexp sequence evaluating as we go, stop at the %% END and return a key and a table where to put data. This is a %% prefixexp with different tail. var({'.',L,Exp,Rest}, St0) -> {Ce,St1} = prefixexp_first(Exp, St0), {Cr,St2} = var_rest(Rest, St1), {dot(L, Ce, Cr),St2}; var({'NAME',L,N}, St) -> {var_name(L, N),St}. var_rest({'.',L,Exp,Rest}, St0) -> {Ce,St1} = prefixexp_element(Exp, St0), {Cr,St2} = var_rest(Rest, St1), {dot(L, Ce, Cr),St2}; var_rest(Exp, St) -> var_last(Exp, St). var_last({'NAME',L,N}, St) -> %% Transform this to a key_field with the name string. NO! {#key{l=L,key=lit_name(L, N)},St}; var_last({key_field,L,Exp}, St0) -> {Ce,St1} = exp(Exp, St0), {#key{l=L,key=Ce},St1}. %% call_stmt(Line, Exp, State) -> {Call,State}. call_stmt(Line, Exp, St0) -> {Ce,St1} = exp(Exp, St0), Anno = line_file_anno(Line, St1), {#call_stmt{l=Anno,call=Ce},St1}. %% return_stmt(Line, Exps, State) -> {Return,State}. return_stmt(Line, Es, St0) -> {Ces,St1} = explist(Es, St0), Anno = line_file_anno(Line, St1), {#return_stmt{l=Anno,exps=Ces},St1}. %% block_stmt(Line, Stats, State) -> {Block,Stmte}. block_stmt(Line, Ss0, St0) -> {Ss1,St1} = stmts(Ss0, St0), Anno = line_file_anno(Line, St1), {#block_stmt{l=Anno,body=Ss1},St1}. block(Line, Ss0, St0) -> {Ss1,St1} = stmts(Ss0, St0), {#block{l=Line,body=Ss1},St1}. %% while_stmt(Line, Exp, Block, State) -> {While,State}. while_stmt(Line, Exp, B, St0) -> {Ce,St1} = exp(Exp, St0), {Cb,St2} = block(Line, B, St1), Anno = line_file_anno(Line, St2), {#while_stmt{l=Anno,exp=Ce,body=Cb},St2}. %% repeat_stmt(Line, Block, Exp, State) -> {Repeat,State}. %% Append the test expression into the block as a single value %% expression. repeat_stmt(Line, B, Exp, St0) -> {Cb0,St1} = block(Line, B, St0), {Ce,St2} = expr_stmt(Line, {single,Line,Exp}, St1), Cb1 = Cb0#block{body=Cb0#block.body ++ [Ce]}, Anno = line_file_anno(Line, St2), {#repeat_stmt{l=Anno,body=Cb1},St2}. %% if_stmt(Line, Test, Else, State) -> {If,State}. if_stmt(Line, Tests, Else, St0) -> {Cts,St1} = if_tests(Line, Tests, St0), {Ce,St2} = block(Line, Else, St1), Anno = line_file_anno(Line, St2), {#if_stmt{l=Anno,tests=Cts,else_block=Ce},St2}. if_tests(L, Ts, St) -> Test = fun ({T,B}, S0) -> {Ct,S1} = exp(T, S0), {Cb,S2} = block(L, B, S1), {{Ct,Cb},S2} end, lists:mapfoldl(Test, St, Ts). %% numfor_stmt(Line, Var, Init, Limit, Step, Stmts, State) -> {NumFor,State}. numfor_stmt(Line, {'NAME',Ln,N}, I0, L0, S0, Ss, St0) -> Var = var_name(Ln, N), {[I1,L1,S1],St1} = explist([I0,L0,S0], St0), {B,St2} = block(Line, Ss, St1), Anno = line_file_anno(Line, St2), {#nfor_stmt{l=Anno,var=Var,init=I1,limit=L1,step=S1,body=B},St2}. %% genfor_stmt(Line, Vars, Generators, Stmts, State) -> {GenFor,State}. genfor_stmt(Line, Vs0, Gs0, Ss, St0) -> Vs1 = [ var_name(Ln, N) || {'NAME',Ln,N} <- Vs0 ], {Gs1,St1} = explist(Gs0, St0), {B,St2} = block(Line, Ss, St1), Anno = line_file_anno(Line, St2), {#gfor_stmt{l=Anno,vars=Vs1,gens=Gs1,body=B},St2}. %% fdef_stmt(Line, Name, Pars, Stmts, State) -> {Fdef,State}. %% Transform this to an assign. fdef_stmt(Line, Fname, Ps, B, St0) -> {V,F,St1} = functiondef(Line, Fname, Ps, B, St0), Anno = line_file_anno(Line, St1), {#assign_stmt{l=Anno,vars=[V],exps=[F]},St1}. %% functiondef(FunctionDef, State) -> {CFunc,State}. %% functiondef(Line, Pars, Block, State) -> {CFunc,State}. %% functiondef(Line, Name, Pars, Block, State) -> {Var,CFunc,State}. %% Have to specially handle the case where the function is a %% "method". All this really means is that the function has an extra %% parameter 'self' prepended to the parameter list. functiondef({functiondef,L,Ps,B}, St) -> functiondef(L, Ps, B, St). functiondef(L, Ps, Stmts, St0) -> {Cp,Cb,St1} = function_block(Ps, Stmts, St0), Anno = line_file_anno(L, St1), {#fdef{l=Anno,pars=Cp,body=Cb},St1}. functiondef(L, Name0, Ps0, B, St0) -> %% Check if method and transform method to 'NAME' and add self to vars. case is_method(Name0) of %Export Name1 and Ps1 {yes,Name1} -> Ps1 = [{'NAME',L,<<"self">>}|Ps0]; no -> Name1 = Name0, Ps1 = Ps0 end, {Var,St1} = funcname(Name1, St0), {F0,St2} = functiondef(L, Ps1, B, St1), %% Add the function name to the annotations. Anno = luerl_anno:set(name, flat_funcname(Name1), F0#fdef.l), F1 = F0#fdef{l=Anno}, {Var,F1,St2}. is_method({'NAME',_,_}) -> no; is_method({'.',L,N,Rest0}) -> case is_method(Rest0) of {yes,Rest1} -> {yes,{'.',L,N,Rest1}}; no -> no %No change end; is_method({method,_,{'NAME',_,_}=N}) -> {yes,N}. flat_funcname(Name) -> list_to_binary(flat_funcname(Name, [])). flat_funcname({'NAME',_,N}, Rest) -> [N|Rest]; flat_funcname({'.',_,L,R}, Rest) -> flat_funcname(L, [<<".">>|flat_funcname(R, Rest)]). %% funcname(FuncNameExp, State) -> {CFuncNameExp,State}. funcname({'.',L,Exp,Rest}, St0) -> {Ce,St1} = funcname_first(Exp, St0), {Cr,St2} = funcname_rest(Rest, St1), {dot(L, Ce, Cr),St2}; funcname({'NAME',L,N}, St) -> {var_name(L, N),St}. funcname_first({'NAME',L,N}, St) -> {var_name(L, N),St}. funcname_rest({'.',L,Exp,Rest}, St0) -> {Ce,St1} = funcname_element(Exp, St0), {Cr,St2} = funcname_rest(Rest, St1), {dot(L, Ce, Cr),St2}; funcname_rest(Exp, St) -> funcname_last(Exp, St). funcname_element({'NAME',L,N}, St) -> %% Transform this to key_field with the name string. {#key{l=L,key=lit_name(L, N)},St}. %% Method call has been transformed away funcname_last({'NAME',L,N}, St) -> %% Transform this to key_field with the name string. {#key{l=L,key=lit_name(L, N)},St}. %% local_stmt(Line, Local, State) -> {Assign,State}. %% Create and assign local variables. local_stmt(Line, {functiondef,Lf,Name,Ps,B}, St0) -> {Var,F,St1} = functiondef(Lf, Name, Ps, B, St0), Anno = line_file_anno(Line, St1), {#local_fdef_stmt{l=Anno,var=Var,func=F},St1}; local_stmt(Line, {assign,_,Ns,Es}, St0) -> {Ces,St1} = explist(Es, St0), {Cns,St2} = lists:mapfoldl(fun (V, St) -> var(V, St) end, St1, Ns), Anno = line_file_anno(Line, St2), {#local_assign_stmt{l=Anno,vars=Cns,exps=Ces},St2}. %% expr_stmt(Line, Exp, State) -> {Call,State}. %% The expression pseudo statement. This will return a single value. expr_stmt(Line, Exp, St0) -> {Ce,St1} = exp(Exp, St0), Anno = line_file_anno(Line, St1), {#expr_stmt{l=Anno,exp=Ce},St1}. %% explist(Exprs, State) -> {Ins,State}. %% exp(Expression, State) -> {Ins,State}. explist([E|Es], St0) -> {Ce,St1} = exp(E, St0), {Ces,St2} = explist(Es, St1), {[Ce|Ces],St2}; explist([], St) -> {[],St}. %No expressions at all exp({nil,L}, St) -> {#lit{l=L,val=nil},St}; exp({false,L}, St) -> {#lit{l=L,val=false},St}; exp({true,L}, St) -> {#lit{l=L,val=true},St}; exp({'NUMERAL',L,N}, St) -> {#lit{l=L,val=N},St}; exp({'LITERALSTRING',L,S}, St) -> {#lit{l=L,val=S},St}; exp({'...',L}, St) -> {var_name(L, '...'),St}; %% {#lit{l=L,v='...'},St}; exp({functiondef,L,Ps,B}, St0) -> {Cf,St1} = functiondef(L, Ps, B, St0), {Cf,St1}; exp({table,L,Fs}, St0) -> {Cfs,St1} = tableconstructor(Fs, St0), {#tabcon{l=L,fields=Cfs},St1}; exp({op,L,Op,A1,A2}, St0) -> {Ca1,St1} = exp(A1, St0), {Ca2,St2} = exp(A2, St1), {#op{l=L,op=Op,args=[Ca1,Ca2]},St2}; exp({op,L,Op,A}, St0) -> {Ca,St1} = exp(A, St0), {#op{l=L,op=Op,args=[Ca]},St1}; exp(E, St) -> prefixexp(E, St). %% prefixexp(PrefixExp, State) -> {CPrefixExp,State}. prefixexp({'.',L,Exp,Rest}, St0) -> {Ce,St1} = prefixexp_first(Exp, St0), {Cr,St2} = prefixexp_rest(Rest, St1), {dot(L, Ce, Cr),St2}; prefixexp(P, St) -> prefixexp_first(P, St). prefixexp_first({'NAME',L,N}, St) -> {var_name(L, N),St}; prefixexp_first({single,L,E}, St0) -> {Ce,St1} = exp(E, St0), {#single{l=L,exp=Ce},St1}. prefixexp_rest({'.',L,Exp,Rest}, St0) -> {Ce,St1} = prefixexp_element(Exp, St0), {Cr,St2} = prefixexp_rest(Rest, St1), {dot(L, Ce, Cr),St2}; prefixexp_rest(Exp, St) -> prefixexp_element(Exp, St). prefixexp_element({'NAME',L,N}, St) -> %% Transform this to a key_field with the name string {#key{l=L,key=lit_name(L, N)},St}; prefixexp_element({key_field,L,Exp}, St0) -> {Ce,St1} = exp(Exp, St0), {#key{l=L,key=Ce},St1}; prefixexp_element({functioncall,L,Args}, St0) -> {Cas,St1} = explist(Args, St0), Anno = line_file_anno(L, St1), {#fcall{l=Anno,args=Cas},St1}; prefixexp_element({methodcall,Lm,{'NAME',Ln,N},Args}, St0) -> {Args1,St1} = explist(Args, St0), Anno = line_file_anno(Lm, St1), {#mcall{l=Anno,meth=lit_name(Ln, N),args=Args1},St1}. dot(L, Exp, Rest) -> #dot{l=L,exp=Exp,rest=Rest}. function_block(Pars, Stmts, St0)-> {Cps,St1} = make_local_pars(Pars, St0), {Cs,St2} = stmts(Stmts, St1), %% io:format("fb: ~p\n", [{St3#comp.fs}]), {Cps,Cs,St2}. make_local_pars(Ps, St) -> Add = fun ({'NAME',L,N}, S) -> {var_name(L, N),S}; ({'...',L}, S) -> {var_name(L, '...'),S} end, lists:mapfoldl(Add, St, Ps). %% tableconstrutor(Fields, State) -> {Instrs,State}. %% Build the instructions to construct a table. We could be smarter %% here and recognise already uses keys and only actually insert the %% last one. Or we could pre-order the table elements so the keys are %% already sorted. We can't unpack the last field if it is a multiple %% value efield as this must be done at run-time. tableconstructor(Fs, St0) -> %% N.B. this fun is for a MAPFOLDL!! Fun = fun ({exp_field,L,Ve}, S0) -> {Ce,S1} = exp(Ve, S0), %Value {#efield{l=L,val=Ce},S1}; ({name_field,L,{'NAME',Ln,N},Ve}, S0) -> {Ce,S1} = exp(Ve, S0), %Value {#kfield{l=L,key=lit_name(Ln, N),val=Ce},S1}; ({key_field,L,Ke,Ve}, S0) -> {Ck,S1} = exp(Ke, S0), %Key {Cv,S2} = exp(Ve, S1), %Value {#kfield{l=L,key=Ck,val=Cv},S2} end, {Cfs,St1} = lists:mapfoldl(Fun, St0, Fs), {Cfs,St1}. %% var_name(Line, Name) -> #var{}. %% lit_name(Line, Name) -> #lit{}. lit_name(L, N) -> #lit{l=L,val=N}. var_name(L, N) -> #var{l=L,name=N}. %% line_file_anno(Line, State) -> Anno. %% set_anno(KeyList, Anno) -> Anno. line_file_anno(L, St) -> Anno = luerl_anno:new(L), luerl_anno:set(file, St#cinfo.lfile, Anno). %% set_anno(Ps, Anno) -> %% lists:foldl(fun ({Key,Val}, A) -> luerl_anno:set(Key, Val, A) end, %% Anno, Ps). luerl-1.2.3/src/luerl_parse.yrl0000664000175000017500000002265014677012037017070 0ustar debalancedebalance%% Copyright (c) 2013-2019 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_parse.yrl %% Author : Robert Virding %% Purpose : Parser for LUA 5.2. %% The Grammar rules here are taken directly from the LUA 5.2 %% manual. Unfortunately it is not an LALR(1) grammar but I have %% included a fix by Florian Weimer which makes it %% so, but it needs some after processing. Actually his fix was %% unnecessarily complex and all that was needed was to change one %% rule for statements. Expect 2. %Suppress shift/reduce warning Nonterminals chunk block stats stat semi retstat label_stat while_stat repeat_stat if_stat if_elseif if_else for_stat local_decl funcname dottedname varlist var namelist explist exp prefixexp args functioncall functiondef funcbody parlist tableconstructor fieldlist fields field fieldsep binop unop uminus. Terminals NAME NUMERAL LITERALSTRING 'and' 'break' 'do' 'else' 'elseif' 'end' 'false' 'for' 'function' 'goto' 'if' 'in' 'local' 'nil' 'not' 'or' 'repeat' 'return' 'then' 'true' 'until' 'while' '+' '-' '*' '/' '//' '%' '^' '&' '|' '~' '>>' '<<' '#' '==' '~=' '<=' '>=' '<' '>' '=' '(' ')' '{' '}' '[' ']' '::' ';' ':' ',' '.' '..' '...' . Rootsymbol chunk. %% uminus needed for '-' as it has duplicate precedences. Left 100 'or'. Left 200 'and'. Left 300 '<' '>' '<=' '>=' '~=' '=='. Left 400 '|'. Left 500 '~'. Left 600 '&'. Left 700 '<<' '>>'. Right 800 '..'. Left 900 '+' '-'. Left 1000 '*' '/' '//' '%'. Unary 1100 'not' '#' uminus. Right 1200 '^'. chunk -> block : '$1' . %% block ::= {stat} [retstat] block -> stats : '$1' . block -> stats retstat : '$1' ++ ['$2'] . retstat -> return semi : {return,line('$1'),[]} . retstat -> return explist semi : {return,line('$1'),'$2'} . semi -> ';' . %semi is never returned semi -> '$empty' . stats -> '$empty' : [] . stats -> stats stat : '$1' ++ ['$2'] . stat -> ';' : '$1' . stat -> varlist '=' explist : {assign,line('$2'),'$1','$3'} . %% Following functioncall rule removed to stop reduce-reduce conflict. %% Replaced with a prefixexp which should give the same. We hope! %%stat -> functioncall : '$1' . stat -> prefixexp : check_functioncall('$1') . stat -> label_stat : '$1' . stat -> 'break' : {break,line('$1')} . stat -> 'goto' NAME : {goto,line('$1'),'$2'} . stat -> 'do' block 'end' : {block,line('$1'),'$2'} . stat -> while_stat : '$1' . stat -> repeat_stat : '$1' . stat -> if_stat : '$1' . stat -> for_stat : '$1' . stat -> function funcname funcbody : functiondef(line('$1'),'$2','$3') . stat -> local local_decl : {local,line('$1'),'$2'} . label_stat -> '::' NAME '::' : {label,line('$1'),'$2'} . while_stat -> 'while' exp 'do' block 'end' : {while,line('$1'),'$2','$4'} . repeat_stat -> 'repeat' block 'until' exp : {repeat,line('$1'),'$2','$4'} . %% stat ::= if exp then block {elseif exp then block} [else block] end if_stat -> 'if' exp 'then' block if_elseif if_else 'end' : {'if',line('$1'),[{'$2','$4'}|'$5'],'$6'} . if_elseif -> if_elseif 'elseif' exp 'then' block : '$1' ++ [{'$3','$5'}] . if_elseif -> '$empty' : [] . if_else -> 'else' block : '$2' . if_else -> '$empty' : [] . %An empty block %% stat ::= for Name '=' exp ',' exp [',' exp] do block end %% stat ::= for namelist in explist do block end for_stat -> 'for' NAME '=' explist do block end : numeric_for(line('$1'), '$2', '$4', '$6') . for_stat -> 'for' namelist 'in' explist 'do' block 'end' : generic_for(line('$1'), '$2', '$4', '$6') . %% funcname ::= Name {'.' Name} [':' Name] funcname -> dottedname ':' NAME : dot_append(line('$2'), '$1', {method,line('$2'),'$3'}) . funcname -> dottedname : '$1' . local_decl -> function NAME funcbody : functiondef(line('$1'),'$2','$3') . local_decl -> namelist : {assign,line(hd('$1')),'$1',[]} . local_decl -> namelist '=' explist : {assign,line('$2'),'$1','$3'} . dottedname -> NAME : '$1'. dottedname -> dottedname '.' NAME : dot_append(line('$2'), '$1', '$3') . varlist -> var : ['$1'] . varlist -> varlist ',' var : '$1' ++ ['$3'] . var -> NAME : '$1' . var -> prefixexp '[' exp ']' : dot_append(line('$2'), '$1', {key_field,line('$2'),'$3'}) . var -> prefixexp '.' NAME : dot_append(line('$2'), '$1', '$3') . namelist -> NAME : ['$1'] . namelist -> namelist ',' NAME : '$1' ++ ['$3'] . explist -> exp : ['$1'] . explist -> explist ',' exp : '$1' ++ ['$3'] . exp -> 'nil' : '$1' . exp -> 'false' : '$1' . exp -> 'true' : '$1' . exp -> NUMERAL : '$1' . exp -> LITERALSTRING : '$1' . exp -> '...' : '$1' . exp -> functiondef : '$1' . exp -> prefixexp : '$1' . exp -> tableconstructor : '$1' . exp -> binop : '$1' . exp -> unop : '$1' . prefixexp -> var : '$1' . prefixexp -> functioncall : '$1' . prefixexp -> '(' exp ')' : {single,line('$1'),'$2'} . functioncall -> prefixexp args : dot_append(line('$1'), '$1', {functioncall,line('$1'), '$2'}) . functioncall -> prefixexp ':' NAME args : dot_append(line('$2'), '$1', {methodcall,line('$2'),'$3','$4'}) . args -> '(' ')' : [] . args -> '(' explist ')' : '$2' . args -> tableconstructor : ['$1'] . %Syntactic sugar args -> LITERALSTRING : ['$1'] . %Syntactic sugar functiondef -> 'function' funcbody : functiondef(line('$1'), '$2'). funcbody -> '(' ')' block 'end' : {[],'$3'} . funcbody -> '(' parlist ')' block 'end' : {'$2','$4'} . parlist -> namelist : '$1' . parlist -> namelist ',' '...' : '$1' ++ ['$3'] . parlist -> '...' : ['$1'] . tableconstructor -> '{' '}' : {table,line('$1'),[]} . tableconstructor -> '{' fieldlist '}' : {table,line('$1'),'$2'} . fieldlist -> fields : '$1' . fieldlist -> fields fieldsep : '$1' . fields -> field : ['$1'] . fields -> fields fieldsep field : '$1' ++ ['$3'] . field -> '[' exp ']' '=' exp : {key_field,line('$1'),'$2','$5'} . field -> NAME '=' exp : {name_field,line('$1'),'$1','$3'} . field -> exp : {exp_field,line('$1'),'$1'} . fieldsep -> ',' . fieldsep -> ';' . %% exp ::= exp binop exp %% exp ::= unop exp %% We have to write them these way for the prioriies to work. binop -> exp '+' exp : {op,line('$2'),cat('$2'),'$1','$3'}. binop -> exp '-' exp : {op,line('$2'),cat('$2'),'$1','$3'}. binop -> exp '*' exp : {op,line('$2'),cat('$2'),'$1','$3'}. binop -> exp '/' exp : {op,line('$2'),cat('$2'),'$1','$3'}. binop -> exp '//' exp : {op,line('$2'),cat('$2'),'$1','$3'}. binop -> exp '%' exp : {op,line('$2'),cat('$2'),'$1','$3'}. binop -> exp '^' exp : {op,line('$2'),cat('$2'),'$1','$3'}. binop -> exp '&' exp : {op,line('$2'),cat('$2'),'$1','$3'}. binop -> exp '|' exp : {op,line('$2'),cat('$2'),'$1','$3'}. binop -> exp '~' exp : {op,line('$2'),cat('$2'),'$1','$3'}. binop -> exp '>>' exp : {op,line('$2'),cat('$2'),'$1','$3'}. binop -> exp '<<' exp : {op,line('$2'),cat('$2'),'$1','$3'}. binop -> exp '==' exp : {op,line('$2'),cat('$2'),'$1','$3'}. binop -> exp '~=' exp : {op,line('$2'),cat('$2'),'$1','$3'}. binop -> exp '<=' exp : {op,line('$2'),cat('$2'),'$1','$3'}. binop -> exp '>=' exp : {op,line('$2'),cat('$2'),'$1','$3'}. binop -> exp '<' exp : {op,line('$2'),cat('$2'),'$1','$3'}. binop -> exp '>' exp : {op,line('$2'),cat('$2'),'$1','$3'}. binop -> exp '..' exp : {op,line('$2'),cat('$2'),'$1','$3'}. binop -> exp 'and' exp : {op,line('$2'),cat('$2'),'$1','$3'}. binop -> exp 'or' exp : {op,line('$2'),cat('$2'),'$1','$3'}. unop -> 'not' exp : {op,line('$1'),cat('$1'),'$2'} . unop -> '#' exp : {op,line('$1'),cat('$1'),'$2'} . unop -> '~' exp : {op,line('$1'),cat('$1'),'$2'} . unop -> uminus : '$1' . uminus -> '-' exp : {op,line('$1'),'-','$2'} . Erlang code. -export([chunk/1]). %% chunk(Tokens) -> FunctionDef | Error. %% Return the parse as a callable nameless function definition. chunk(Ts) -> case parse(Ts) of {error,_}=Error -> Error; {ok,Body} -> {ok,{functiondef,1,[{'...',1}],Body}} end. cat(T) -> element(1, T). line(T) -> element(2, T). %% numeric_for(Line, LoopVar, [Init,Test,Upd], Block). numeric_for(Line, Var, [Init,Limit], Block) -> {for,Line,Var,Init,Limit,Block}; numeric_for(Line, Var, [Init,Limit,Step], Block) -> {for,Line,Var,Init,Limit,Step,Block}; numeric_for(Line, _, _, _) -> %Wrong number of expressions return_error(Line, "illegal for"). %% generic_for(Line, Names, ExpList, Block). generic_for(Line, Names, Exps, Block) -> {for,Line,Names,Exps,Block}. %% functiondef(Line, Name, {Parameters,Body}). %% functiondef(Line, {Parameters,Body}). functiondef(Line, Name, {Pars,Body}) -> {functiondef,Line,Name,Pars,Body}. functiondef(Line, {Pars,Body}) -> {functiondef,Line,Pars,Body}. %% dot_append(Line, DotList, Last) -> DotList. %% Append Last to the end of a dotlist. dot_append(Line, {'.',L,H,T}, Last) -> {'.',L,H,dot_append(Line, T, Last)}; dot_append(Line, H, Last) -> {'.',Line,H,Last}. %% check_functioncall(PrefixExp) -> PrefixExp. %% Check that the PrefixExp is a proper function call/method. check_functioncall({functioncall,_,_}=C) -> C; check_functioncall({methodcall,_,_,_}=M) -> M; check_functioncall({'.',L,H,T}) -> {'.',L,H,check_functioncall(T)}; check_functioncall(Other) -> return_error(line(Other),"illegal call"). luerl-1.2.3/src/luerl_comp_vars.erl0000664000175000017500000003217714677012037017730 0ustar debalancedebalance%% Copyright (c) 2013 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_comp_vars.erl %% Author : Robert Virding %% Purpose : A basic LUA 5.3 compiler for Luerl. %% Does variable and stack analysis in the compiler -module(luerl_comp_vars). -include("luerl.hrl"). -include("luerl_comp.hrl"). -export([chunk/2]). -import(ordsets, [add_element/2,del_element/2,is_element/2, union/1,union/2,subtract/2,intersection/2]). %% chunk(Code, CompInfo) -> {ok,Code}. chunk(Code0, #cinfo{opts=Opts}=_Ci) -> %% No local state here! {Code1,_,_,nul} = functiondef(Code0, [], nul), luerl_comp:debug_print(Opts, "cv: ~p\n", [Code1]), {ok,Code1}. %% stmts(Stmts, VarData, State) -> %% {Stmts,NewVarData,State}. %% Main problem here is to calculate local/free/used variables in the %% right order. Must do everything going forwards. stmts([S0|Ss0], Vars0, St0) -> {S1,New,Used,Fused,St1} = stmt(S0, nul, St0), Vars1 = update_vars(Vars0, New, Used, Fused), %% io:format("ss1: ~p\n", [Vars0]), %% io:format("ss1> ~p\n", [{New,Used,Fused}]), %% io:format("ss1> ~p\n", [Vars1]), {Ss1,Vars2,St2} = stmts(Ss0, Vars1, St1), {[S1|Ss1],Vars2,St2}; stmts([], Vars, St) -> {[],Vars,St}. update_vars(#vars{local=Lo,free=Fr,used=Us,fused=Fu}, New, Used, Fused) -> Aused = union(Used, Fused), %All used Free = subtract(Aused, Lo), #vars{local=union(New, Lo), free=union(Free, Fr), used=union(Used, Us), fused=union(Fused, Fu)}. %% stmt(Stmt, LocalVars, State) -> {Stmt,NewVars,UsedVars,FusedVars,State}. stmt(#assign_stmt{}=A, Loc, St) -> assign_stmt(A, Loc, St); stmt(#call_stmt{}=C, Loc, St) -> call_stmt(C, Loc, St); stmt(#return_stmt{}=R, Loc, St) -> return_stmt(R, Loc, St); stmt(#break_stmt{}=B, _, St) -> {B,[],[],[],St}; stmt(#block_stmt{}=B, Loc, St) -> block_stmt(B, Loc, St); stmt(#while_stmt{}=W, Loc, St) -> while_stmt(W, Loc, St); stmt(#repeat_stmt{}=R, Loc, St) -> repeat_stmt(R, Loc, St); stmt(#if_stmt{}=If, Loc, St) -> if_stmt(If, Loc, St); stmt(#nfor_stmt{}=For, Loc, St) -> numfor_stmt(For, Loc, St); stmt(#gfor_stmt{}=For, Loc, St) -> genfor_stmt(For, Loc, St); stmt(#local_assign_stmt{}=L, Loc, St) -> local_assign_stmt(L, Loc, St); stmt(#local_fdef_stmt{}=L, Loc, St) -> local_fdef_stmt(L, Loc, St); stmt(#expr_stmt{}=E, Loc, St) -> %Expressions "statement" expr_stmt(E, Loc, St). %% assign_stmt(Assign, LocalVars, State) -> %% {Assign,NewVars,UsedVars,FusedVars,State}. assign_stmt(#assign_stmt{vars=Vs0,exps=Es0}=A, Loc, St0) -> {Vs1,Vused,Vfused,St1} = assign_loop(Vs0, Loc, St0), {Es1,Eused,Efused,St2} = explist(Es0, Loc, St1), Used = union(Vused, Eused), Fused = union(Vfused, Efused), {A#assign_stmt{vars=Vs1,exps=Es1},[],Used,Fused,St2}. assign_loop([V0|Vs0], Loc, St0) -> {V1,Vused,Vfused,St1} = var(V0, Loc, St0), {Vs1,Vsused,Vsfused,St2} = assign_loop(Vs0, Loc, St1), Used = union(Vused, Vsused), Fused = union(Vfused, Vsfused), {[V1|Vs1],Used,Fused,St2}; assign_loop([], _, St) -> {[],[],[],St}. var(#dot{exp=Exp0,rest=Rest0}=D, Loc, St0) -> {Exp1,Eused,Efused,St1} = prefixexp_first(Exp0, Loc, St0), {Rest1,Rused,Rfused,St2} = var_rest(Rest0, Loc, St1), Used = union(Eused, Rused), Fused = union(Efused, Rfused), {D#dot{exp=Exp1,rest=Rest1},Used,Fused,St2}; var(#var{name=N}=V, _, St) -> {V,[N],[],St}. var_rest(#dot{exp=Exp0,rest=Rest0}=D, Loc, St0) -> {Exp1,Eused,Efused,St1} = prefixexp_element(Exp0, Loc, St0), {Rest1,Rused,Rfused,St2} = var_rest(Rest0, Loc, St1), Used = union(Eused, Rused), Fused = union(Efused, Rfused), {D#dot{exp=Exp1,rest=Rest1},Used,Fused,St2}; var_rest(Exp, Loc, St) -> var_last(Exp, Loc, St). var_last(#key{key=Exp0}=K, Loc, St0) -> {Exp1,Used,Fused,St1} = exp(Exp0, Loc, St0), {K#key{key=Exp1},Used,Fused,St1}. %% call_stmt(Call, LocalVars, State) -> %% {Call,NewVars,UsedVars,FusedVars,State}. call_stmt(#call_stmt{call=Exp0}=C, Loc, St0) -> {Exp1,Used,Fused,St1} = exp(Exp0, Loc, St0), {C#call_stmt{call=Exp1},[],Used,Fused,St1}. %% return_stmt(Return, LocalVars, State) -> %% {Return,NewVars,UsedVars,FusedVars,State}. return_stmt(#return_stmt{exps=Es0}=R, Loc, St0) -> {Es1,Used,Fused,St1} = explist(Es0, Loc, St0), {R#return_stmt{exps=Es1},[],Used,Fused,St1}. %% block_stmt(Block, LocalVars, State) -> %% {Block,NewVars,UsedVars,FusedVars,State}. block_stmt(#block_stmt{body=Ss0}=B, _, St0) -> Vars0 = #vars{local=[],free=[],used=[],fused=[]}, {Ss1,Vars1,St1} = stmts(Ss0, Vars0, St0), %% Be careful what we export, adjust Used and Fused for locals. #vars{local=Bloc,used=Bused,fused=Bfused} = Vars1, Used = subtract(Bused, Bloc), Fused = subtract(Bfused, Bloc), {B#block_stmt{body=Ss1,vars=Vars1},[],Used,Fused,St1}. %% do_block(Block, State) -> {Block,UsedVars,FusedVars,State}. %% do_block(Block, LocalVars, State) -> {Block,UsedVars,FusedVars,State}. %% Do_block never returns external new variables as it never exports %% variables. do_block(B, St) -> do_block(B, [], St). do_block(#block{body=Ss0}=B, Loc, St0) -> Vars0 = #vars{local=Loc,free=[],used=[],fused=[]}, {Ss1,Vars1,St1} = stmts(Ss0, Vars0, St0), %% Be careful what we export, adjust Used and Fused for locals. #vars{local=Bloc,used=Bused,fused=Bfused} = Vars1, Used = subtract(Bused, Bloc), Fused = subtract(Bfused, Bloc), {B#block{body=Ss1,vars=Vars1},Used,Fused,St1}. %% while_stmt(While, LocalVars, State) -> %% {While,NewVars,UsedVars,FusedVars,State}. %% While_stmt never returns external new variables. The test %% expression is done in the context of the surrounding block. while_stmt(#while_stmt{exp=E0,body=B0}=W, Loc, St0) -> {E1,Eused,Efused,St1} = exp(E0, Loc, St0), {B1,Bused,Bfused,St2} = do_block(B0, St1), Used = union(Eused, Bused), Fused = union(Efused, Bfused), {W#while_stmt{exp=E1,body=B1},[],Used,Fused,St2}. %% repeat_stmt(Repeat, LocalVars, State) -> %% {Repeat,NewVars,UsedVars,FusedVars,State}. %% Repeat_stmt never returns external new variables. The test %% expression is done in the context of the repeat block and is %% already inside the block. repeat_stmt(#repeat_stmt{body=B0}=R, _, St0) -> {B1,Used,Fused,St1} = do_block(B0, St0), {R#repeat_stmt{body=B1},[],Used,Fused,St1}. %% if_stmt(If, LocalVars, State) -> {If,NewVars,FreeVars,State}. %% The block info includes anything from the test expressions even %% though we keep them separate. if_stmt(#if_stmt{tests=Ts0,else_block=E0}=If, Loc, St0) -> {Ts1,Tused,Tfused,St1} = if_tests(Ts0, Loc, St0), {E1,Eused,Efused,St2} = do_block(E0, St1), Used = union(Tused, Eused), Fused = union(Tfused, Efused), {If#if_stmt{tests=Ts1,else_block=E1},[],Used,Fused,St2}. if_tests([{E0,B0}|Ts0], Loc, St0) -> {E1,Eused,Efused,St1} = exp(E0, Loc, St0), {B1,Bused,Bfused,St2} = do_block(B0, St1), {Ts1,Tsused,Tsfused,St3} = if_tests(Ts0, Loc, St2), Used = union([Eused,Bused,Tsused]), Fused = union([Efused,Bfused,Tsfused]), {[{E1,B1}|Ts1],Used,Fused,St3}; if_tests([], _, St) -> {[],[],[],St}. %% numfor_stmt(For, LocalVars, State) -> %% {For,NewVars,UsedVars,FusedVars,State}. numfor_stmt(#nfor_stmt{var=#var{name=N},init=I0,limit=L0,step=S0,body=B0}=For, Loc, St0) -> {[I1,L1,S1],Esused,Esfused,St1} = explist([I0,L0,S0], Loc, St0), {B1,Bused,Bfused,St2} = do_block(B0, [N], St1), %% Be careful what we export, adjust Used and Fused for N. Used = union(Esused, del_element(N, Bused)), Fused = union(Esfused, del_element(N, Bfused)), {For#nfor_stmt{init=I1,limit=L1,step=S1,body=B1},[],Used,Fused,St2}. %% genfor_stmt(For, LocalVars, State) -> {For,NewVars,FreeVars,State}. genfor_stmt(#gfor_stmt{vars=Vs,gens=Gs0,body=B0}=For, Loc, St0) -> {Gs1,Gused,Gfused,St1} = explist(Gs0, Loc, St0), Ns = lists:foldl(fun (#var{name=N}, Ns) -> add_element(N, Ns) end, [], Vs), {B1,Bused,Bfused,St2} = do_block(B0, Ns, St1), %% Be careful what we export, adjust Used and Fused for Ns. Used = union(Gused, subtract(Bused, Ns)), Fused = union(Gfused, subtract(Bfused, Ns)), {For#gfor_stmt{gens=Gs1,body=B1},[],Used,Fused,St2}. %% local_assign_stmt(Local, LocalVars, State) -> {Local,NewVars,FreeVars,State}. local_assign_stmt(#local_assign_stmt{vars=Vs,exps=Es0}=L, Loc, St0) -> {Es1,Used,Fused,St1} = explist(Es0, Loc, St0), New = lists:foldl(fun (#var{name=N}, Ns) -> add_element(N, Ns) end, [], Vs), {L#local_assign_stmt{exps=Es1},New,Used,Fused,St1}. %% local_fdef_stmt(Local, LocalVars, State) -> %% {Local,NewVars,FreeVars,UsedVars,State}. %% We explicitly handle used variables here as we want the function %% name to be included in Used in recursive function calls. local_fdef_stmt(#local_fdef_stmt{var=#var{name=N},func=F0}=L, _, St0) -> {F1,Used,Fused,St1} = functiondef(F0, nul, St0), New = [N], {L#local_fdef_stmt{func=F1},New,Used,Fused,St1}. %% exp_stmt(Expr, LocalVars, State) -> %% {Expr,NewVars,UsedVars,FusedVars,State}. %% This will return a single value. expr_stmt(#expr_stmt{exp=Exp0}=E, Loc, St0) -> {Exp1,Used,Fused,St1} = exp(Exp0, Loc, St0), {E#expr_stmt{exp=Exp1},[],Used,Fused,St1}. %% explist(Exprs, LocalVars, State) -> {Exprs,UsedVars,FusedVars,State}. %% exp(Expr, LocalVars, State) -> {Expr,UsedVars,FusedVars,State}. %% prefixexp(Expr, LocalVars, State) -> {Expr,UsedVars,FusedVars,State}. %% An expression can never create new local variables. explist([E0|Es0], Loc, St0) -> {E1,Eused,Efused,St1} = exp(E0, Loc, St0), {Es1,Esused,Esfused,St2} = explist(Es0, Loc, St1), Used = union(Eused, Esused), Fused = union(Efused, Esfused), {[E1|Es1],Used,Fused,St2}; explist([], _, St) -> {[],[],[],St}. %No expressions at all exp(#lit{}=L, _, St) -> {L,[],[],St}; %Nothing to do exp(#fdef{}=F, _, St) -> functiondef(F, nul, St); exp(#op{args=Es0}=Op, Loc, St0) -> {Es1,Used,Fused,St1} = explist(Es0, Loc, St0), {Op#op{args=Es1},Used,Fused,St1}; exp(#tabcon{fields=Fs0}=T, Loc, St0) -> {Fs1,Used,Fused,St1} = tableconstructor(Fs0, Loc, St0), {T#tabcon{fields=Fs1},Used,Fused,St1}; exp(E, Loc, St) -> prefixexp(E, Loc, St). prefixexp(#dot{exp=Exp0,rest=Rest0}=D, Loc, St0) -> {Exp1,Eused,Efused,St1} = prefixexp_first(Exp0, Loc, St0), {Rest1,Rused,Rfused,St2} = prefixexp_rest(Rest0, Loc, St1), Used = union(Eused, Rused), Fused = union(Efused, Rfused), {D#dot{exp=Exp1,rest=Rest1},Used,Fused,St2}; prefixexp(Exp, Loc, St) -> prefixexp_first(Exp, Loc, St). prefixexp_first(#single{exp=E0}=S, Loc, St0) -> {E1,Used,Fused,St1} = exp(E0, Loc, St0), {S#single{exp=E1},Used,Fused,St1}; prefixexp_first(#var{name=N}=V, _, St) -> {V,[N],[],St}. prefixexp_rest(#dot{exp=Exp0,rest=Rest0}=D, Loc, St0) -> {Exp1,Eused,Efused,St1} = prefixexp_element(Exp0, Loc, St0), {Rest1,Rused,Rfused,St2} = prefixexp_rest(Rest0, Loc, St1), Used = union(Eused, Rused), Fused = union(Efused, Rfused), {D#dot{exp=Exp1,rest=Rest1},Used,Fused,St2}; prefixexp_rest(Exp, Loc, St) -> prefixexp_element(Exp, Loc, St). prefixexp_element(#key{key=E0}=K, Loc, St0) -> {E1,Used,Fused,St1} = exp(E0, Loc, St0), {K#key{key=E1},Used,Fused,St1}; prefixexp_element(#fcall{args=As0}=F, Loc, St0) -> {As1,Used,Fused,St1} = explist(As0, Loc, St0), {F#fcall{args=As1},Used,Fused,St1}; prefixexp_element(#mcall{meth=#lit{val=N},args=As0}=M, Loc, St0) -> {As1,Used,Fused,St1} = explist(As0, Loc, St0), {M#mcall{args=As1},add_element(N, Used),Fused,St1}. %% functiondef(Func, LocalVars, State) -> {Func,UsedVars,FusedVars,State}. %% All the variables "used" in the function which are not local %% become "fused" externally. functiondef(#fdef{pars=Ps,body=Ss0}=F, _, St0) -> Loc0 = lists:foldl(fun (#var{name=N}, Vs) -> add_element(N, Vs); (_, Vs) -> Vs end, [], Ps), Vars0 = #vars{local=Loc0,free=[],used=[],fused=[]}, {Ss1,Vars1,St1} = stmts(Ss0, Vars0, St0), %% Make all free variables "fused" in outside block. {F#fdef{body=Ss1,vars=Vars1},[],Vars1#vars.free,St1}. %% tableconstructor(Fields, LocalVars, State) -> %% {Fields,UsedVars,FusedVars,State}. tableconstructor(Fs0, Loc, St0) -> Fun = fun (#efield{val=V0}=F, {Used0,Fused0,S0}) -> {V1,Vused,Vfused,S1} = exp(V0, Loc, S0), Used1 = union(Vused, Used0), Fused1 = union(Vfused, Fused0), {F#efield{val=V1},{Used1,Fused1,S1}}; (#kfield{key=K0,val=V0}=F, {Used0,Fused0,S0}) -> {K1,Kused,Kfused,S1} = exp(K0, Loc, S0), {V1,Vused,Vfused,S2} = exp(V0, Loc, S1), Used1 = union([Kused,Vused,Used0]), Fused1 = union([Kfused,Vfused,Fused0]), {F#kfield{key=K1,val=V1},{Used1,Fused1,S2}} end, {Fs1,{Used,Fused,St1}} = lists:mapfoldl(Fun, {[],[],St0}, Fs0), {Fs1,Used,Fused,St1}. luerl-1.2.3/src/luerl_lib_io.erl0000664000175000017500000000254514677012037017170 0ustar debalancedebalance%% Copyright (c) 2013-2020 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_lib_io.erl %% Author : Robert Virding %% Purpose : The io library for Luerl. %% This is a quick hack to get io working. It will be improved in time. -module(luerl_lib_io). -include("luerl.hrl"). -export([install/1,flush/3,write/3]). -import(luerl_lib, [lua_error/2,badarg_error/3]). %Shorten this install(St) -> luerl_heap:alloc_table(table(), St). %% table() -> [{FuncName,Function}]. table() -> [{<<"flush">>,#erl_mfa{m=?MODULE,f=flush}}, {<<"write">>,#erl_mfa{m=?MODULE,f=write}} ]. flush(_, _, St) -> {[true],St}. write(_, As, St) -> case luerl_lib:args_to_strings(As) of error -> badarg_error(write, As, St); Ss -> lists:foreach(fun (S) -> io:format("~s", [S]) end, Ss), {[#userdata{d=standard_io}],St} end. luerl-1.2.3/src/luerl_lib.erl0000664000175000017500000002615514677012037016504 0ustar debalancedebalance%% Copyright (c) 2013-2024 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_lib.erl %% Author : Robert Virding %% Purpose : Luerl libraries. %% A collection of useful functions. Those with '_' in their names %% generate Erlang data types while those with generate Lua data types %% (floats and binaries). -module(luerl_lib). -include("luerl.hrl"). -export([lua_error/2,badarg_error/3,badarith_error/3,format_error/1, format_value/1]). -export([boolean_value/1,first_value/1]). -export([number_to_list/1]). -export([arg_to_list/1,args_to_lists/1,args_to_lists/2]). -export([arg_to_number/1,arg_to_number/2,args_to_numbers/1,args_to_numbers/2]). -export([arg_to_integer/1,args_to_integers/1,args_to_integers/2]). -export([arg_to_float/1,args_to_floats/1,args_to_floats/2]). -export([arg_to_string/1,args_to_strings/1,args_to_strings/2]). -export([conv_list/2,conv_list/3]). -spec lua_error(_,_) -> no_return(). -spec badarg_error(_,_,_) -> no_return(). lua_error(E, St) -> error({lua_error,E,St}). badarg_error(What, Args, St) -> lua_error({badarg,What,Args}, St). badarith_error(What, Args, St) -> lua_error({badarith,What,Args}, St). %% format_error(LuaError) -> ErrorString. %% The ErrorString is a UTF-8 encoded binary. The UTF-8 encoded %% codepoints can come from Lua/Luerl strings. Some of these use %% same text as Lua error string, so be careful if modifying them. format_error({badarg,Where,Args}) -> %% Note Args is a list which must be kept as its own list! format_error("bad argument ~ts to ~ts", [Args,Where]); format_error({badarith,Op,Args}) -> %% Note Args is a list which must be kept as its own list! format_error("bad arithmetic ~ts on ~ts", [Op,Args]); format_error({illegal_index,Where,Index}) -> format_error("invalid index in ~ts: ~ts", [Where,Index]); format_error({illegal_value,Where,Val}) -> format_error("invalid value in ~ts: ~ts", [Where,Val]); format_error({illegal_value,Val}) -> format_error("invalid value: ~ts", [Val]); format_error({illegal_comp,Where}) -> Msg = io_lib:format("illegal comparison in ~ts", [Where]), unicode:characters_to_binary(Msg); %% format_error({invalid_order,Where}) -> %Keep text! %% io_lib:format("invalid order function in ~w", [Where]); format_error({undefined_function,Name}) -> format_error("undefined function ~ts", [Name]); format_error({undefined_method,Object,Name}) -> format_error("undefined method ~ts in ~ts", [Name,Object]); format_error(illegal_return_value) -> <<"illegal format of return value">>; %% Pattern errors. format_error(invalid_pattern) -> %Keep text! <<"malformed pattern">>; format_error(invalid_capture) -> %Keep text! <<"malformed pattern">>; format_error({invalid_char_class,C}) -> %Keep text! Msg = io_lib:format("malformed pattern (class ~c)", [C]), unicode:characters_to_binary(Msg); format_error(invalid_char_set) -> %Keep text! <<"malformed pattern (missing ']')">>; %% Illegal or undefined ops. format_error({illegal_op,Op}) -> format_error("illegal op: ~ts", [Op]); format_error({no_module,Mod}) -> %% We know the module name is an atom. Msg = io_lib:format("module '~s' not found", [Mod]), unicode:characters_to_binary(Msg); %% Assertions format_error({assert_error,Obj}) -> if is_binary(Obj) -> <>; true -> Type = luerl_lib_basic:type(Obj), <<"error object is a ",Type/binary,$!>> end; %% We have an error message here already. format_error({error_message,Msg}) -> Msg; %% Error is called. format_error({error_call,Args}) -> format_error_call(Args); %% Everything we don't recognise or know about. format_error(Error) -> unicode:characters_to_binary(io_lib:format(<<"~w!">>, [Error])). %% format_error_call(Args) -> ErrorString. %% Just get it more or less equivalent to what Lua does. format_error_call([A|_]) when is_binary(A) -> A; format_error_call([A|_]) when is_number(A) -> iolist_to_binary(format_value(A)); format_error_call(Args) -> Type = case Args of [A|_] -> luerl_lib_basic:type(A); [] -> <<"nil">> end, <<"error object is a ",Type/binary," value">>. %% format_error(FormatString, Values) -> ErrorString. %% Useful when all the values in the list need to be formatted %% separately and will be output separately. format_error(Format, Vals) -> Ps = lists:map(fun format_value/1, Vals), unicode:characters_to_binary(io_lib:format(Format, Ps)). %% format_value(LuerlData) -> Iolist. %% Take an Luerl data and return a "printable" representation suitable %% to use when printing error messages. format_value(nil) -> <<"nil">>; format_value(true) -> <<"true">>; format_value(false) -> <<"false">>; format_value(N) when is_number(N) -> io_lib:write(N); format_value(B) when is_binary(B) -> %% A luerl string which we print with quotes around it. %% Note that the string can contain unicode codepoints. [$\',B,$\']; format_value(#tref{}) -> <<"table">>; format_value(#usdref{}) -> <<"userdata">>; format_value(#funref{}) -> <<"function">>; format_value(#erl_func{code=Fun}) -> {name,Name} = erlang:fun_info(Fun, name), atom_to_binary(Name, utf8); format_value(#erl_mfa{f=Func}) -> atom_to_binary(Func, utf8); format_value(List) when is_list(List) -> Pl = lists:map(fun format_value/1, List), lists:join($\,, Pl); %% Treat atoms as binary strings here, probably just a name. format_value(A) when is_atom(A) -> [$\',atom_to_binary(A, utf8),$\']; %% Everything else just straight through. format_value(_Other) -> <<"unknown stuff">>. %% boolean_value(Rets) -> boolean(). %% first_value(Rets) -> Value | nil. %% Test first value of return list. boolean_value([V|_]) -> ?IS_TRUE(V); boolean_value([]) -> false. first_value([V|_]) -> V; first_value([]) -> nil. %% bin_to_number(Binary) -> {ok,Number} | error. %% str_to_number(String) -> {ok,Number} | error. %% Use the scanner to process all allowed number syntaxes. bin_to_number(B) -> str_to_number(binary_to_list(B)). str_to_number(S) -> case luerl_scan:string(S) of {ok,[{'NUMERAL',_,N}],_} -> {ok,N}; {ok,[{'+',_},{'NUMERAL',_,N}],_} -> {ok,N}; {ok,[{'-',_},{'NUMERAL',_,N}],_} -> {ok,-N}; _ -> error end. number_to_list(N) -> io_lib:write(N). %% case ?IS_FLOAT_INT(N, I) of %Is it an "integer"? %% true -> integer_to_list(I); %% false -> io_lib:write(N) %% end. %% arg_to_list(Arg) -> List | 'error'. %% args_to_lists(Args) -> Lists | 'error'. %% args_to_lists(Args, Acc) -> Lists | 'error'. arg_to_list(N) when is_number(N) -> number_to_list(N); arg_to_list(B) when is_binary(B) -> binary_to_list(B); arg_to_list(_) -> error. args_to_lists(As) -> args_to_lists(As, []). args_to_lists(As, Acc) -> to_loop(As, fun arg_to_list/1, Acc). %% arg_to_number(Arg) -> Number | error. %% arg_to_number(Arg, Base) -> Number | error. %% args_to_numbers(Args) -> Numbers | 'error'. %% args_to_numbers(Arg, Arg) -> Numbers | 'error'. %% Strings always result in floats. %% Arg_to_number/2 only generates "integers". Lua does it like that. arg_to_number(N) when is_number(N) -> N; arg_to_number(B) when is_binary(B) -> case bin_to_number(B) of {ok,N} -> float(N); error -> error end; arg_to_number(_) -> error. arg_to_number(A, B) -> case conv_list([A,B], [erl_list,lua_integer]) of [N0,Base] -> case catch begin [N1] = string:tokens(N0, [9,10,11,12,13,32,160]), {ok,list_to_integer(N1, Base)} end of {ok,I} -> float(I); _ -> error end end. %% arg_to_number(A, B) -> %% case args_to_numbers([A,B]) of %% [N1,N2] when ?IS_FLOAT_INT(N1) -> %% N1 * math:pow(10,N2); %% error -> error %% end. args_to_numbers(A1, A2) -> case luerl_lib:arg_to_number(A1) of error -> error; N1 -> case luerl_lib:arg_to_number(A2) of error -> error; N2 -> [N1,N2] end end. args_to_numbers(As) -> to_loop(As, fun arg_to_number/1, []). %% arg_to_integer(Arg) -> Integer | 'error'. %% args_to_integers(Args) -> Integers | 'error'. %% args_to_integers(Arg, Arg) -> Integers | 'error'. %% Convert arguments to rounded integers. arg_to_integer(A) -> case arg_to_number(A) of N when is_integer(N) -> N; N when ?IS_FLOAT_INT(N) -> round(N); _Other -> error %Other floats are bad here end. args_to_integers(A1, A2) -> case arg_to_integer(A1) of error -> error; N1 -> case arg_to_integer(A2) of error -> error; N2 -> [N1,N2] end end. args_to_integers(As) -> to_loop(As, fun arg_to_integer/1, []). %% arg_to_float(Arg) -> Float | 'error'. %% args_to_floats(Args) -> Floats | 'error'. %% args_to_floats(Arg, Arg) -> Floats | 'error'. %% Convert arguments to rounded floats. arg_to_float(A) -> case arg_to_number(A) of N when is_integer(N) -> float(N); N when is_float(N) -> N; _Other -> error end. args_to_floats(A1, A2) -> case arg_to_float(A1) of error -> error; N1 -> case arg_to_float(A2) of error -> error; N2 -> [N1,N2] end end. args_to_floats(As) -> to_loop(As, fun arg_to_float/1, []). %% arg_to_string(Arg) -> String | error. %% arg_to_strings(Args) -> Strings | error. %% arg_to_strings(Arg, Arg) -> Strings | error. arg_to_string(N) when is_number(N) -> list_to_binary(number_to_list(N)); arg_to_string(B) when is_binary(B) -> B; arg_to_string(_) -> error. args_to_strings(As) -> args_to_strings(As, []). args_to_strings(As, Acc) -> to_loop(As, fun arg_to_string/1, Acc). %% to_loop(List, Convert, Acc) -> List | 'error'. %% Step over list using foldl and return list or 'error'. We assume %% the list won't be very long so appending is ok. to_loop([A|As], Fun, Acc) -> case Fun(A) of error -> error; %Terminate on error E -> to_loop(As, Fun, Acc ++ [E]) end; to_loop([], _Fun, Acc) -> Acc. %% conv_list(Args, ToTypes) -> List | 'error'. %% conv_list(Args, ToTypes, Done) -> List | 'error'. %% Basically a type driven foldl where we return a list or 'error'. conv_list(As, Tos) -> conv_list(As, Tos, []). conv_list(_, _, error) -> error; %Propagate error conv_list([A|As], [To|Tos], Rs) -> %% Get the right value. Ret = case To of %% Erlang types. erl_list -> arg_to_list(A); erl_string -> arg_to_list(A); %% Lua types. lua_any -> A; lua_integer -> arg_to_integer(A); lua_number -> arg_to_number(A); lua_string -> arg_to_string(A); lua_bool -> ?IS_TRUE(A) end, case Ret of error -> error; %Return error Ret -> conv_list(As, Tos, [Ret|Rs]) end; conv_list([], _, Rs) -> lists:reverse(Rs); %No more arguments, done conv_list(_, [], Rs) -> lists:reverse(Rs). %No more conversions, done luerl-1.2.3/src/luerl_lib_math.erl0000664000175000017500000002732314677012037017513 0ustar debalancedebalance%% Copyright (c) 2013-2020 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_lib_math.erl %% Author : Robert Virding %% Purpose : The math library for Luerl. %% We try to mirror the handling of arguments which occurs in the Lua %% math module. Many functions allow extra arguments but only look at %% the first required ones of the right type and completely ignore the %% rest. %% %% We keep atan2, cosh, sinh tanh, pow, frexp and ldexp even though %% have been deprecated. -module(luerl_lib_math). -include("luerl.hrl"). -export([install/1,abs/3,acos/3,asin/3,atan2/3,atan/3,ceil/3,cos/3,cosh/3,deg/3,exp/3,floor/3, fmod/3,frexp/3,ldexp/3,log/3,log10/3,max/3,min/3,modf/3,pow/3,rad/3,random/3,randomseed/3, sin/3,sinh/3,sqrt/3,tan/3,tanh/3,tointeger/3,type/3]). -export([internalize/1,externalize/1]). -import(luerl_lib, [lua_error/2,badarg_error/3]). %Shorten this %% Use the correct random number module. -ifdef(NEW_RAND). -define(RAND_UNIFORM(S), rand:uniform_s(S)). -define(RAND_UNIFORM(L, S), rand:uniform_s(L, S)). -define(RAND_SEED(), rand:seed_s(exs1024)). -define(RAND_SEED(S1,S2,S3), rand:seed_s(exs1024, {S1,S2,S3})). -define(RAND_EXTERNALIZE(S), rand_externalize(S)). -define(RAND_INTERNALIZE(S), rand_internalize(S)). -else. -define(RAND_UNIFORM(S), random:uniform_s(S)). -define(RAND_UNIFORM(L, S), random:uniform_s(L, S)). -define(RAND_SEED(), random:seed0()). -define(RAND_SEED(S1,S2,S3), %Naughty, copied from source {(abs(S1) rem (30269-1) + 1), %PRIME1 (abs(S2) rem (30307-1) + 1), %PRIME2 (abs(S3) rem (30323-1) + 1)}). %PRIME3 -define(RAND_EXTERNALIZE(S), S). % random has just three integers for state so no special work needed. -define(RAND_INTERNALIZE(S), S). -endif. install(St0) -> St1 = St0#luerl{rand=?RAND_SEED()}, %Default initial random seed luerl_heap:alloc_table(table(), St1). table() -> [{<<"abs">>,#erl_mfa{m=?MODULE,f=abs}}, {<<"acos">>,#erl_mfa{m=?MODULE,f=acos}}, {<<"asin">>,#erl_mfa{m=?MODULE,f=asin}}, {<<"atan">>,#erl_mfa{m=?MODULE,f=atan}}, {<<"atan2">>,#erl_mfa{m=?MODULE,f=atan2}}, %For 5.2 backwards compatibility {<<"ceil">>,#erl_mfa{m=?MODULE,f=ceil}}, {<<"cos">>,#erl_mfa{m=?MODULE,f=cos}}, {<<"cosh">>,#erl_mfa{m=?MODULE,f=cosh}}, %For 5.2 backwards compatibility {<<"deg">>,#erl_mfa{m=?MODULE,f=deg}}, {<<"exp">>,#erl_mfa{m=?MODULE,f=exp}}, {<<"floor">>,#erl_mfa{m=?MODULE,f=floor}}, {<<"fmod">>,#erl_mfa{m=?MODULE,f=fmod}}, {<<"frexp">>,#erl_mfa{m=?MODULE,f=frexp}}, %For 5.2 backwards compatibility {<<"huge">>,1.7976931348623157e308}, %From the specs {<<"ldexp">>,#erl_mfa{m=?MODULE,f=ldexp}}, %For 5.2 backwards compatibility {<<"log">>,#erl_mfa{m=?MODULE,f=log}}, {<<"log10">>,#erl_mfa{m=?MODULE,f=log10}}, %For 5.1 backwards compatibility {<<"max">>,#erl_mfa{m=?MODULE,f=max}}, {<<"maxinteger">>,16#7FFFFFFFFFFFFFFF}, %From Lua 5.4.3 {<<"min">>,#erl_mfa{m=?MODULE,f=min}}, {<<"mininteger">>,-16#8000000000000000}, %From Lua 5.4.3 {<<"modf">>,#erl_mfa{m=?MODULE,f=modf}}, {<<"pi">>,math:pi()}, {<<"pow">>,#erl_mfa{m=?MODULE,f=pow}}, {<<"rad">>,#erl_mfa{m=?MODULE,f=rad}}, {<<"random">>,#erl_mfa{m=?MODULE,f=random}}, {<<"randomseed">>,#erl_mfa{m=?MODULE,f=randomseed}}, {<<"sin">>,#erl_mfa{m=?MODULE,f=sin}}, {<<"sinh">>,#erl_mfa{m=?MODULE,f=sinh}}, %For 5.2 backwards compatibility {<<"sqrt">>,#erl_mfa{m=?MODULE,f=sqrt}}, {<<"tan">>,#erl_mfa{m=?MODULE,f=tan}}, {<<"tanh">>,#erl_mfa{m=?MODULE,f=tanh}}, %For 5.2 backwards compatibility {<<"tointeger">>,#erl_mfa{m=?MODULE,f=tointeger}}, {<<"type">>,#erl_mfa{m=?MODULE,f=type}} ]. %% abs(Args, State) -> {[Ret],State}. abs(_, As, St) -> case get_number_args(As) of [N|_] when is_number(N) -> {[abs(N)],St}; _ -> badarg_error(abs, As, St) end. acos(_, As, St) -> case get_number_args(As) of [N|_] when is_number(N) -> {[math:acos(N)],St}; _ -> badarg_error(acos, As, St) end. asin(_, As, St) -> case get_number_args(As) of [N|_] when is_number(N) -> {[math:asin(N)],St}; _ -> badarg_error(asin, As, St) end. atan(_, As, St) -> case get_number_args(As) of [N1,N2|_] when is_number(N1), is_number(N2) -> {[math:atan2(N1, N2)],St}; [N|_] when is_number(N) -> {[math:atan(N)],St}; _ -> badarg_error(atan, As, St) end. atan2(_, As, St) -> %For 5.2 backwards compatibility case get_number_args(As) of [N1,N2|_] when is_number(N1), is_number(N2) -> {[math:atan2(N1, N2)],St}; _ -> badarg_error(atan2, As, St) end. ceil(_, As, St) -> case get_number_args(As) of [N|_] when is_number(N) -> {[ceil(N)],St}; _ -> badarg_error(ceil, As, St) end. -ifndef(HAS_CEIL). %% ceil(Number) -> integer(). %% Ceil does not exist before 20 so we need to do it ourselves. ceil(N) when is_integer(N) -> N; ceil(N) when is_float(N) -> round(N + 0.5). -endif. cos(_, As, St) -> case get_number_args(As) of [N|_] when is_number(N) -> {[math:cos(N)],St}; _ -> badarg_error(cos, As, St) end. cosh(_, As, St) -> %For 5.2 backwards compatibility case get_number_args(As) of [N|_] when is_number(N) -> {[math:cosh(N)],St}; _ -> badarg_error(cosh, As, St) end. deg(_, As, St) -> case get_number_args(As) of [N|_] when is_number(N) -> {[180.0*N/math:pi()],St}; _ -> badarg_error(deg, As, St) end. exp(_, As, St) -> case get_number_args(As) of [N|_] when is_number(N) -> {[math:exp(N)],St}; _ -> badarg_error(exp, As, St) end. floor(_, As, St) -> case get_number_args(As) of [N|_] when is_number(N) -> {[floor(N)],St}; _ -> badarg_error(floor, As, St) end. -ifndef(HAS_FLOOR). %% floor(Number) -> integer(). %% Floor does not exist before 20 so we need to do it ourselves. floor(N) when is_integer(N) -> N; floor(N) when is_float(N) -> round(N - 0.5). -endif. fmod(_, As, St) -> case get_number_args(As) of [X,Y|_] when is_number(X), is_number(Y) -> Div = trunc(X/Y), Rem = X - Div*Y, {[Rem],St}; _ -> badarg_error(fmod, As, St) end. frexp(_, As, St) -> %For 5.2 backwards compatibility %% M,E such that X = M * 2 ^ E. case get_number_args(As) of [X|_] when is_number(X) -> %% The sneaky bit! <> = <<(X+0.0)/float>>, Two52 = 1 bsl 52, Man1 = (Man0 bor Two52)/Two52, %% Bit naughty here, export Man2, Exp1 if Man1 >= 1.0 -> Man2 = Man1/2, Exp1 = Exp0 - 1022; Man1 < 0.5 -> Man2 = Man1*2.0, Exp1 = Exp0 - 1024; true -> Man2 = Man1, Exp1 = Exp0 - 1023 end, Ret = if Sign =:= 1 -> -Man2; true -> Man2 end, {[float(Ret),Exp1],St}; _ -> badarg_error(frexp, As, St) end. ldexp(_, As, St) -> %For 5.2 backwards compatibility case get_number_args(As) of [M,E|_] when is_float(M), is_integer(E) -> {[M*math:pow(2, E)],St}; %% <> = <<0:1,E:11,M:52>>, %% {[X],St}; _ -> badarg_error(ldexp, As, St) end. log(_, As, St) -> case get_number_args(As) of [N1,N2|_] when is_number(N1), N2 == 10 -> {[math:log10(N1)],St}; %Seeing it is builtin [N1,N2|_] when is_number(N1), is_number(N2) -> {[math:log(N1)/math:log(N2)],St}; [N|_] when is_number(N) -> {[math:log(N)],St}; _ -> badarg_error(log, As, St) end. log10(_, As, St) -> %For 5.1 backwards compatibility case get_number_args(As) of [N|_] when N == 0 -> {[-500.0],St}; %Bit hacky [N|_] when is_number(N) -> {[math:log10(N)],St}; _ -> badarg_error(log10, As, St) end. max(_, As, St) -> case luerl_lib:args_to_numbers(As) of [_|_]=Ns -> {[lists:max(Ns)],St}; %At least one number _ -> badarg_error(max, As, St) end. min(_, As, St) -> case luerl_lib:args_to_numbers(As) of [_|_]=Ns -> {[lists:min(Ns)],St}; %At least one number _ -> badarg_error(min, As, St) end. modf(_, As, St) -> case get_number_args(As) of [N|_] when is_integer(N) -> {[N,0.0],St}; [N|_] when is_float(N) -> I = trunc(N), %Integral part {[I,float(N-I)],St}; _ -> badarg_error(modf, As, St) end. pow(_, As, St) -> %For 5.2 backwards compatibility case get_number_args(As) of [N1,N2|_] when is_number(N1) and is_number(N2) -> {[math:pow(N1, N2)],St}; _ -> badarg_error(pow, As, St) end. rad(_, As, St) -> case get_number_args(As) of [N|_] when is_number(N) -> {[math:pi()*N/180.0],St}; _ -> badarg_error(rad, As, St) end. random(_, As, #luerl{rand=S0}=St) -> case luerl_lib:args_to_integers(As) of [] -> %0.0 - 1.0 {R,S1} = ?RAND_UNIFORM(S0), {[R],St#luerl{rand=S1}}; [M] when M >= 1 -> {R,S1} = ?RAND_UNIFORM(M, S0), {[R],St#luerl{rand=S1}}; [M,N] when N >= M -> {R,S1} = ?RAND_UNIFORM(N - M + 1, S0), {[R + M - 1],St#luerl{rand=S1}}; _ -> badarg_error(random, As, St) end. randomseed(_, As, St) -> case get_number_args(As) of [S|_] when is_number(S) -> %% Split integer or float-64 into three integers. <> = <>, {[],St#luerl{rand=?RAND_SEED(A1, A2, A3)}}; _ -> badarg_error(randomseed, As, St) end. sin(_, As, St) -> case get_number_args(As) of [N|_] when is_number(N) -> {[math:sin(N)],St}; _ -> badarg_error(sin, As, St) end. sinh(_, As, St) -> %For 5.2 backwards compatibility case get_number_args(As) of [N|_] when is_number(N) -> {[math:sinh(N)],St}; _ -> badarg_error(sinh, As, St) end. sqrt(_, As, St) -> case get_number_args(As) of [N|_] when is_number(N) -> {[math:sqrt(N)],St}; _ -> badarg_error(sqrt, As, St) end. tan(_, As, St) -> case get_number_args(As) of [N|_] when is_number(N) -> {[math:tan(N)],St}; _ -> badarg_error(tan, As, St) end. tanh(_, As, St) -> %For 5.2 backwards compatibility case get_number_args(As) of [N|_] when is_number(N) -> {[math:tanh(N)],St}; _ -> badarg_error(tanh, As, St) end. tointeger(_, As, St) -> case get_number_args(As) of [N|_] when is_integer(N) -> {[N],St}; [N|_] when is_float(N) -> case trunc(N) of I when I == N -> {[I],St}; _ -> {[nil], St} end; [_|_] -> {[nil],St}; [] -> badarg_error(tointeger, As, St) end. type(_, As, St) -> %% No conversion here. case As of [N|_] when is_integer(N) -> {[<<"integer">>],St}; [N|_] when is_float(N) -> {[<<"float">>],St}; [_|_] -> {[nil],St}; %Not a number [] -> badarg_error(type, As, St) end. %% get_number_args(Args) -> [Number]. %% Convert args to numbers inserting nil when not possible. This %% allows us to disting between no numbers and an empty list. get_number_args(As) -> lists:map(fun luerl_lib:arg_to_number/1, As). %% get_number_args([A|As]) -> %% case luerl_lib:tonumber(A) of %% N when is_number(N) -> %% [N|get_number_args(As)]; %% nil -> [] %% end; %% get_number_args([]) -> []. internalize(S) -> ?RAND_INTERNALIZE(S). externalize(S) -> ?RAND_EXTERNALIZE(S). -ifdef(NEW_RAND). rand_externalize(#luerl{rand=S0}=St) -> St#luerl{rand=rand:export_seed_s(S0)}. rand_internalize(#luerl{rand=S0}=St) -> St#luerl{rand=rand:seed_s(S0)}. -endif. luerl-1.2.3/src/luerl_new.erl0000664000175000017500000003525014677012037016523 0ustar debalancedebalance%% Copyright (c) 2020-2021 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_new.erl %% Authors : Robert Virding %% Purpose : The new basic LUA 5.3 interface. -module(luerl_new). -include("luerl.hrl"). %% Basic user API to luerl. -export([init/0,gc/1, load/2,load/3,loadfile/2,loadfile/3, path_loadfile/2,path_loadfile/3,path_loadfile/4, load_module/3,load_module_dec/3, do/2,do_dec/2,do/3,do_dec/3, dofile/2,dofile/3,dofile_dec/2,dofile_dec/3, call/3,call_chunk/2,call_chunk/3, call_function/3,call_function_dec/3, call_method/4,call_method_dec/4, get_table_keys/2,get_table_keys_dec/2, set_table_keys/3,set_table_keys_dec/3, get_stacktrace/1 ]). %% Tracing. -export([set_trace_func/2,clear_trace_func/1, set_trace_data/2,get_trace_data/1]). %% Encoding and decoding. -export([encode/2,encode_list/2,decode/2,decode_list/2]). %% Helping with storing VM state -export([externalize/1,internalize/1]). %% init() -> State. init() -> luerl_emul:init(). %% gc(State) -> State. gc(St) -> luerl_heap:gc(St). %% set_trace_func(TraceFunction, State) -> State. %% clear_trace_func(State) -> State. %% get_trace_data(State) -> TraceData. %% set_trace_data(TraceData, State) -> State. %% Set the trace function and access the trace data. set_trace_func(Tfunc, St) -> St#luerl{trace_func=Tfunc}. clear_trace_func(St) -> St#luerl{trace_func=none}. get_trace_data(St) -> St#luerl.trace_data. set_trace_data(Tdata, St) -> St#luerl{trace_data=Tdata}. %% load(String|Binary, State) -> {ok,FuncRef,NewState}. %% load(String|Binary, Options, State) -> {ok,FuncRef,NewState}. load(Bin, St) -> load(Bin, [return], St). load(Bin, Opts, St) when is_binary(Bin) -> load(binary_to_list(Bin), Opts, St); load(Str, Opts, St0) -> case luerl_comp:string(Str, Opts) of {ok,Chunk} -> {FunRef,St1} = luerl_emul:load_chunk(Chunk, St0), {ok,FunRef,St1}; Error -> %Compile error Error end. %% loadfile(FileName, State) -> {ok,FuncRef,NewState}. %% loadfile(FileName, Options, State) -> {ok,FuncRef,NewState}. loadfile(Name, St) -> loadfile(Name, [return], St). loadfile(Name, Opts, St0) -> case luerl_comp:file(Name, Opts) of {ok,Chunk} -> {Func,St1} = luerl_emul:load_chunk(Chunk, St0), {ok,Func,St1}; Error -> Error end. %% path_loadfile(FileName, State) -> {ok,Function,FullName,State}. %% path_loadfile(Path, FileName, State) -> {ok,Function,FullName,State}. %% path_loadfile(Path, FileName, Options, State) -> %% {ok,Function,FullName,State}. %% When no path is given we use the value of LUA_LOAD_PATH. %% We manually step down the path to get the correct handling of %% filenames by the compiler. path_loadfile(Name, St) -> Path = case os:getenv("LUA_LOAD_PATH") of false -> []; %You get what you asked for Env -> %% Get path separator depending on os type. Sep = case os:type() of {win32,_} -> ";"; %Windows _ -> ":" %Unix end, string:tokens(Env, Sep) %Split into path list end, path_loadfile(Path, Name, [return], St). path_loadfile(Dirs, Name, St) -> path_loadfile(Dirs, Name, [return], St). path_loadfile([Dir|Dirs], Name, Opts, St0) -> Full = filename:join(Dir, Name), case loadfile(Full, Opts, St0) of {ok,Func,St1} -> {ok,Func,Full,St1}; {error,[{_,_,enoent}],_} -> %Couldn't find the file path_loadfile(Dirs, Name, St0); Error -> Error end; path_loadfile([], _, _, _) -> {error,[{none,file,enoent}],[]}. %% load_module(LuaTablePath, ModuleName, State) -> State. %% Load module and add module table to the path. load_module([_|_] = Lfp, Mod, St0) -> {Tab,St1} = Mod:install(St0), luerl_emul:set_table_keys(Lfp, Tab, St1); load_module(_, _, _) -> error(badarg). %% load_module_dec(DecodedTablePath, ModuleName, State) -> State. %% Load module and add module table to the path. load_module_dec([_|_] = Dfp, Mod, St0) -> {Efp,St1} = encode_list(Dfp, St0), load_module(Efp, Mod, St1); load_module_dec(_, _, _) -> error(badarg). %% luerl:do(String|Binary|Form, State) -> %% luerl:do(String|Binary|Form, CompileOptions, State) -> %% {ok,Result,NewState} | {lua_error,Error,State}. do(S, St) -> do(S, [return], St). do(S, Opts, St0) -> case load(S, Opts, St0) of {ok,Func,St1} -> call_function(Func, [], St1); Error -> Error end. do_dec(S, St) -> do_dec(S, [return], St). do_dec(S, Opts, St0) -> case do(S, Opts, St0) of {ok,Eret,St1} -> {ok,decode_list(Eret, St1),St1}; Error -> Error end. %% luerl:dofile(FileName, State) -> %% luerl:dofile(FileName, CompileOptions, State) -> %% {ok,Result,NewState} | {lua_error,Error,State}. dofile(File, St) -> dofile(File, [], St). dofile(File, Opts, St0) -> case loadfile(File, Opts, St0) of {ok,Func,St1} -> call_function(Func, [], St1); Error -> Error end. dofile_dec(File, St) -> dofile_dec(File, [], St). dofile_dec(File, Opts, St0) -> case dofile(File, Opts, St0) of {ok,Eret,St1} -> {ok,decode_list(Eret, St1),St1}; Error -> Error end. %% call(FuncRef, Args, State) -> %% call_chunk(FuncRef, State) -> %% call_chunk(FuncRef, Args, State) -> %% {ok,Return,State} | {lua_error,Error,State}. call(C, As, St) -> call_function(C, As, St). call_chunk(C, St) -> call_chunk(C, [], St). call_chunk(C, As, St) -> call_function(C, As, St). %% call_function(LuaFuncRef, Args, State) -> %% {ok,LuaReturn,State} | {lua_error,Error,State}. call_function(Func, Args, St0) -> try {Ret,St1} = luerl_emul:functioncall(Func, Args, St0), {ok,Ret,St1} catch error:{lua_error,_E,_St} = LuaErr -> LuaErr end. %% call_function_dec(DecodedFuncRef, Args, State) -> %% {ok,DecodedReturn,State} | {lua_error,Error,State}. call_function_dec(Dtpath, Dargs, St0) -> {ok,Efunc,St1} = get_table_keys_dec(Dtpath, St0), {Eargs,St2} = encode_list(Dargs, St1), case call_function(Efunc, Eargs, St2) of {ok,Eret,St3} -> {ok,decode_list(Eret, St3),St3}; LuaError -> LuaError end. %% call_method(LuaObject, Method, Args, State) -> %% {ok,Return,State} | {lua_error,Error,State}. call_method(Obj, Meth, Args, St0) -> try {Ret,St1} = luerl_emul:methodcall(Obj, Meth, Args, St0), {ok,Ret,St1} catch error:{lua_error,_E,_St} = LuaErr -> LuaErr end. %% call_method_dec(DecodedObject, Method, Args, State) -> %% {ok,DecodedReturn,State} | {lua_error,Error,State}. call_method_dec(Dobj, Dmeth, Dargs, St0) -> {ok,Eobj,St1} = get_table_keys_dec(Dobj, St0), {Emeth,St2} = encode(Dmeth, St1), {Eargs,St3} = encode_list(Dargs, St2), case call_method(Eobj, Emeth, Eargs, St3) of {ok,Eret,St4} -> {ok,decode_list(Eret, St4),St4}; LuaError -> LuaError end. %% get_table_keys(Keys, State) -> %% get_table_keys_dec(DecodedKeys, State) -> %% {ok,Return,State} | {lua_error,Error,State}. %% set_table_keys(Keys, Val, State) -> %% set_table_keys_dec(DecodedKeys, DecodedVal, State) -> %% {ok,Return,State} | {lua_error,Error,State}. get_table_keys(Keys, St0) -> try {Ret,St1} = luerl_emul:get_table_keys(Keys, St0), {ok,Ret,St1} catch error:{lua_error,_E,_St} = LuaErr -> LuaErr end. get_table_keys_dec(Dkeys, St0) -> {Ekeys,St1} = encode_list(Dkeys, St0), get_table_keys(Ekeys, St1). set_table_keys(Keys, Val, St0) -> try St1 = luerl_emul:set_table_keys(Keys, Val, St0), {ok,[],St1} catch error:{lua_error,_E,_St} = LuaErr -> LuaErr end. set_table_keys_dec(Dkeys, Dval, St0) -> {Ekeys,St1} = encode_list(Dkeys, St0), {Eval,St2} = encode(Dval, St1), set_table_keys(Ekeys, Eval, St2). %% get_stacktrace(State) -> [{FuncName,[{file,FileName},{line,Line}]}]. get_stacktrace(#luerl{cs=Stack}=St) -> Fun = fun (Frame, Acc) -> do_stackframe(Frame, Acc, St) end, {_,Trace} = lists:foldl(Fun, {1,[]}, Stack), lists:reverse(Trace). do_stackframe(#call_frame{func=Funref,args=Args}, {Line,Trace}, St) -> case Funref of #funref{} -> {Func,_} = luerl_heap:get_funcdef(Funref, St), Anno = Func#lua_func.anno, Name = case luerl_anno:get(name, Anno) of undefined -> <<"-no-name-">>; N -> N end, File = luerl_anno:get(file, Anno), {Line,[{Name,Args,[{file,File},{line,Line}]} | Trace]}; #erl_func{code=Fun} -> {module,Module} = erlang:fun_info(Fun, module), {name,Name} = erlang:fun_info(Fun, name), FileName = get_filename(Module), {Line,[{{Module,Name},Args,[{file,FileName}]} | Trace]}; #erl_mfa{m=M,f=F,a=A} -> FileName = get_filename(M), %% {Line,[{{M,F},{A,Args},[{file,FileName}]} | Trace]}; %% {Line,[{{M,F},[A | Args],[{file,FileName}]} | Trace]}; {Line,[{{M,F,A},Args,[{file,FileName}]} | Trace]}; Other -> {Line,[{Other,Args,[{file,<<"-no-file-">>},{line,Line}]} | Trace]} end; do_stackframe(#current_line{line=Line}, {_,Trace}, _St) -> {Line,Trace}; do_stackframe(#loop_frame{}, Acc, _St) -> %Ignore these Acc. get_filename(Mod) -> Comp = erlang:get_module_info(Mod, compile), case lists:keyfind(source, 1, Comp) of {source,FileName} -> BaseName = filename:basename(FileName), list_to_binary(BaseName); false -> %The compiler doesn't know <<"-no-file-">> end. %% Define IS_MAP/1 macro for is_map/1 bif. -ifdef(HAS_MAPS). -define(IS_MAP(T), is_map(T)). -else. -define(IS_MAP(T), false). -endif. %% encode_list([Term], State) -> {[LuerlTerm],State}. %% encode(Term, State) -> {LuerlTerm,State}. encode_list(Ts, St) -> lists:mapfoldl(fun encode/2, St, Ts). encode(nil, St) -> {nil,St}; encode(false, St) -> {false,St}; encode(true, St) -> {true,St}; encode(B, St) when is_binary(B) -> {B,St}; encode(A, St) when is_atom(A) -> {atom_to_binary(A, utf8),St}; encode(N, St) when is_number(N) -> {N,St}; %Integers and floats encode(F, St) when ?IS_MAP(F) -> encode(maps:to_list(F), St); encode(L, St0) when is_list(L) -> %% Encode the table elements in the list. EncTab = fun ({K0,V0}, {I,S0}) -> {K1,S1} = encode(K0, S0), {V1,S2} = encode(V0, S1), {{K1,V1},{I,S2}}; (V0, {I,S0}) -> {V1,S1} = encode(V0, S0), {{I,V1},{I+1,S1}} end, {Es,{_,St1}} = lists:mapfoldl(EncTab, {1,St0}, L), {T,St2} = luerl_heap:alloc_table(Es, St1), {T,St2}; %No more to do for now encode(F, St) when is_function(F, 2) -> F1 = fun(Args, State) -> Args1 = decode_list(Args, State), {Res, State1} = F(Args1, State), encode_list(Res, State1) end, {#erl_func{code=F1}, St}; encode(F, St) when is_function(F, 1) -> F1 = fun(Args, State) -> Args1 = decode_list(Args, State), Res = F(Args1), encode_list(Res, State) end, {#erl_func{code=F1}, St}; encode({M,F,A}, St) when is_atom(M) and is_atom(F) -> {#erl_mfa{m=M,f=F,a=A}, St}; encode({userdata,Data}, St) -> luerl_heap:alloc_userdata(Data, St); % Table refs should not be re-encoded encode(#tref{}=T, St) -> case luerl_heap:chk_table(T, St) of ok -> {T, St}; error -> error(badarg) end; encode(_, _) -> error(badarg). %Can't encode anything else %% decode_list([LuerlTerm], State) -> [Term]. %% decode(LuerlTerm, State) -> Term. %% In decode we track of which tables we have seen to detect %% recursive references and generate an error when that occurs. decode_list(Lts, St) -> lists:map(fun (Lt) -> decode(Lt, St) end, Lts). decode(LT, St) -> decode(LT, St, []). decode(nil, _, _) -> nil; decode(false, _, _) -> false; decode(true, _, _) -> true; decode(B, _, _) when is_binary(B) -> B; decode(N, _, _) when is_number(N) -> N; %Integers and floats decode(#tref{}=T, St, In) -> decode_table(T, St, In); decode(#usdref{}=U, St, _) -> decode_userdata(U, St); decode(#funref{}=Fun, State, _) -> F = fun(Args) -> {Args1, State1} = encode_list(Args, State), {Ret, State2} = luerl_emul:functioncall(Fun, Args1, State1), decode_list(Ret, State2) end, F; %Just a bare fun decode(#erl_func{code=Fun}, _, _) -> Fun; decode(#erl_mfa{m=M,f=F,a=A}, _, _) -> {M,F,A}; decode(_, _, _) -> error(badarg). %Shouldn't have anything else decode_table(#tref{i=N}=T, St, In0) -> case lists:member(N, In0) of true -> error({recursive_table,T}); %Been here before false -> In1 = [N|In0], %We are in this as well case luerl_heap:get_table(T, St) of #table{a=Arr,d=Dict} -> Fun = fun (K, V, Acc) -> [{decode(K, St, In1),decode(V, St, In1)}|Acc] end, Ts = ttdict:fold(Fun, [], Dict), array:sparse_foldr(Fun, Ts, Arr); _Undefined -> error(badarg) end end. decode_userdata(U, St) -> {#userdata{d=Data},_} = luerl_heap:get_userdata(U, St), {userdata,Data}. %% Externalize and Internalize ensure that the VM state passed in %% can be stored externally or can be recreated from external storage. %% Currently very simple: only random state needs special treatment. externalize(S) -> luerl_lib_math:externalize(S). internalize(S) -> luerl_lib_math:internalize(S). luerl-1.2.3/src/luerl_lib_string_format.erl0000664000175000017500000002323314677012037021434 0ustar debalancedebalance%% Copyright (c) 2020 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_lib_string_format.erl %% Author : Robert Virding %% Purpose : The string formatting for Luerl. -module(luerl_lib_string_format). -include("luerl.hrl"). -export([format/3]). format(F, As, St0) -> {Str,St1} = format_loop(luerl_lib:arg_to_list(F), As, St0), {[unicode:characters_to_binary(Str)],St1}. format_loop(Fmt, As, St) -> format_loop(Fmt, As, St, []). format_loop([$%|Fmt0], As0, St0, Acc) -> {Format,Fmt1} = collect(Fmt0), {Out,As1,St1} = build(Format, As0, St0), format_loop(Fmt1, As1, St1, [Out|Acc]); format_loop([$\\,C|Fmt], As, St, Acc) -> format_loop(Fmt, As, St, [C|Acc]); format_loop([C|Fmt], As, St, Acc) -> format_loop(Fmt, As, St, [C|Acc]); format_loop([], _, St, Acc) -> %Ignore extra arguments {lists:reverse(Acc),St}. %% collect(Format) -> {{C,Flags,Field,Precision},Format}. %% Collect a conversion specification. collect(Fmt0) -> {Fl,Fmt1} = flags(Fmt0), %The flags characters {F,Fmt2} = field_width(Fmt1), %The field width {P,Fmt3} = precision(Fmt2), %The precision {C,Fmt4} = collect_cc(Fmt3), %The control character {{C,Fl,F,P},Fmt4}. %% Handling the flags of a format. %% Yes, we should use a tuple or record, but this is much more fun. -define(FL_NONE, 0). -define(FL_H, 2#00001). -define(FL_Z, 2#00010). -define(FL_M, 2#00100). -define(FL_S, 2#01000). -define(FL_P, 2#10000). -define(SET_BIT(FL,B), (FL bor (B))). -define(ANY_BITS(Fl, B), ((Fl band (B)) =/= 0)). -define(ALL_BITS(Fl, B), ((Fl band (B)) =:= (B))). -define(NO_BITS(Fl, B), ((Fl band (B)) =:= 0)). flags(Fmt) -> flags(Fmt, ?FL_NONE). flags([$#|Fmt], Fl) -> flags(Fmt, ?SET_BIT(Fl, ?FL_H)); flags([$0|Fmt], Fl) -> flags(Fmt, ?SET_BIT(Fl, ?FL_Z)); flags([$-|Fmt], Fl) -> flags(Fmt, ?SET_BIT(Fl, ?FL_M)); flags([$\s|Fmt], Fl) -> flags(Fmt, ?SET_BIT(Fl, ?FL_S)); flags([$+|Fmt], Fl) -> flags(Fmt, ?SET_BIT(Fl, ?FL_P)); flags(Fmt, Fl) -> {Fl,Fmt}. field_width(Fmt) -> field_value(Fmt). precision([$.|Fmt]) -> field_value(Fmt); precision(Fmt) -> {none,Fmt}. collect_cc([C|Fmt]) -> {C,Fmt}; collect_cc([]) -> {none,[]}. field_value([C|_]=Fmt) when C >= $0, C =< $9 -> field_value(Fmt, 0); field_value(Fmt) -> {none,Fmt}. field_value([C|Fmt], F) when C >= $0, C =< $9 -> field_value(Fmt, 10*F + (C - $0)); field_value(Fmt, F) -> {F,Fmt}. %% build({C,Flags,Field,Precision}, Args) -> {Out,Args}. %% Build a string from the conversion specification. %% Implemented conversions are d,i o,u,x,X e,E f,F g,G c s %. %% No length modifiers, h L l, no conversions n p S C allowed. build({$q,_,_,_}, [A|As], St0) -> %% No trimming or adjusting of the $q string, we only get all of %% it. Use an RE to split string on quote needing characters. {[S0],St1} = luerl_lib_basic:tostring([A], St0), RE = "([\\0-\\39\\\n\\\"\\\\\\177-\\237])", %You don't really want to know! Ss0 = re:split(S0, RE, [{return,binary},trim]), Ss1 = build_q(Ss0), {[$",Ss1,$"],As,St1}; build({$s,Fl,F,P}, [A|As], St0) -> {[S0],St1} = luerl_lib_basic:tostring([A], St0), S1 = trim_bin(S0, P), {adjust_bin(S1, Fl, F),As,St1}; %% Integer formats. build({$c,Fl,F,_}, [A|As], St) -> N = luerl_lib:arg_to_integer(A), C = N band 255, {adjust_str([C], Fl, F),As,St}; build({$i,Fl,F,P}, [A|As], St) -> I = luerl_lib:arg_to_integer(A), {format_decimal(Fl, F, P, I),As,St}; build({$d,Fl,F,P}, [A|As], St) -> I = luerl_lib:arg_to_integer(A), {format_decimal(Fl, F, P, I),As,St}; build({$o,Fl,F,P}, [A|As], St) -> I = luerl_lib:arg_to_integer(A), {format_octal(Fl, F, P, I),As,St}; build({$x,Fl,F,P}, [A|As], St) -> I = luerl_lib:arg_to_integer(A), {format_hex(Fl, F, P, I),As,St}; build({$X,Fl,F,P}, [A|As], St) -> I = luerl_lib:arg_to_integer(A), {format_HEX(Fl, F, P, I),As,St}; build({$u,Fl,F,P}, [A|As], St) -> N = luerl_lib:arg_to_integer(A), {format_unsigned(Fl, F, P, N),As,St}; %% Float formats. build({$e,Fl,F,P}, [A|As], St) -> N = luerl_lib:arg_to_float(A), {format_e_float(Fl, F, P, N),As,St}; build({$E,Fl,F,P}, [A|As], St) -> N = luerl_lib:arg_to_float(A), {format_e_float(Fl, F, P, N),As,St}; build({$f,Fl,F,P}, [A|As], St) -> N = luerl_lib:arg_to_float(A), {format_f_float(Fl, F, P, N),As,St}; build({$F,Fl,F,P}, [A|As], St) -> N = luerl_lib:arg_to_float(A), {format_f_float(Fl, F, P, N),As,St}; build({$g,Fl,F,P}, [A|As], St) -> N = luerl_lib:arg_to_float(A), {format_g_float(Fl, F, P, N),As,St}; build({$G,Fl,F,P}, [A|As], St) -> N = luerl_lib:arg_to_float(A), {format_g_float(Fl, F, P, N),As,St}; %% Literal % format. build({$%,?FL_NONE,none,none}, As, St) -> %No flags, field or precision! {"%",As,St}. %% format_decimal(Flags, Field, Precision, Number) -> String. %% format_octal(Flags, Field, Precision, Number) -> String. %% format_hex(Flags, Field, Precision, Number) -> String. %% format_HEX(Flags, Field, Precision, Number) -> String. %% format_integer(Flags, Field, Precision, Number, String) -> String. %% Print integer Number with base Base. This is a bit messy as we are %% following string.format handling. format_unsigned(Fl, F, P, N) -> %% We have to make the number always positive so we are assuming %% 124 bit integers which matches Lua 5.3. I = if N >= 0 -> N; true -> N band 16#FFFFFFFFFFFFFFFF end, Str = integer_to_list(I), format_integer(Fl, F, P, I, Str). format_decimal(Fl, F, P, N) -> Str = integer_to_list(abs(N), 10), format_integer(Fl, F, P, N, Str). format_octal(Fl, F, P, N) -> Str = integer_to_list(abs(N), 8), format_integer(Fl, F, P, N, Str). format_hex(Fl, F, P, N) -> Str = lists:flatten(io_lib:fwrite("~.16b", [abs(N)])), format_integer(Fl, F, P, N, Str). format_HEX(Fl, F, P, N) -> Str = lists:flatten(io_lib:fwrite("~.16B", [abs(N)])), format_integer(Fl, F, P, N, Str). format_integer(Fl, F, P, N, Str0) -> Sign = sign(Fl, N), if P =/= none -> Str1 = Sign ++ lists:flatten(adjust_str(Str0, ?FL_Z, P)), adjust_str(Str1, (Fl band ?FL_M), F); ?ANY_BITS(Fl, ?FL_M) -> Str1 = Sign ++ Str0, adjust_str(Str1, Fl, F); ?ANY_BITS(Fl, ?FL_Z), F =/= none -> Str1 = adjust_str(Str0, ?FL_Z, F-length(Sign)), Sign ++ Str1; true -> Str1 = Sign ++ Str0, adjust_str(Str1, Fl, F) end. %% format_e_float(Flags, Field, Precision, Number) -> String. %% format_f_float(Flags, Field, Precision, Number) -> String. %% format_g_float(Flags, Field, Precision, Number) -> String. %% Print float Number in e/f/g format. format_e_float(Fl, F, P, N) -> format_float(Fl, F, e_float_precision(P), "~.*e", float(N)). format_f_float(Fl, F, P, N) -> format_float(Fl, F, f_float_precision(P), "~.*f", float(N)). format_g_float(Fl, F, P, N) -> format_float(Fl, F, g_float_precision(P), "~.*g", float(N)). format_float(Fl, F, P, Format, N) -> Str0 = lists:flatten(io_lib:format(Format, [P,abs(N)])), Sign = sign(Fl, N), if ?ANY_BITS(Fl, ?FL_M) -> Str1 = Sign ++ Str0, adjust_str(Str1, Fl, F); ?ANY_BITS(Fl, ?FL_Z) -> Str1 = adjust_str(Str0, ?FL_Z, F-length(Sign)), Sign ++ Str1; true -> Str1 = Sign ++ Str0, adjust_str(Str1, Fl, F) end. e_float_precision(none) -> 7; e_float_precision(P) -> P+1. f_float_precision(none) -> 6; f_float_precision(P) -> P. g_float_precision(none) -> 6; g_float_precision(P) -> P. %% sign(Flags, Number) -> SignString. sign(_, N) when N < 0 -> "-"; %Always sign when N<0 sign(Fl, _) -> if ?ALL_BITS(Fl, ?FL_P) -> "+"; %+ flag has priority ?ALL_BITS(Fl, ?FL_S) -> " "; true -> "" end. trim_bin(Bin, Prec) when is_integer(Prec), byte_size(Bin) > Prec -> binary:part(Bin, 0, Prec); trim_bin(Bin, _) -> Bin. %% adjust_bin(Binary, Flags, Field) -> iolist(). %% adjust_str(String, Flags, Field) -> iolist(). adjust_bin(Bin, ?FL_NONE, none) -> Bin; adjust_bin(Bin, Fl, F) when is_integer(F), byte_size(Bin) < F -> Size = byte_size(Bin), Padding = lists:duplicate(F-Size, pad_char(Fl, F)), if ?ALL_BITS(Fl, ?FL_M) -> [Bin,Padding]; true -> [Padding,Bin] end; adjust_bin(Bin, _, _) -> Bin. adjust_str(Str, ?FL_NONE, none) -> Str; adjust_str(Str, Fl, F) when is_integer(F), length(Str) < F -> Size = length(Str), Padding = lists:duplicate(F-Size, pad_char(Fl, F)), if ?ALL_BITS(Fl, ?FL_M) -> [Str,Padding]; true -> [Padding,Str] end; adjust_str(Str, _, _) -> Str. %% pad_char(Flags, Field) -> Char. pad_char(Fl, F) -> if ?ALL_BITS(Fl, ?FL_M) -> $\s; %'-' forces padding to " " ?ALL_BITS(Fl, ?FL_Z), F =/= none -> $0; true -> $\s end. build_q([<<>>|Ss]) -> build_q(Ss); build_q([<<$\n>>|Ss]) -> [$\\,$\n|build_q(Ss)]; build_q([<<$">>|Ss]) -> [$\\,$"|build_q(Ss)]; build_q([<<$\\>>|Ss]) -> [$\\,$\\|build_q(Ss)]; build_q([<>=B1|Ss0]) when C1 >=0, C1 =< 31 -> case Ss0 of [<>|_] when C2 >= $0, C2 =< $9 -> [io_lib:format("\\~.3.0w", [C1])|build_q(Ss0)]; [<<>>|Ss1] -> build_q([B1|Ss1]); _ -> [io_lib:format("\\~w", [C1])|build_q(Ss0)] end; build_q([<>|Ss0]) when B >= 127, B =< 159 -> [io_lib:write(B)|build_q(Ss0)]; build_q([S|Ss]) -> [S|build_q(Ss)]; build_q([]) -> []. luerl-1.2.3/src/luerl_comp_cg.erl0000664000175000017500000004471114677012037017343 0ustar debalancedebalance%% Copyright (c) 2013 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_comp_cg.erl %% Author : Robert Virding %% Purpose : A basic LUA 5.3 compiler for Luerl. %% Does code generation in the compiler. In the generated function %% definitions annotations and when we generate the #current_line{} %% instruction we use the virtual filename the compiler has %% generated. This is either the default file name or an explicit one %% given with the {file,FileName} compiler option. -module(luerl_comp_cg). -include("luerl.hrl"). -include("luerl_comp.hrl"). -include("luerl_instrs.hrl"). -export([chunk/2]). -import(ordsets, [add_element/2,is_element/2,union/1,union/2, subtract/2,intersection/2,new/0]). -record(c_cg, {line, %Current line vfile=[] %Current virtual file }). %% chunk(Code, CompInfo) -> {ok,Code}. %% Return a list of instructions to define the chunk function. chunk(Code0, #cinfo{vfile=Vfile,opts=Opts}=_Ci) -> St0 = #c_cg{line=0,vfile=Vfile}, %Get the virtual filename {Code1,_} = functiondef(Code0, St0), luerl_comp:debug_print(Opts, "cg: ~p\n", [Code1]), {ok,Code1}. %% set_var(Var) -> SetIs. %% get_var(Var) -> GetIs. %% These return a LIST of instructions for setting/getting variable. set_var(#lvar{d=D,i=I}) -> [?STORE_LVAR(D, I)]; set_var(#evar{d=D,i=I}) -> [?STORE_EVAR(D, I)]; set_var(#gvar{n=N}) -> [?STORE_GVAR(N)]. get_var(#lvar{d=D,i=I}) -> [?PUSH_LVAR(D, I)]; get_var(#evar{d=D,i=I}) -> [?PUSH_EVAR(D, I)]; get_var(#gvar{n=N}) -> [?PUSH_GVAR(N)]. %% stmt(Stmts, State) -> {Istmts,State}. stmts([S0|Ss0], St0) -> %% We KNOW that the annotation is the second element. Line = luerl_anno:line(element(2, S0)), {CurLine,St1} = add_current_line(Line, St0), {S1,St2} = stmt(S0, nul, St1), %% io:format("ss1: ~p\n", [{Loc0,Free0,Used0}]), {Ss1,St3} = stmts(Ss0, St2), {CurLine ++ S1 ++ Ss1,St3}; stmts([], St) -> {[],St}. %% add_current_line(Line, State) -> {CurLine,State}. %% Return currentline instruction and update state if new line. add_current_line(Line, #c_cg{line=Line}=St) -> {[],St}; add_current_line(Line, #c_cg{vfile=Vfile}=St) -> {[?CURRENT_LINE(Line, Vfile)],St#c_cg{line=Line}}. %% stmt(Stmt, LocalVars, State) -> {Istmt,State}. stmt(#assign_stmt{}=A, _, St) -> assign_stmt(A, St); stmt(#call_stmt{}=C, _, St) -> call_stmt(C, St); stmt(#return_stmt{}=R, _, St) -> return_stmt(R, St); stmt(#break_stmt{}, _, St) -> {[?BREAK],St}; stmt(#block_stmt{}=B, _, St) -> block_stmt(B, St); stmt(#while_stmt{}=W, _, St) -> while_stmt(W, St); stmt(#repeat_stmt{}=R, _, St) -> repeat_stmt(R, St); stmt(#if_stmt{}=I, _, St) -> if_stmt(I, St); stmt(#nfor_stmt{}=F, _, St) -> numfor_stmt(F, St); stmt(#gfor_stmt{}=F, _, St) -> genfor_stmt(F, St); stmt(#local_assign_stmt{}=L, _, St) -> local_assign_stmt(L, St); stmt(#local_fdef_stmt{}=L, _, St) -> local_fdef_stmt(L, St); stmt(#expr_stmt{}=E, _, St) -> expr_stmt(E, St). %% assign_stmt(Assign, State) -> {AssignIs,State}. %% We must evaluate all expressions, even the unneeded ones. assign_stmt(#assign_stmt{vars=Vs,exps=Es}, St) -> assign_loop(Vs, Es, St). %% assign_loop(Vars, Exps, State) -> {Iassigns,State}. %% Must be careful with pushing and popping values here. Make sure %% all non-last values are singleton. %% %% This could most likely be folded together with assign_local_loop/3. assign_loop([V], [E], St0) -> %Remove unnecessary ?PUSH_VALS {Ie,St1} = exp(E, single, St0), %Last argument to one variable {Iv,St2} = assign_prefixexp(V, St1), {Ie ++ Iv,St2}; assign_loop([V|Vs], [E], St0) -> {Ie,St1} = exp(E, multiple, St0), %Last argument to rest of vars {Ias,St2} = assign_loop_var(Vs, St1), {Iv,St3} = assign_prefixexp(V, St2), {Ie ++ Ias ++ Iv,St3}; assign_loop([V|Vs], [E|Es], St0) -> {Ie,St1} = exp(E, single, St0), %Not last argument! {Ias,St2} = assign_loop(Vs, Es, St1), {Iv,St3} = assign_prefixexp(V, St2), {Ie ++ Ias ++ Iv,St3}; assign_loop([], Es, St) -> assign_loop_exp(Es, St). %% assign_loop_var(Vars, State) -> {Iassigns,State}. %% Extract necessary number of values from value list on stack. Pad %% with nil. assign_loop_var(Vs, St) -> assign_loop_var(Vs, 1, St). assign_loop_var([V|Vs], Vc, St0) -> {Ias,St1} = assign_loop_var(Vs, Vc+1, St0), {Iv,St2} = assign_prefixexp(V, St1), {Ias ++ Iv,St2}; assign_loop_var([], Vc, St) -> {[?PUSH_VALS(Vc)],St}. %% assign_loop_exp(Exprs, State) -> {Instrs,State}. %% Evaluate remaining expressions and pop the values from the stack. assign_loop_exp([E|Es], St0) -> {Ie,St1} = exp(E, single, St0), %It will be dropped anyway {Ias,St2} = assign_loop_exp(Es, St1), {Ie ++ Ias ++ [?POP],St2}; %Pop unneeded value off stack assign_loop_exp([], St) -> {[],St}. %% assign_prefixexp(Expr, State) -> {Instrs,State}. %% assign_prefixexp_rest(Expr, State) -> {Instrs,State}. %% assign_prefixexp_element(Expr, State) -> {Instrs,State}. assign_prefixexp(#dot{exp=Exp,rest=Rest}, St0) -> {Ie,St1} = prefixexp_first(Exp, single, St0), {Ir,St2} = assign_prefixexp_rest(Rest, St1), {Ie ++ Ir,St2}; assign_prefixexp(V, St) -> {set_var(V),St}. assign_prefixexp_rest(#dot{exp=Exp,rest=Rest}, St0) -> {Ie,St1} = prefixexp_element(Exp, single, St0), {Ir,St2} = assign_prefixexp_rest(Rest, St1), {Ie ++ Ir,St2}; assign_prefixexp_rest(Exp, St) -> assign_prefixexp_element(Exp, St). assign_prefixexp_element(#key{key=#lit{val=K}}, St) -> {[?SET_LIT_KEY(K)],St}; %[?PUSH_LIT(K),?SET_KEY] assign_prefixexp_element(#key{key=Exp}, St0) -> {Ie,St1} = exp(Exp, single, St0), {Ie ++ [?SET_KEY],St1}. %% call_stmt(Call, State) -> {CallIs,State}. %% Must pop function return value list from stack. call_stmt(#call_stmt{call=Exp}, St0) -> {Ie,St1} = exp(Exp, multiple, St0), {Ie ++ [?POP],St1}. %% return_stmt(Return, State) -> {ReturnIs,State}. %% Can ignore any value left on stack here. return_stmt(#return_stmt{exps=Es}, St0) -> {Ies,St1} = explist(Es, multiple, St0), {Ies ++ [?RETURN(length(Es))],St1}. %% block_stmt(Block, State) -> {BlockIs,State}. block_stmt(#block_stmt{body=Ss,lsz=Lsz,esz=Esz}, St0) -> {Iss,St1} = stmts(Ss, St0), {[?BLOCK_OPEN(Lsz, Esz)] ++ Iss ++ [?BLOCK_CLOSE],St1}. %% do_block(Block, Prefix, Postfix, State) -> {Block,State}. %% do_block(Block, State) -> {Block,State}. %% Do_block never returns external new variables. Fits into stmt(). do_block(Block, St) -> do_block(Block, [], [], St). do_block(#block{body=Ss,lsz=Lsz,esz=Esz}, Pre, Post, St0) -> {Iss,St1} = stmts(Ss, St0), {[?BLOCK_OPEN(Lsz, Esz)] ++ Pre ++ Iss ++ Post ++ [?BLOCK_CLOSE],St1}. %% while_stmt(While, State) -> {WhileIs,State}. while_stmt(#while_stmt{exp=E,body=B}, St0) -> {Ie,St1} = exp(E, single, St0), {Ib,St2} = do_block(B, St1), {[?WHILE(Ie, Ib)],St2}. %% repeat_stmt(Repeat, State) -> {RepeatIs,State}. repeat_stmt(#repeat_stmt{body=B}, St0) -> {Ib,St1} = do_block(B, St0), {[?REPEAT(Ib)],St1}. %% if_stmt(If, State) -> {IfIs,State}. %% We generate code which "steps down" the sequence of %% test-block. This means more nested calls but simpler emulator %% code. if_stmt(#if_stmt{tests=Ts,else_block=E}, St) -> if_tests(Ts, E, St). if_tests([{E,B}], #block{body=[]}, St0) -> Line = luerl_anno:line(element(2, E)), {CurLine,St1} = add_current_line(Line, St0), {Ie,St2} = exp(E, single, St1), {Ib,St3} = do_block(B, St2), {CurLine ++ Ie ++ [?IF_TRUE(Ib)],St3}; if_tests([{E,B}|Ts], Else, St0) -> Line = luerl_anno:line(element(2, E)), {CurLine,St1} = add_current_line(Line, St0), {Ie,St2} = exp(E, single, St1), {Ib,St3} = do_block(B, St2), {Its,St4} = if_tests(Ts, Else, St3), {CurLine ++ Ie ++ [?IF(Ib, Its)],St4}; if_tests([], Else, St0) -> {Ielse,St1} = do_block(Else, St0), {Ielse,St1}. %% numfor_stmt(For, State) -> {ForIs,State}. numfor_stmt(#nfor_stmt{var=V,init=I,limit=L,step=S,body=B}, St0) -> {Ies,St1} = explist([I,L,S], single, St0), {Ib,St2} = do_block(B, set_var(V), [], St1), {Ies ++ [?NFOR(V, Ib)],St2}. %% %% An experiment to put the block *outside* the for loop. %% numfor_stmt(#nfor_stmt{v=V,init=I,limit=L,step=S,b=B}, St0) -> %% {Ies,St1} = explist([I,L,S], single, St0), %% {Ib,St2} = do_block(B, St1), %% [?BLOCK(Lsz, Esz, Is)] = Ib, %% ForBlock = [?BLOCK(Lsz, Esz, [?NFOR(V,set_var(V) ++ Is)])], %% {Ies ++ ForBlock,St2}. %% genfor_stmt(For, State) -> {ForIs,State}. %% Evaluate the explist to return the generator function, data and %% initial value. The handling of setting the pushing and setting the %% vars in the block come from assign_local_loop. genfor_stmt(Gfor, St) -> genfor_stmt_1(Gfor, St). genfor_stmt_1(#gfor_stmt{vars=Vs,gens=Gs,body=B}, St0) -> {Igs,St1} = explist(Gs, multiple, St0), {Ias,St2} = assign_local_loop_var(Vs, 0, St1), {Ib,St3} = do_block(B, Ias, [], St2), {Igs ++ [?POP_VALS(length(Gs))] ++ [?GFOR(Vs, Ib)],St3}. %% local_assign_stmt(Local, State) -> {Ilocal,State}. %% We must evaluate all expressions, even the unneeded ones. %% Have two versions, run both and see that we get the same result. local_assign_stmt(#local_assign_stmt{vars=Vs,exps=Es}, St) -> R = assign_local_test(Vs, Es, St), R = assign_local(Vs, Es, St). assign_local([V|Vs], [], St0) -> {Ias,St1} = assign_local_loop_var(Vs, St0), {[?PUSH_LIT([])] ++ Ias ++ set_var(V),St1}; assign_local(Vs, Es, St) -> assign_local_loop(Vs, Es, St). assign_local_test([V|Vs], [], St0) -> {Ias,St1} = assign_loop_var(Vs, St0), {[?PUSH_LIT([])] ++ Ias ++ set_var(V),St1}; assign_local_test(Vs, Es, St) -> assign_loop(Vs, Es, St). %% assign_local_loop(Vars, Exps, State) -> {Iassigns,State}. %% Must be careful with pushing and popping values here. Make sure %% all non-last values are singleton. %% %% This could most likely be folded together with assign_loop/3. assign_local_loop([V], [E], St0) -> %Remove unnecessary ?PUSH_VALS {Ie,St1} = exp(E, single, St0), %Last argument to one variable! {Ie ++ set_var(V),St1}; assign_local_loop([V|Vs], [E], St0) -> {Ie,St1} = exp(E, multiple, St0), %Last argument to many vars! {Ias,St2} = assign_local_loop_var(Vs, St1), {Ie ++ Ias ++ set_var(V),St2}; assign_local_loop([V|Vs], [E|Es], St0) -> {Ie,St1} = exp(E, single, St0), %Not last argument! {Ias,St2} = assign_local_loop(Vs, Es, St1), {Ie ++ Ias ++ set_var(V),St2}; assign_local_loop([], Es, St) -> assign_local_loop_exp(Es, St). %% assign_local_loop_var(Vars, State) -> {Iassigns,State}. %% Extract necessary number of values from value list on stack. Pad %% with nil. assign_local_loop_var(Vs, St) -> assign_local_loop_var(Vs, 1, St). assign_local_loop_var([V|Vs], Vc, St0) -> {Ias,St1} = assign_local_loop_var(Vs, Vc+1, St0), {Ias ++ set_var(V),St1}; assign_local_loop_var([], Vc, St) -> {[?PUSH_VALS(Vc)],St}. %% assign_local_loop_exp(Exprs, State) -> {Instrs,State}. %% Evaluate remaining expressions and pop the values from the stack. assign_local_loop_exp([E|Es], St0) -> {Ie,St1} = exp(E, single, St0), %It will be dropped anyway {Ias,St2} = assign_local_loop_exp(Es, St1), {Ie ++ Ias ++ [?POP],St2}; %Pop value off stack assign_local_loop_exp([], St) -> {[],St}. %% local_fdef_stmt(Local, State) -> {ILocal,State}. local_fdef_stmt(#local_fdef_stmt{var=V,func=F}, St0) -> {If,St1} = functiondef(F, St0), {If ++ set_var(V),St1}. %% expr_stmt(Expr, State) -> {ExprIs,State}. %% The expression pseudo statement. This will return a single value %% which we leave on the stack. expr_stmt(#expr_stmt{exp=Exp}, St0) -> {Ie,St1} = exp(Exp, single, St0), {Ie,St1}. %% explist(Exprs, Values, State) -> {Instrs,State}. %% exp(Expr, Values, State) -> {Instrs,State}. %% Values determines if we are to only return the first value of a %% list of values. Values multiple makes us a return a list! explist([E], S, St) -> exp(E, S, St); %Append values to output? explist([E|Es], S, St0) -> {Ie,St1} = exp(E, single, St0), {Ies,St2} = explist(Es, S, St1), {Ie ++ Ies,St2}; explist([], _, St) -> {[],St}. %No expressions at all exp(#lit{val=L}, S, St) -> Is = [?PUSH_LIT(L)], {multiple_values(S, Is),St}; exp(#fdef{}=F, S, St0) -> {If,St1} = functiondef(F, St0), {multiple_values(S, If), St1}; exp(#op{op='and',args=[A1,A2]}, S, St0) -> {Ia1,St1} = exp(A1, S, St0), {Ia2,St2} = exp(A2, S, St1), {Ia1 ++ [?AND_THEN(Ia2)],St2}; %Must handle single/multiple exp(#op{op='or',args=[A1,A2]}, S, St0) -> {Ia1,St1} = exp(A1, S, St0), {Ia2,St2} = exp(A2, S, St1), {Ia1 ++ [?OR_ELSE(Ia2)],St2}; %Must handle single/multiple exp(#op{op=Op,args=As}, S, St0) -> {Ias,St1} = explist(As, single, St0), Iop = Ias ++ [?OP(Op,length(As))], {multiple_values(S, Iop),St1}; exp(#tabcon{fields=Fs}, S, St0) -> {Its,Fc,I,St1} = tableconstructor(Fs, St0), {Its ++ multiple_values(S, [?BUILD_TAB(Fc,I)]),St1}; exp(#lvar{n='...'}=V, S, St) -> %Can be either local or frame {single_value(S, get_var(V)),St}; exp(#evar{n='...'}=V, S, St) -> {single_value(S, get_var(V)),St}; exp(E, S, St) -> prefixexp(E, S, St). %% single_value(Values, Instrs) -> Instrs. %% multiple_values(Values, Instrs) -> Instrs. %% Ensure either single value or multiple value. single_value(single, Is) -> Is ++ [?SINGLE]; single_value(multiple, Is) -> Is. multiple_values(single, Is) -> Is; multiple_values(multiple, Is) -> Is ++ [?MULTIPLE]. %% prefixexp(Expr, Values, State) -> {Instrs,State}. %% prefixexp_rest(Expr, Values, State) -> {Instrs,State}. %% prefixexp_first(Expr, Values, State) -> {Instrs,State}. %% prefixexp_element(Expr, Values, State) -> {Instrs,State}. %% Single determines if we are to only return the first value of a %% list of values. Single false makes us a return a list! prefixexp(#dot{exp=Exp,rest=Rest}, S, St0) -> {Ie,St1} = prefixexp_first(Exp, single, St0), {Ir,St2} = prefixexp_rest(Rest, S, St1), {Ie ++ Ir,St2}; prefixexp(Exp, S, St) -> prefixexp_first(Exp, S, St). prefixexp_first(#single{exp=E}, S, St0) -> {Ie,St1} = exp(E, single, St0), %Will make it single {multiple_values(S, Ie),St1}; prefixexp_first(Var, S, St) -> {multiple_values(S, get_var(Var)),St}. prefixexp_rest(#dot{exp=Exp,rest=Rest}, S, St0) -> {Ie,St1} = prefixexp_element(Exp, single, St0), {Ir,St2} = prefixexp_rest(Rest, S, St1), {Ie ++ Ir,St2}; prefixexp_rest(Exp, S, St) -> prefixexp_element(Exp, S, St). prefixexp_element(#key{key=#lit{val=K}}, S, St) -> {multiple_values(S, [?GET_LIT_KEY(K)]),St}; prefixexp_element(#key{key=E}, S, St0) -> {Ie,St1} = exp(E, single, St0), {Ie ++ multiple_values(S, [?GET_KEY]),St1}; %% prefixexp_element(#fcall{args=[]}, S, St) -> %% Ifs = [?FCALL(0)], %% {single_value(S, Ifs),St}; %Function call returns list %% prefixexp_element(#fcall{args=As}, S, St0) -> %% {Ias,St1} = explist(As, multiple, St0), %% Ifs = Ias ++ [?FCALL(length(As))], %% {single_value(S, Ifs),St1}; %Function call returns list prefixexp_element(#fcall{args=As}, S, St0) -> {Ias,St1} = explist(As, multiple, St0), Ifs = Ias ++ [?POP_ARGS(length(As)),?FCALL], {single_value(S, Ifs),St1}; %Function call returns list %% prefixexp_element(#mcall{meth=#lit{val=K},args=[]}, S, St) -> %% Ims = [?MCALL(K, 0)], %% {single_value(S, Ims),St}; %Method call returns list %% prefixexp_element(#mcall{meth=#lit{val=K},args=As}, S, St0) -> %% {Ias,St1} = explist(As, multiple, St0), %% Ims = Ias ++ [?MCALL(K, length(As))], %% {single_value(S, Ims),St1}. %Method call returns list prefixexp_element(#mcall{meth=#lit{val=K},args=As}, S, St0) -> {Ias,St1} = explist(As, multiple, St0), Ims = Ias ++ [?POP_ARGS(length(As)),?MCALL(K)], {single_value(S, Ims),St1}. %Method call returns list %% functiondef(Func, State) -> {Func,State}. %% This will return a single value which we leave on the stack. Set %% the local current line to 0 to get correct line numbers inside the %% function. Reset to the original afterwards. functiondef(#fdef{l=Anno0,pars=Ps0,body=Ss,lsz=Lsz,esz=Esz}, #c_cg{line=Line,vfile=Vfile}=St0) -> St1 = St0#c_cg{line=0}, %Set current line to 0 %% Set the functions file annotation to the virtual file. Anno1 = luerl_anno:set(file, Vfile, Anno0), Ps1 = func_pars(Ps0), {Iss,St2} = stmts(Ss, St1), Iss1 = [?PUSH_ARGS(Ps1)] ++ gen_store(Ps1, Iss ++ [?RETURN(0)]), {[?PUSH_FDEF(Anno1,Lsz,Esz,Ps1,Iss1)],St2#c_cg{line=Line}}. func_pars([#evar{n='...',i=I}]) -> -I; %Tail is index for varargs func_pars([#lvar{n='...',i=I}]) -> I; func_pars([#evar{i=I}|Ps]) -> [-I|func_pars(Ps)]; func_pars([#lvar{i=I}|Ps]) -> [I|func_pars(Ps)]; func_pars([]) -> []. %No varargs %% Experiments testing case where we push the args onto the stack and %% have explicit instructions which pop them and store them in the LVs %% and Upvs. gen_store([V|Vs], Is) when V > 0 -> gen_store(Vs, [?STORE_LVAR(1, V)|Is]); gen_store([V|Vs], Is) when V < 0 -> gen_store(Vs, [?STORE_EVAR(1, -V)|Is]); gen_store([], Is) -> Is; gen_store(V, Is) when V > 0 -> [?STORE_LVAR(1, V)|Is]; gen_store(V, Is) when V < 0 -> [?STORE_LVAR(1, -V)|Is]. %% tableconstructor(Fields, State) -> {Ifields,FieldCount,Index,State}. %% FieldCount is how many Key/Value pairs are on the stack, Index is %% the index of the next value in the last value pushed. Make sure %% that the last value is a multiple. tableconstructor(Fs, St0) -> {Its,Fc,I,St1} = tc_fields(Fs, 0, St0), {Its,Fc,I,St1}. tc_fields([#efield{val=V}], I0, St0) -> I1 = I0 + 1, %Index of next element {Iv,St1} = exp(V, multiple, St0), {Iv,0,I1,St1}; tc_fields([#efield{val=V}|Fs], I0, St0) -> I1 = I0 + 1, %Index of next element {Iv,St1} = exp(V, single, St0), {Ifs,Fc,I2,St2} = tc_fields(Fs, I1, St1), {[?PUSH_LIT(I1)] ++ Iv ++ Ifs,Fc+1,I2,St2}; tc_fields([#kfield{key=K,val=V}|Fs], I0, St0) -> {Ik,St1} = exp(K, single, St0), {Iv,St2} = exp(V, single, St1), {Ifs,Fc,I1,St3} = tc_fields(Fs, I0, St2), {Ik ++ Iv ++ Ifs,Fc+1,I1,St3}; tc_fields([], _, St) -> {[?PUSH_LIT([])],0,1,St}. luerl-1.2.3/src/luerl_app.erl0000664000175000017500000000167414677012037016515 0ustar debalancedebalance%% Copyright (c) 2013-2021 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. -module(luerl_app). -behaviour(application). %% Application callbacks -export([start/2, stop/1]). %% =================================================================== %% Application callbacks %% =================================================================== start(_StartType, _StartArgs) -> luerl_sup:start_link(). stop(_State) -> ok. luerl-1.2.3/src/luerl_scan.xrl0000664000175000017500000002573414677012037016707 0ustar debalancedebalance%% Copyright (c) 2013-2023 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_scan.xrl %% Author : Robert Virding %% Purpose : Token definitions for LUA. Definitions. D = [0-9] H = [0-9A-Fa-f] U = [A-Z] L = [a-z] Rules. %% Names/identifiers. ({U}|{L}|_)({U}|{L}|_|{D})* : name_token(TokenChars, TokenLine). %% Numbers, we separately parse (Erlang) integers and floats. %% Integers. {D}+ : case catch {ok,list_to_integer(TokenChars)} of {ok,I} -> {token,{'NUMERAL',TokenLine,I}}; _ -> {error,"illegal number"} end. 0[xX]{H}+ : Int = list_to_integer(string:substr(TokenChars, 3), 16), {token,{'NUMERAL',TokenLine,Int}}. %% Floats, we have separate rules to make them easier to handle. {D}+\.{D}+([eE][-+]?{D}+)? : case catch {ok,list_to_float(TokenChars)} of {ok,F} -> {token,{'NUMERAL',TokenLine,F}}; _ -> {error,"illegal number"} end. {D}+[eE][-+]?{D}+ : [M,E] = string:tokens(TokenChars, "eE"), case catch {ok,list_to_float(M ++ ".0e" ++ E)} of {ok,F} -> {token,{'NUMERAL',TokenLine,F}}; _ -> {error,"illegal number"} end. {D}+\.([eE][-+]?{D}+)? : [M|E] = string:tokens(TokenChars, "."), case catch {ok,list_to_float(lists:append([M,".0"|E]))} of {ok,F} -> {token,{'NUMERAL',TokenLine,F}}; _ -> {error,"illegal number"} end. \.{D}+([eE][-+]?{D}+)? : case catch {ok,list_to_float("0" ++ TokenChars)} of {ok,F} -> {token,{'NUMERAL',TokenLine,F}}; _ -> {error,"illegal number"} end. %% Hexadecimal floats, we have one complex rule to handle bad formats %% more like the Lua parser. 0[xX]{H}*\.?{H}*([pP][+-]?{D}+)? : hex_float_token(TokenChars, TokenLine). %% Strings. %% Handle the illegal newlines in string_token. \"(\\.|\\\n|[^"\\])*\" : string_token(TokenChars, TokenLen, TokenLine). \'(\\.|\\\n|[^'\\])*\' : string_token(TokenChars, TokenLen, TokenLine). %% Handle multi line strings, [[ ]], [=[ ]=], [==[ ]==] %% This gets a bit tedious as we have to each case separately. \[\[([^]]|\][^]])*\]\] : long_string_token(TokenChars, TokenLen, 2, TokenLine). \[=\[([^]]|\](=[^]]|[^=]))*\]=\] : long_string_token(TokenChars, TokenLen, 3, TokenLine). \[==\[([^]]|\](==[^]]|=[^=]|[^=]))*\]==\] : long_string_token(TokenChars, TokenLen, 4, TokenLine). \[===\[([^]]|\](===[^]]|==[^=]|=[^=]|[^=]))*\]===\] : long_string_token(TokenChars, TokenLen, 5, TokenLine). %% \[==\[([^]]|\]==[^]]|\]=[^=]|\][^=])*\]==\] : %% Other known tokens. \+ : {token,{'+',TokenLine}}. \- : {token,{'-',TokenLine}}. \* : {token,{'*',TokenLine}}. \/ : {token,{'/',TokenLine}}. \// : {token,{'//',TokenLine}}. \% : {token,{'%',TokenLine}}. \^ : {token,{'^',TokenLine}}. \& : {token,{'&',TokenLine}}. \| : {token,{'|',TokenLine}}. \~ : {token,{'~',TokenLine}}. \>> : {token,{'>>',TokenLine}}. \<< : {token,{'<<',TokenLine}}. \# : {token,{'#',TokenLine}}. == : {token,{'==',TokenLine}}. ~= : {token,{'~=',TokenLine}}. <= : {token,{'<=',TokenLine}}. >= : {token,{'>=',TokenLine}}. < : {token,{'<',TokenLine}}. > : {token,{'>',TokenLine}}. = : {token,{'=',TokenLine}}. \( : {token,{'(',TokenLine}}. \) : {token,{')',TokenLine}}. \{ : {token,{'{',TokenLine}}. \} : {token,{'}',TokenLine}}. \[ : {token,{'[',TokenLine}}. \] : {token,{']',TokenLine}}. :: : {token,{'::',TokenLine}}. ; : {token,{';',TokenLine}}. : : {token,{':',TokenLine}}. , : {token,{',',TokenLine}}. \. : {token,{'.',TokenLine}}. \.\. : {token,{'..',TokenLine}}. \.\.\. : {token,{'...',TokenLine}}. [\011-\015\s\240]+ : skip_token. %Mirror Lua here %% Comments, either -- or --[[ ]]. %%--(\[([^[\n].*|\[\n|[^[\n].*|\n) : skip_token. --\n : skip_token. --[^[\n].* : skip_token. --\[\n : skip_token. --\[[^[\n].* : skip_token. %% comment --ab ... yz --ab([^y]|y[^z])*yz --\[\[([^]]|\][^]])*\]\] : skip_token. --\[\[([^]]|\][^]])* : {error,"unfinished long comment"}. Erlang code. -export([is_keyword/1]). -export([string_chars/1,chars/1]). %% name_token(Chars, Line) -> %% {token,{'NAME',Line,Symbol}} | {Name,Line} | {error,E}. %% Build a name from list of legal characters, else error. name_token(Cs, L) -> case catch {ok,list_to_binary(Cs)} of {ok,Name} -> case is_keyword(Name) of true -> {token,{name_string(Name),L}}; false -> {token,{'NAME',L,Name}} end; _ -> {error,"illegal name"} end. name_string(Name) -> binary_to_atom(Name, latin1). %Only latin1 in Lua %% hex_float_token(TokenChars, TokenLine) -> %% {token,{'NUMERAL',TokenLine,Float}} | {error,E}. %% Build a float form a hex float string. hex_float_token(TokenChars, TokenLine) -> Tcs = string:substr(TokenChars, 3), case lists:splitwith(fun (C) -> (C =/= $p) and (C =/= $P) end, Tcs) of {Mcs,[]} when Mcs /= [] -> hex_float(Mcs, [], TokenLine); {Mcs,[_P|Ecs]} when Ecs /= [] -> hex_float(Mcs, Ecs, TokenLine); _Other -> {error,"malformed number"} end. %% hex_float(Mantissa, Exponent) -> {token,{'NUMERAL',Line,Float}} | {error,E}. %% hex_mantissa(Chars) -> {float,Float} | error. %% hex_fraction(Chars, Pow, SoFar) -> Fraction. hex_float(Mcs, [], Line) -> case hex_mantissa(Mcs) of {float,M} -> {token,{'NUMERAL',Line,M}}; error -> {error,"malformed number"} end; hex_float(Mcs, Ecs, Line) -> case hex_mantissa(Mcs) of {float,M} -> case catch list_to_integer(Ecs, 10) of {'EXIT',_} -> {error,"malformed number"}; E -> {token,{'NUMERAL',Line,M * math:pow(2, E)}} end; error -> {error,"malformed number"} end. hex_mantissa(Mcs) -> case lists:splitwith(fun (C) -> C =/= $. end, Mcs) of {[],[]} -> error; %Nothing at all {[],[$.]} -> error; %Only a '.' {[],[$.|Fcs]} -> {float,hex_fraction(Fcs, 16.0, 0.0)}; {Hcs,[]} -> {float,float(list_to_integer(Hcs, 16))}; {Hcs,[$.|Fcs]} -> H = float(list_to_integer(Hcs, 16)), {float,hex_fraction(Fcs, 16.0, H)} end. hex_fraction([C|Cs], Pow, SoFar) when C >= $0, C =< $9 -> hex_fraction(Cs, Pow*16, SoFar + (C - $0)/Pow); hex_fraction([C|Cs], Pow, SoFar) when C >= $a, C =< $f -> hex_fraction(Cs, Pow*16, SoFar + (C - $a + 10)/Pow); hex_fraction([C|Cs], Pow, SoFar) when C >= $A, C =< $F -> hex_fraction(Cs, Pow*16, SoFar + (C - $A + 10)/Pow); hex_fraction([], _Pow, SoFar) -> SoFar. %% string_token(InputChars, Length, Line) -> %% {token,{'LITERALSTRING',Line,Cs}} | {error,Error}. %% Convert an input string into the corresponding string characters. %% We know that the input string is correct. string_token(Cs0, Len, L) -> Cs1 = string:substr(Cs0, 2, Len - 2), %Strip quotes try Bytes = string_chars(Cs1), String = unicode:characters_to_binary(Bytes, utf8, utf8), %% String = iolist_to_binary(Bytes), {token,{'LITERALSTRING',L,String}} catch _:_ -> {error,"illegal string"} end. %% string_chars(Chars) %% chars(Chars) %% Return a list of UTF-8 encoded binaries and one byte unencoded %% characters. chars/1 is for external backwards compatibilty. chars(Cs) -> string_chars(Cs). string_chars(Cs) -> string_chars(Cs, []). string_chars([$\\ | Cs], []) -> %Nothing here to worry about bq_chars(Cs); string_chars([$\\ | Cs], Acc) -> [lists:reverse(Acc) | bq_chars(Cs)]; string_chars([$\n | _], _Acc) -> throw(string_error); string_chars([C | Cs], Acc) -> string_chars(Cs, [C|Acc]); string_chars([], []) -> []; string_chars([], Acc) -> [lists:reverse(Acc)]. %% long_string_token(InputChars, Length, BracketLength, Line) -> %% {token,{'LITERALSTRING',Line,Cs}} | {error,Error}. long_string_token(Cs0, Len, BrLen, Line) -> %% Strip the brackets and remove first char if a newline. %% Note we export Cs1 here, :-) case string:substr(Cs0, BrLen+1, Len - 2*BrLen) of [$\n | Cs1] -> Cs1; Cs1 -> Cs1 end, try String = unicode:characters_to_binary(Cs1, utf8, utf8), {token,{'LITERALSTRING',Line,String}} catch _:_ -> {error,"illegal string"} end. %% bq_chars(Chars) %% Handle the backquotes characters. These always fit directly into %% one byte and are never UTF-8 encoded. bq_chars([C1|Cs0]) when C1 >= $0, C1 =< $9 -> %1-3 decimal digits I1 = C1 - $0, case Cs0 of [C2|Cs1] when C2 >= $0, C2 =< $9 -> I2 = C2 - $0, case Cs1 of [C3|Cs2] when C3 >= $0, C3 =< $9 -> I3 = C3 - $0, Byte = 100*I1 + 10*I2 + I3, %% Must fit into one byte! (Byte =< 255) orelse throw(string_error), [Byte | string_chars(Cs2, [])]; _ -> Byte = 10*I1 + I2, [Byte | string_chars(Cs1, [])] end; _ -> [I1 | string_chars(Cs0, [])] end; bq_chars([$x,C1,C2|Cs]) -> %2 hex digits case hex_char(C1) and hex_char(C2) of true -> Byte = hex_val(C1)*16 + hex_val(C2), [Byte | string_chars(Cs, [])]; false -> throw(string_error) end; bq_chars([$z|Cs]) -> %Skip blanks string_chars(skip_space(Cs), []); bq_chars([C|Cs]) -> [escape_char(C)|string_chars(Cs, [])]; bq_chars([]) -> []. skip_space([C|Cs]) when C >= 0, C =< $\s -> skip_space(Cs); skip_space(Cs) -> Cs. hex_char(C) when C >= $0, C =< $9 -> true; hex_char(C) when C >= $a, C =< $f -> true; hex_char(C) when C >= $A, C =< $F -> true; hex_char(_) -> false. hex_val(C) when C >= $0, C =< $9 -> C - $0; hex_val(C) when C >= $a, C =< $f -> C - $a + 10; hex_val(C) when C >= $A, C =< $F -> C - $A + 10. escape_char($n) -> $\n; %\n = LF escape_char($r) -> $\r; %\r = CR escape_char($t) -> $\t; %\t = TAB escape_char($v) -> $\v; %\v = VT escape_char($b) -> $\b; %\b = BS escape_char($f) -> $\f; %\f = FF escape_char($e) -> $\e; %\e = ESC escape_char($s) -> $\s; %\s = SPC escape_char($d) -> $\d; %\d = DEL escape_char(C) -> C. %% is_keyword(Name) -> boolean(). %% Test if the name is a keyword. is_keyword(<<"and">>) -> true; is_keyword(<<"break">>) -> true; is_keyword(<<"do">>) -> true; is_keyword(<<"else">>) -> true; is_keyword(<<"elseif">>) -> true; is_keyword(<<"end">>) -> true; is_keyword(<<"false">>) -> true; is_keyword(<<"for">>) -> true; is_keyword(<<"function">>) -> true; is_keyword(<<"goto">>) -> true; is_keyword(<<"if">>) -> true; is_keyword(<<"in">>) -> true; is_keyword(<<"local">>) -> true; is_keyword(<<"nil">>) -> true; is_keyword(<<"not">>) -> true; is_keyword(<<"or">>) -> true; is_keyword(<<"repeat">>) -> true; is_keyword(<<"return">>) -> true; is_keyword(<<"then">>) -> true; is_keyword(<<"true">>) -> true; is_keyword(<<"until">>) -> true; is_keyword(<<"while">>) -> true; is_keyword(_) -> false. luerl-1.2.3/src/luerl_comp_peep.erl0000664000175000017500000000721214677012037017676 0ustar debalancedebalance%% Copyright (c) 2013-2019 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_comp_peep.erl %% Author : Robert Virding %% Purpose : A basic LUA 5.3 compiler for Luerl. %% Does peep-hole optimisation in the compiler. -module(luerl_comp_peep). -include("luerl.hrl"). -include("luerl_comp.hrl"). -include("luerl_instrs.hrl"). -export([chunk/2]). %% chunk(Code, CompInfo) -> {ok,Code}. %% A chunk is now a list of instructions to define the function. chunk(Is0, #cinfo{opts=Opts}=_Ci) -> Is1 = instrs(Is0, nil), %No local state luerl_comp:debug_print(Opts, "cp: ~p\n", [Is1]), {ok,Is1}. %% Combining instructions. instrs([?PUSH_LIT(L),?GET_KEY|Is], St) -> instrs([?GET_LIT_KEY(L)|Is], St); instrs([?PUSH_LIT(L),?SET_KEY|Is], St) -> instrs([?SET_LIT_KEY(L)|Is], St); %% Must check these properly, probably seldom used anyway. %% instrs([?STORE_EVAR(D, I),?PUSH_EVAR(D, I)|Is], St) -> %% instrs([?DUP,?STORE_EVAR(D, I)|Is], St); %% instrs([?STORE_LVAR(D, I),?PUSH_LVAR(D, I)|Is], St) -> %% instrs([?DUP,?STORE_LVAR(D, I)|Is], St); %% instrs([?STORE_GVAR(K),?PUSH_GVAR(K)|Is], St) -> %% instrs([?DUP,?STORE_EVAR(D, I)|Is], St); instrs([?PUSH_LIT(L),?MULTIPLE|Is], St) -> instrs([?PUSH_LAST_LIT(L)|Is], St); instrs([?PUSH_LVAR(D, I),?MULTIPLE|Is], St) -> instrs([?PUSH_LAST_LVAR(D, I)|Is], St); instrs([?PUSH_EVAR(D, I),?MULTIPLE|Is], St) -> instrs([?PUSH_LAST_EVAR(D, I)|Is], St); instrs([?PUSH_GVAR(K),?MULTIPLE|Is], St) -> instrs([?PUSH_LAST_GVAR(K)|Is], St); instrs([?POP,?POP|Is], St) -> instrs([?POP2|Is], St); %% Doing sub instructions. instrs([?PUSH_FDEF(Anno,Lsz,Esz,Pars,Fis0)|Is], St) -> Fis1 = instrs(Fis0, St), [?PUSH_FDEF(Anno,Lsz,Esz,Pars,Fis1)|instrs(Is, St)]; instrs([?BLOCK(Lsz,Esz,Bis0)|Is], St) -> Bis1 = instrs(Bis0, St), [?BLOCK(Lsz,Esz,Bis1)|instrs(Is, St)]; instrs([?REPEAT(Ris0)|Is], St) -> Ris1 = instrs(Ris0, St), [?REPEAT(Ris1)|instrs(Is, St)]; instrs([?WHILE(Eis0, Wis0)|Is], St) -> Eis1 = instrs(Eis0, St), Wis1 = instrs(Wis0, St), [?WHILE(Eis1, Wis1)|instrs(Is, St)]; instrs([?AND_THEN(Tis0)|Is], St) -> Tis1 = instrs(Tis0, St), [?AND_THEN(Tis1)|instrs(Is, St)]; instrs([?OR_ELSE(Fis0)|Is], St) -> Fis1 = instrs(Fis0, St), [?OR_ELSE(Fis1)|instrs(Is, St)]; instrs([?IF_TRUE(Tis0)|Is], St) -> Tis1 = instrs(Tis0, St), [?IF_TRUE(Tis1)|instrs(Is, St)]; instrs([?IF(Tis, [])|Is], St) -> instrs([?IF_TRUE(Tis)|Is], St); instrs([?IF(Tis0, Fis0)|Is], St) -> Tis1 = instrs(Tis0, St), Fis1 = instrs(Fis0, St), [?IF(Tis1, Fis1)|instrs(Is, St)]; instrs([?NFOR(V, Fis0)|Is], St) -> Fis1 = instrs(Fis0, St), [?NFOR(V, Fis1)|instrs(Is, St)]; instrs([?GFOR(Vs, Fis0)|Is], St) -> Fis1 = instrs(Fis0, St), [?GFOR(Vs, Fis1)|instrs(Is, St)]; %% Tail calls for when they are implemented in the VM. %% instrs([?FCALL,?POP], _St) -> [?TAIL_FCALL]; %% instrs([?FCALL,?RETURN(_)|_], _St) -> [?TAIL_FCALL]; %% instrs([?MCALL(M),?POP], _St) -> [?TAIL_MCALL(M)]; %% instrs([?MCALL(M),?RETURN(_)|_], _St) -> [?TAIL_MCALL(M)]; %% Nothing to do. instrs([I|Is], St) -> [I|instrs(Is, St)]; instrs([], _) -> []. luerl-1.2.3/src/Elixir.Luerl.New.erl0000664000175000017500000001005214677012037017566 0ustar debalancedebalance%% Copyright (c) 2013-2021 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_ex.erl %% Authors : Cees de Groot %% Purpose : Elixir-style wrappers for luerl.erl %% This module just contains functions that forward to luerl.erl, but place %% the VM State arguments in the first position rather than the last. This %% better matches Elixir conventions and allows for using the Elixir pipe %% operator '|>' to chain Luerl function calls. -module('Elixir.Luerl.New'). %% Basic user API to luerl. -export([init/0,gc/1, load/2,load/3,loadfile/2,loadfile/3, load_module/3,load_module_dec/3, do/2,do_dec/2,do/3,do_dec/3, dofile/2,dofile/3,dofile_dec/2,dofile_dec/3, call/3,call_chunk/2,call_chunk/3, call_function/3,call_function_dec/3, call_method/4,call_method_dec/4, get_table_keys/2,get_table_keys_dec/2, set_table_keys/3,set_table_keys_dec/3, get_stacktrace/1 ]). %% Tracing. -export([set_trace_func/2,clear_trace_func/1, set_trace_data/2,get_trace_data/1]). %% Encoding and decoding. -export([encode/2,encode_list/2,decode/2,decode_list/2]). %%Helping with storing VM state -export([externalize/1,internalize/1]). init() -> luerl_new:init(). gc(St) -> luerl_new:gc(St). set_trace_func(St, Func) -> luerl_new:set_trace_func(Func, St). clear_trace_func(St) -> luerl_new:clear_trace_func(St). get_trace_data(St) -> luerl_new:get_trace_data(St). set_trace_data(St, Tdata) -> luerl_new:set_trace_data(Tdata, St). load(St, Bin) -> luerl_new:load(Bin, St). load(St, Bin, Opts) -> luerl_new:load(Bin, Opts, St). loadfile(St, Name) -> luerl_new:loadfile(Name, St). loadfile(St, Name, Opts) -> luerl_new:loadfile(Name, Opts, St). load_module(St, Lfp, Mod) -> luerl_new:load_module(Lfp, Mod, St). load_module_dec(St, Dfp, Mod) -> luerl_new:load_module_dec(Dfp, Mod, St). do(St, S) -> luerl_new:do(S, St). do(St, S, Opts) -> luerl_new:do(S, Opts, St). do_dec(St, S) -> luerl_new:do_dec(S, St). do_dec(St, S, Opts) -> luerl_new:do_dec(S, Opts, St). dofile(St, Path) -> luerl_new:dofile(Path, St). dofile(St, Path, Opts) -> luerl_new:dofile(Path, Opts, St). dofile_dec(St, Path) -> luerl_new:dofile_dec(Path, St). dofile_dec(St, Path, Opts) -> luerl_new:dofile_dec(Path, Opts, St). call(St, C, Args) -> luerl_new:call(C, Args, St). call_chunk(St, C) -> luerl_new:call_chunk(C, St). call_chunk(St, C, Args) -> luerl_new:call_chunk(C, Args, St). call_function(St, Fp, Args) -> luerl_new:call_function(Fp, Args, St). call_function_dec(St, Dfunc, Dargs) -> luerl_new:call_function_dec(Dfunc, Dargs, St). call_method(St, Obj, Meth, Args) -> luerl_new:call_method(Obj, Meth, Args, St). call_method_dec(St, Dobj, Dmeth, Dargs) -> luerl_new:call_method_dec(Dobj, Dmeth, Dargs, St). get_table_keys(St, Keys) -> luerl_new:get_table_keys(Keys, St). get_table_keys_dec(St, Dkeys) -> luerl_new:get_table_keys_dec(Dkeys, St). set_table_keys(St, Keys, Val) -> luerl_new:set_table_keys(Keys, Val, St). set_table_keys_dec(St, Dkeys, Dval) -> luerl_new:set_table_keys_dec(Dkeys, Dval, St). get_stacktrace(St) -> luerl_new:get_stacktrace(St). encode(St, V) -> luerl_new:encode(V, St). encode_list(St, Ts) -> luerl_new:encode_list(Ts, St). decode(St, V) -> luerl_new:decode(V, St). decode_list(St, Lts) -> luerl_new:decode_list(Lts, St). externalize(St) -> luerl_new:externalize(St). internalize(St) -> luerl_new:internalize(St). luerl-1.2.3/src/ttdict.erl0000664000175000017500000005532014677012037016022 0ustar debalancedebalance%% Copyright (c) 2013 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : ttdict.erl %% Author : Robert Virding %% Purpose : Key-Value dictionary as a 2-3 tree. %% This implementation uses 2-3 trees. The description of the tree %% restructuring which is used comes from Prof. Lyn Turbak's notes for %% CS230 Data Structures at Wellesley College. -module(ttdict). %% Standard interface. -export([new/0,is_key/2,to_list/1,from_list/1,size/1]). -export([fetch/2,find/2,fetch_keys/1,erase/2]). -export([store/3,append/3,append_list/3]). -export([update_val/3,update/3,update/4,update_counter/3]). -export([fold/3,map/2,filter/2,merge/3]). %% Extended interface. -export([foreach/2,mapfold/3]). %% Special interface. -export([first/1,last/1,next/2,prev/2]). %% Deprecated interface. -export([dict_to_list/1,list_to_dict/1]). -deprecated([{dict_to_list,1},{list_to_dict,1}]). -compile({no_auto_import,[size/1]}). %We mean our own size/1 -ifdef(DEBUG). -export([check_depth/1]). -endif. %% Data structure: %% - {Left,Key,Val,Right} %% - {Left,Key,Val,Middle,Key,Val,Right} %% - empty %% %% The term order is an arithmetic total order, so we should not %% test exact equality for the keys. (If we do, then it becomes %% possible that neither `>', `<', nor `=:=' matches.) Testing '<' %% and '>' first is statistically better than testing for %% equality, and also allows us to skip the test completely in the %% remaining case. %% %% In all the functions we test keys from left to right in the %% structure. This might not always be the best choice (is there any %% best choice?) but it makes the code consistent. -type ttdict() :: empty | {ttdict(),any(),any(),ttdict()} | {ttdict(),any(),any(),ttdict(),any(),any(),ttdict()}. -export_type([ttdict/0]). -spec new() -> Dict when Dict :: ttdict(). new() -> empty. %The empty dict -spec is_key(Key, Dict) -> boolean() when Key :: term(), Dict :: ttdict(). is_key(_, empty) -> false; is_key(Key, {L,Xk,_,_}) when Key < Xk -> is_key(Key, L); is_key(Key, {_,Xk,_,R}) when Key > Xk -> is_key(Key, R); is_key(_, {_,_,_,_}) -> true; %Key == Xk is_key(Key, {L,Xk,_,_,_,_,_}) when Key < Xk -> is_key(Key, L); is_key(Key, {_,Xk,_,M,Yk,_,R}) when Key > Xk -> if Key < Yk -> is_key(Key, M); Key > Yk -> is_key(Key, R); true -> true %Key == Yk end; is_key(_, {_,_,_,_,_,_,_}) -> true. %Key == Xk -spec to_list(Dict) -> List when Dict :: ttdict(), List :: [{Key :: term(),Value :: term()}]. to_list(D) -> to_list(D, []). to_list(empty, Tail) -> Tail; to_list({L,Xk,Xv,R}, Tail) -> to_list(L, [{Xk,Xv}|to_list(R, Tail)]); to_list({L,Xk,Xv,M,Yk,Yv,R}, Tail) -> to_list(L, [{Xk,Xv}|to_list(M, [{Yk,Yv}|to_list(R, Tail)])]). -spec from_list(List) -> Dict when List :: [{Key :: term(),Value :: term()}], Dict :: ttdict(). from_list(List) -> lists:foldl(fun ({K,V}, D) -> store(K, V, D) end, new(), List). -spec size(Dict) -> non_neg_integer() when Dict :: ttdict(). size(empty) -> 0; size({L,_,_,R}) -> size(L) + size(R) + 1; size({L,_,_,M,_,_,R}) -> size(L) + size(M) + size(R) + 2. -spec fetch(Key, Dict) -> Value when Key :: term(), Dict :: ttdict(), Value :: term(). fetch(K, {L,Xk,_,_}) when K < Xk -> fetch(K, L); fetch(K, {_,Xk,_,R}) when K > Xk -> fetch(K, R); fetch(_, {_,_,Xv,_}) -> Xv; fetch(K, {L,Xk,_,_,_,_,_}) when K < Xk -> fetch(K, L); fetch(K, {_,Xk,_,M,Yk,Yv,R}) when K > Xk -> if K < Yk -> fetch(K, M); %Middle K > Yk -> fetch(K, R); %Right true -> Yv end; fetch(_, {_,_,Xv,_,_,_,_}) -> Xv; fetch(_, empty) -> error(badarg). -spec find(Key, Dict) -> {ok,Value} | error when Key :: term(), Dict :: ttdict(), Value :: term(). find(K, {L,Xk,_,_}) when K < Xk -> find(K, L); find(K, {_,Xk,_,B}) when K > Xk -> find(K, B); find(_, {_,_,Xv,_}) -> {ok,Xv}; find(K, {L,Xk,_,_,_,_,_}) when K < Xk -> find(K, L); find(K, {_,Xk,_,M,Yk,Yv,R}) when K > Xk -> if K < Yk -> find(K, M); %Middle K > Yk -> find(K, R); %Right true -> {ok,Yv} end; find(_, {_,_,Xv,_,_,_,_}) -> {ok,Xv}; find(_, empty) -> error. -spec fetch_keys(Dict) -> Keys when Dict :: ttdict(), Keys :: [term()]. fetch_keys(D) -> fetch_keys(D, []). fetch_keys(empty, Tail) -> Tail; fetch_keys({L,Xk,_,R}, Tail) -> fetch_keys(L, [Xk|fetch_keys(R, Tail)]); fetch_keys({L,Xk,_,M,Yk,_,R}, Tail) -> fetch_keys(L, [Xk|fetch_keys(M, [Yk|fetch_keys(R, Tail)])]). -spec store(Key, Value, Dict1) -> Dict2 when Key :: term(), Value :: term(), Dict1 :: ttdict(), Dict2 :: ttdict(). store(Key, Val, T) -> %% Store and check for a returned "Up" node. case store_aux(Key, Val, T) of {up,Lu,Ku,Vu,Ru} -> {Lu,Ku,Vu,Ru}; Node -> Node end. store_aux(Key, Val, empty) -> {up,empty,Key,Val,empty}; %"Up" node store_aux(Key, Val, {empty,K,V,empty}) -> %% Special case to avoid creating temporary "up" nodes. %% It helps a little bit, but not much. if Key < K -> {empty,Key,Val,empty,K,V,empty}; Key > K -> {empty,K,V,empty,Key,Val,empty}; true -> {empty,K,Val,empty} end; store_aux(Key, Val, {L,K,V,R}) -> if Key < K -> %Down the left store_up2_l(store_aux(Key, Val, L), K, V, R); Key > K -> %Down the right store_up2_r(L, K, V, store_aux(Key, Val, R)); true -> {L,K,Val,R} %Replace current value end; store_aux(Key, Val, {L,Xk,Xv,M,Yk,Yv,R}) when Key < Xk -> store_up3_l(store_aux(Key, Val, L), Xk, Xv, M, Yk, Yv, R); store_aux(Key, Val, {L,Xk,Xv,M,Yk,Yv,R}) when Key > Xk -> if Key < Yk -> %Down the middle store_up3_m(L, Xk, Xv, store_aux(Key, Val, M), Yk, Yv, R); Key > Yk -> %Down the right store_up3_r(L, Xk, Xv, M, Yk, Yv, store_aux(Key, Val, R)); true -> {L,Xk,Xv,M,Yk,Val,R} end; store_aux(_, Val, {L,Xk,_,M,Yk,Yv,R}) -> %Key == Xk {L,Xk,Val,M,Yk,Yv,R}. -spec append(Key, Value, Dict1) -> Dict2 when Key :: term(), Value :: term(), Dict1 :: ttdict(), Dict2 :: ttdict(). append(Key, Val, T) -> %% Append and check for a returned "Up" node. case append_aux(Key, [Val], T) of {up,Lu,Ku,Vu,Ru} -> {Lu,Ku,Vu,Ru}; Node -> Node end. -spec append_list(Key, Values, Dict1) -> Dict2 when Key :: term(), Values :: [Value :: term()], Dict1 :: ttdict(), Dict2 :: ttdict(). append_list(Key, Val, T) -> %% Append and check for a returned "Up" node. case append_aux(Key, Val, T) of {up,Lu,Ku,Vu,Ru} -> {Lu,Ku,Vu,Ru}; Node -> Node end. append_aux(Key, Val, empty) -> {up,empty,Key,Val,empty}; %"Up" node append_aux(Key, Val, {L,K,V,R}) -> if Key < K -> %Down the left store_up2_l(append_aux(Key, Val, L), K, V, R); Key > K -> %Down the right store_up2_r(L, K, V, append_aux(Key, Val, R)); true -> {L,Key,V ++ Val,R} %Append to current value end; append_aux(Key, Val, {L,Xk,Xv,M,Yk,Yv,R}) when Key < Xk -> store_up3_l(append_aux(Key, Val, L), Xk, Xv, M, Yk, Yv, R); append_aux(Key, Val, {L,Xk,Xv,M,Yk,Yv,R}) when Key > Xk -> if Key < Yk -> store_up3_m(L, Xk, Xv, append_aux(Key, Val, M), Yk, Yv, R); Key > Yk -> store_up3_r(L, Xk, Xv, M, Yk, Yv, append_aux(Key, Val, R)); true -> {L,Xk,Xv,M,Key,Yv ++ Val,R} end; append_aux(Key, Val, {L,_,Xv,M,Yk,Yv,R}) -> {L,Key,Xv ++ Val,M,Yk,Yv,R}. -spec update_val(Key, Value, Dict1) -> Dict2 when Key :: term(), Value :: term(), Dict1 :: ttdict(), Dict2 :: ttdict(). update_val(Key, Val, {L,Xk,Xv,R}) -> if Key < Xk -> {update_val(Key, Val, L),Xk,Xv,R}; Key > Xk -> {L,Xk,Xv,update_val(Key, Val, R)}; true -> {L,Xk,Val,R} end; update_val(Key, Val, {L,Xk,Xv,M,Yk,Yv,R}) when Key < Xk -> {update_val(Key, Val, L),Xk,Xv,M,Yk,Yv,R}; update_val(Key, Val, {L,Xk,Xv,M,Yk,Yv,R}) when Key > Xk -> if Key < Yk -> {L,Xk,Xv,update_val(Key, Val, M),Yk,Yv,R}; Key > Yk -> {L,Xk,Xv,M,Yk,Yv,update_val(Key, Val, R)}; true -> {L,Xk,Xv,M,Yk,Val,R} end; update_val(_, Val, {L,Xk,_,M,Yk,Yv,R}) -> %Key == Xk {L,Xk,Val,M,Yk,Yv,R}. -spec update(Key, Fun, Dict1) -> Dict2 when Key :: term(), Fun :: fun((Value1 :: term()) -> Value2 :: term()), Dict1 :: ttdict(), Dict2 :: ttdict(). update(Key, Fun, {L,Xk,Xv,R}) -> if Key < Xk -> {update(Key, Fun, L),Xk,Xv,R}; Key > Xk -> {L,Xk,Xv,update(Key, Fun, R)}; true -> {L,Xk,Fun(Xv),R} %Key == Xk end; update(Key, Fun, {L,Xk,Xv,M,Yk,Yv,R}) when Key < Xk -> {update(Key, Fun, L),Xk,Xv,M,Yk,Yv,R}; update(Key, Fun, {L,Xk,Xv,M,Yk,Yv,R}) when Key > Xk -> if Key < Yk -> {L,Xk,Xv,update(Key, Fun, M),Yk,Yv,R}; Key > Yk -> {L,Xk,Xv,M,Yk,Yv,update(Key, Fun, R)}; true -> {L,Xk,Xv,M,Yk,Fun(Yv),R} end; update(_, Fun, {L,Xk,Xv,M,Yk,Yv,R}) -> %Key == Xk {L,Xk,Fun(Xv),M,Yk,Yv,R}. -spec update(Key, Fun, Initial, Dict1) -> Dict2 when Key :: term, Initial :: term(), Fun :: fun((Value :: term()) -> Value2 :: term()), Dict1 :: ttdict(), Dict2 :: ttdict(). update(Key, Fun, I, T) -> case update_aux(Key, Fun, I, T) of {up,Lu,Ku,Vu,Ru} -> {Lu,Ku,Vu,Ru}; Node -> Node end. update_aux(Key, _, I, empty) -> {up,empty,Key,I,empty}; update_aux(Key, Fun, I, {L,Xk,Xv,R}) -> if Key < Xk -> store_up2_l(update_aux(Key, Fun, I, L), Xk, Xv, R); Key > Xk -> store_up2_r(L, Xk, Xv, update_aux(Key, Fun, I, R)); true -> {L,Xk,Fun(Xv),R} end; update_aux(Key, Fun, I, {L,Xk,Xv,M,Yk,Yv,R}) when Key < Xk -> store_up3_l(update_aux(Key, Fun, I, L), Xk, Xv, M, Yk, Yv, R); update_aux(Key, Fun, I, {L,Xk,Xv,M,Yk,Yv,R}) when Key > Xk -> if Key < Yk -> store_up3_m(L, Xk, Xv, update_aux(Key, Fun, I, M), Yk, Yv, R); Key > Yk -> store_up3_r(L, Xk, Xv, M, Yk, Yv, update_aux(Key, Fun, I, R)); true -> {L,Xk,Xv,M,Key,Fun(Yv),R} end; update_aux(_, Fun, _, {L,Xk,Xv,M,Yk,Yv,R}) -> %Key == Xk {L,Xk,Fun(Xv),M,Yk,Yv,R}. -spec update_counter(Key, Increment, Dict1) -> Dict2 when Key :: term(), Increment :: number(), Dict1 :: ttdict(), Dict2 :: ttdict(). update_counter(Key, I, T) -> case update_counter_aux(Key, I, T) of {up,Lu,Ku,Vu,Ru} -> {Lu,Ku,Vu,Ru}; Node -> Node end. update_counter_aux(Key, I, empty) -> {up,empty,Key,I,empty}; update_counter_aux(Key, I, {L,Xk,Xv,R}) -> if Key < Xk -> store_up2_l(update_counter_aux(Key, I, L), Xk, Xv, R); Key > Xk -> store_up2_r(L, Xk, Xv, update_counter_aux(Key, I, R)); true -> {L,Xk,Xv+I,R} end; update_counter_aux(Key, I, {L,Xk,Xv,M,Yk,Yv,R}) when Key < Xk -> store_up3_l(update_counter_aux(Key, I, L), Xk, Xv, M, Yk, Yv, R); update_counter_aux(Key, I, {L,Xk,Xv,M,Yk,Yv,R}) when Key > Xk -> if Key < Yk -> store_up3_m(L, Xk, Xv, update_counter_aux(Key, I, M), Yk, Yv, R); Key > Yk -> store_up3_r(L, Xk, Xv, M, Yk, Yv, update_counter_aux(Key, I, R)); true -> {L,Xk,Xv,M,Yk,Yv+I,R} end; update_counter_aux(_, I, {L,Xk,Xv,B,Yk,Yv,R}) -> %Key == Xk {L,Xk,Xv+I,B,Yk,Yv,R}. %% store_up2_l/r(L, K, V, R) -> {L,Xk,Xv,M,Yk,Yv,R} | {L,K,V,R}. store_up2_l({up,Lu,Ku,Vu,Ru}, K, V, R) -> {Lu,Ku,Vu,Ru,K,V,R}; store_up2_l(L, K, V, R) -> {L,K,V,R}. store_up2_r(L, K, V, {up,Lu,Ku,Vu,Ru}) -> {L,K,V,Lu,Ku,Vu,Ru}; store_up2_r(L, K, V, R) -> {L,K,V,R}. %% store_up3_l/m/r(L, Xk, Xv, M, Yk, Yv, R) -> %% {up,L,K,V,R} | {L,Xk,Xv,M,Yk,Yv,R}. store_up3_l({up,Lu,Ku,Vu,Ru}, Xk, Xv, M, Yk, Yv, R) -> {up,{Lu,Ku,Vu,Ru},Xk,Xv,{M,Yk,Yv,R}}; store_up3_l(L, Xk, Xv, M, Yk, Yv, R) -> {L,Xk,Xv,M,Yk,Yv,R}. store_up3_m(L, Xk, Xv, {up,Lu,Ku,Vu,Ru}, Yk, Yv, R) -> {up,{L,Xk,Xv,Lu},Ku,Vu,{Ru,Yk,Yv,R}}; store_up3_m(L, Xk, Xv, M, Yk, Yv, R) -> {L,Xk,Xv,M,Yk,Yv,R}. store_up3_r(L, Xk, Xv, M, Yk, Yv, {up,Lu,Ku,Vu,Ru}) -> {up,{L,Xk,Xv,M},Yk,Yv,{Lu,Ku,Vu,Ru}}; store_up3_r(L, Xk, Xv, M, Yk, Yv, R) -> {L,Xk,Xv,M,Yk,Yv,R}. -spec erase(Key, Dict1) -> Dict2 when Key :: term(), Dict1 :: ttdict(), Dict2 :: ttdict(). erase(Key, T) -> case erase_aux(Key, T) of {up,T1} -> T1; %??? T1 -> T1 end. erase_aux(_, empty) -> empty; %No element erase_aux(Key, {empty,Xk,_,empty}=N) -> if Key < Xk; Key > Xk -> N; %No element true -> {up,empty} end; erase_aux(Key, {L,Xk,Xv,R}) -> if Key < Xk -> %Down the left erase_up2_l(erase_aux(Key, L), Xk, Xv, R); Key > Xk -> %Down the right erase_up2_r(L, Xk, Xv, erase_aux(Key, R)); true -> {{Km,Vm},R1}= erase_min(R), erase_up2_r(L, Km, Vm, R1) end; erase_aux(Key, {empty,Xk,Xv,empty,Yk,Yv,empty}=N) -> if Key < Xk -> N; %No element Key > Xk -> if Key < Yk -> N; %No element Key > Yk -> N; true -> {empty,Xk,Xv,empty} end; true -> {empty,Yk,Yv,empty} end; erase_aux(Key, {L,Xk,Xv,M,Yk,Yv,R}) when Key < Xk -> erase_up3_l(erase_aux(Key, L), Xk, Xv, M, Yk, Yv, R); erase_aux(Key, {L,Xk,Xv,M,Yk,Yv,R}) when Key > Xk -> if Key < Yk -> erase_up3_m(L, Xk, Xv, erase_aux(Key, M), Yk, Yv, R); Key > Yk -> erase_up3_r(L, Xk, Xv, M, Yk, Yv, erase_aux(Key, R)); true -> {{Km,Vm},R1} = erase_min(R), erase_up3_r(L, Xk, Xv, M, Km, Vm, R1) end; erase_aux(_, {L,_,_,M,Yk,Yv,R}) -> {{Km,Vm},M1} = erase_min(M), erase_up3_m(L, Km, Vm, M1, Yk, Yv, R). erase_min(T) -> %%io:format("em: ~p\n-> ~p\n", [T,T1]), erase_min1(T). erase_min1({empty,Xk,Xv,empty}) -> {{Xk,Xv},{up,empty}}; erase_min1({L,Xk,Xv,R}) -> {Min,L1} = erase_min1(L), {Min,erase_up2_l(L1, Xk, Xv, R)}; erase_min1({empty,Xk,Xv,empty,Yk,Yv,empty}) -> {{Xk,Xv},{empty,Yk,Yv,empty}}; erase_min1({L,Xk,Xv,M,Yk,Yv,R}) -> {Min,L1} = erase_min1(L), {Min,erase_up3_l(L1, Xk, Xv, M, Yk, Yv, R)}. %% erase_up2_l/r(L, K, V, R) -> Node | {up,Node}. %% We use the same naming of nodes and keys as in the text. It makes %% checking the rules easier. erase_up2_l({up,L}, Xk, Xv, {M,Yk,Yv,R}) -> %1.1 {up,{L,Xk,Xv,M,Yk,Yv,R}}; erase_up2_l({up,A}, Xk, Xv, {B,Yk,Yv,C,Zk,Zv,D}) -> %2.1 {{A,Xk,Xv,B},Yk,Yv,{C,Zk,Zv,D}}; erase_up2_l(L, K, V, R) -> {L,K,V,R}. erase_up2_r({L,Xk,Xv,M}, Yk, Yv, {up,R}) -> %1.2 {up,{L,Xk,Xv,M,Yk,Yv,R}}; erase_up2_r({A,Xk,Xv,B,Yk,Yv,C}, Zk, Zv, {up,D}) -> %2.2 {{A,Xk,Xv,B},Yk,Yv,{C,Zk,Zv,D}}; erase_up2_r(L, K, V, R) -> {L,K,V,R}. %% erase_up2_r(L, K, V, {up,R}) -> erase_up2_r1(L, K, V, R); %% erase_up2_r(L, K, V, R) -> {L,K,V,R}. %% erase_up2_r1({L,Xk,Xv,M}, Yk, Yv, R) -> %1.2 %% {up,{L,Xk,Xv,M,Yk,Yv,R}}; %% erase_up2_r1({A,Xk,Xv,B,Yk,Yv,C}, Zk, Zv, D) -> %2.2 %% {{A,Xk,Xv,B},Yk,Yv,{C,Zk,Zv,D}}. %% erase_up3_l/m/r(L, Xk, Xv, M, Yk, Yv, R) -> Node | {up,Node}. %% We use the same naming of nodes and keys as in the text. It makes %% checking the rules easier. N.B. there are alternate valid choices %% for the middle case! erase_up3_l({up,A}, Xk, Xv, {B,Yk,Yv,C}, Zk, Zv, D) -> %3a.1 {{A,Xk,Xv,B,Yk,Yv,C},Zk,Zv,D}; erase_up3_l({up,A}, Wk, Wv, {B,Xk,Xv,C,Yk,Yv,D}, Zk, Zv, E) -> %4a.1 {{A,Wk,Wv,B},Xk,Xv,{C,Yk,Yv,D},Zk,Zv,E}; erase_up3_l(A, Xk, Xv, B, Yk, Yv, C) -> {A,Xk,Xv,B,Yk,Yv,C}. erase_up3_m({A,Xk,Xv,B}, Yk, Yv, {up,C}, Zk, Zv, D) -> %3a.2 {{A,Xk,Xv,B,Yk,Yv,C},Zk,Zv,D}; erase_up3_m(A, Xk, Xv, {up,B}, Yk, Yv, {C,Zk,Zv,D}) -> %3b.1 {A,Xk,Xv,{B,Yk,Yv,C,Zk,Zv,D}}; erase_up3_m({A,Wk,Wv,B,Xk,Xv,C}, Yk, Yv, {up,D}, Zk, Zv, E) -> %4a.2 {{A,Wk,Wv,B},Xk,Xv,{C,Yk,Yv,D},Zk,Zv,E}; erase_up3_m(A, Wk, Wv, {up,B}, Xk, Xv, {C,Yk,Yv,D,Zk,Zv,E}) -> %4b.1 {A,Wk,Wv,{B,Xk,Xv,C},Yk,Yv,{D,Zk,Zv,E}}; erase_up3_m(A, Xk, Xv, B, Yk, Yv, C) -> {A,Xk,Xv,B,Yk,Yv,C}. erase_up3_r(A, Xk, Xv, {B,Yk,Yv,C}, Zk, Zv, {up,D}) -> %3b.2 {A,Xk,Xv,{B,Yk,Yv,C,Zk,Zv,D}}; erase_up3_r(A, Wk, Wv, {B,Xk,Xv,C,Yk,Yv,D}, Zk, Zv, {up,E}) -> %4b.2 {A,Wk,Wv,{B,Xk,Xv,C},Yk,Yv,{D,Zk,Zv,E}}; erase_up3_r(A, Xk, Xv, B, Yk, Yv, C) -> {A,Xk,Xv,B,Yk,Yv,C}. -spec fold(Fun, Acc0, Dict) -> Acc1 when Fun :: fun((Key, Value, AccIn) -> AccOut), Key :: term(), Value :: term(), Acc0 :: term(), Acc1 :: term(), AccIn :: term(), AccOut :: term(), Dict :: ttdict(). %% Apply Fun to each element in Dict. Do it left to right, even if %% this is not specified. fold(_, Acc, empty) -> Acc; fold(F, Acc, {L,Xk,Xv,R}) -> fold(F, F(Xk, Xv, fold(F, Acc, R)), L); fold(F, Acc, {L,Xk,Xv,M,Yk,Yv,R}) -> fold(F, F(Xk, Xv, fold(F, F(Yk, Yv, fold(F, Acc, R)), M)), L). -spec map(Fun, Dict1) -> Dict2 when Fun :: fun((Key :: term(), Value1 :: term()) -> Value2 :: term()), Dict1 :: ttdict(), Dict2 :: ttdict(). %% Apply Fun to each element in Dict. Do it left to right, even if %% this is not specified. map(_, empty) -> empty; map(F, {A,Xk,Xv,B}) -> {map(F, A),Xk,F(Xk, Xv),map(F, B)}; map(F, {A,Xk,Xv,B,Yk,Yv,C}) -> {map(F, A),Xk,F(Xk, Xv),map(F, B),Yk,F(Yk, Yv),map(F, C)}. -spec filter(Pred, Dict1) -> Dict2 when Pred :: fun((Key :: term(), Value :: term()) -> boolean()), Dict1 :: ttdict(), Dict2 :: ttdict(). %% Apply Fun to each element in Dict. Do it left to right, even if %% this is not specified. filter(F, D) -> filter(F, D, new()). filter(_, empty, New) -> New; filter(F, {L,Xk,Xv,R}, New0) -> New1 = filter(F, L, New0), New2 = case F(Xk, Xv) of true -> store(Xk, Xv, New1); false -> New1 end, filter(F, R, New2); filter(F, {L,Xk,Xv,M,Yk,Yv,R}, New0) -> New1 = filter(F, L, New0), New2 = case F(Xk, Xv) of true -> store(Xk, Xv, New1); false -> New1 end, New3 = filter(F, M, New2), New4 = case F(Yk, Yv) of true -> store(Yk, Yv, New3); false -> New3 end, filter(F, R, New4). -spec merge(Fun, Dict1, Dict2) -> Dict3 when Fun :: fun((Key :: term(), Value1 :: term(), Value2 :: term()) -> Value :: term()), Dict1 :: ttdict(), Dict2 :: ttdict(), Dict3 :: ttdict(). merge(F, D1, D2) -> fold(fun (K, V2, D) -> update(K, fun(V1) -> F(K, V1, V2) end, V2, D) end, D1, D2). %% Extended interface. -spec foreach(Fun, Dict) -> ok when Fun :: fun((Key :: term(), Value :: term()) -> term()), Dict :: ttdict(). %% Apply Fun to each element in Dict. Do it left to right, even if %% this is not specified. foreach(_, empty) -> ok; foreach(F, {L,Xk,Xv,R}) -> foreach(F, L), F(Xk, Xv), foreach(F, R); foreach(F, {L,Xk,Xv,M,Yk,Yv,R}) -> foreach(F, L), F(Xk, Xv), foreach(F, M), F(Yk, Yv), foreach(F, R). -spec mapfold(Fun, Acc0, Dict1) -> {Dict2,Acc1} when Fun :: fun((Key, Value1, AccIn) -> {Value2,AccOut}), Acc0 :: term(), Acc1 :: term(), Key :: term(), Value1 :: term(), Value2 :: term(), AccIn :: term(), AccOut :: term(), Dict1 :: ttdict(), Dict2 :: ttdict(). %% Apply Fun to each element in Dict. Do it left to right, even if %% this is not specified. mapfold(_, Acc, empty) -> {empty,Acc}; mapfold(F, Acc0, {L0,Xk,Xv0,R0}) -> {L1,Acc1} = mapfold(F, Acc0, L0), {Xv1,Acc2} = F(Xk, Xv0, Acc1), {R1,Acc3} = mapfold(F, Acc2, R0), {{L1,Xk,Xv1,R1},Acc3}; mapfold(F, Acc0, {L0,Xk,Xv0,M0,Yk,Yv0,R0}) -> {L1,Acc1} = mapfold(F, Acc0, L0), {Xv1,Acc2} = F(Xk, Xv0, Acc1), {M1,Acc3} = mapfold(F, Acc2, M0), {Yv1,Acc4} = F(Yk, Yv0, Acc3), {R1,Acc5} = mapfold(F, Acc4, R0), {{L1,Xk,Xv1,M1,Yk,Yv1,R1},Acc5}. %% Special interface. -spec first(Dict) -> error | {ok,{Key1,Value}} when Key1 :: term(), Value :: term(), Dict :: ttdict(). first(empty) -> error; first({L,Xk,Xv,_}) -> case first(L) of error -> {ok,{Xk,Xv}}; First -> First end; first({L,Xk,Xv,_,_,_,_}) -> case first(L) of error -> {ok,{Xk,Xv}}; First -> First end. -spec last(Dict) -> error | {ok,{Key1,Value}} when Key1 :: term(), Value :: term(), Dict :: ttdict(). last(empty) -> error; last({_,Xk,Xv,R}) -> case last(R) of error -> {ok,{Xk,Xv}}; Last -> Last end; last({_,_,_,_,Yk,Yv,R}) -> case last(R) of error -> {ok,{Yk,Yv}}; Last -> Last end. -spec next(Key, Dict) -> error | {ok,{Key1,Value}} when Key :: term(), Key1 :: term(), Value :: term(), Dict :: ttdict(). next(_, empty) -> error; next(K, {L,Xk,Xv,_}) when K < Xk -> case next(K, L) of error -> {ok,{Xk,Xv}}; Next -> Next end; next(K, {_,Xk,_,R}) when K > Xk -> next(K, R); next(_, {_,_,_,R}) -> first(R); %when K == Xk next(K, {L,Xk,Xv,_,_,_,_}) when K < Xk -> case next(K, L) of error -> {ok,{Xk,Xv}}; Next -> Next end; next(K, {_,Xk,_,M,Yk,Yv,R}) when K > Xk -> if K < Yk -> case next(K, M) of error -> {ok,{Yk,Yv}}; Next -> Next end; K > Yk -> next(K, R); true -> first(R) %when K == Yk end; next(_, {_,_,_,M,Yk,Yv,_}) -> %when K == Xk case first(M) of error -> {ok,{Yk,Yv}}; First -> First end. -spec prev(Key, Dict) -> error | {ok,{Key1,Value}} when Key :: term(), Key1 :: term(), Value :: term(), Dict :: ttdict(). %% Go from right to left here as it makes it easier to understand %% what is going on. prev(_, empty) -> error; prev(K, {_,Xk,Xv,R}) when K > Xk -> case prev(K, R) of error -> {ok,{Xk,Xv}}; Prev -> Prev end; prev(K, {L,Xk,_,_}) when K < Xk -> prev(K, L); prev(_, {L,_,_,_}) -> last(L); %when K == Xk prev(K, {_,_,_,_,Yk,Yv,R}) when K > Yk -> case prev(K, R) of error -> {ok,{Yk,Yv}}; Prev -> Prev end; prev(K, {L,Xk,Xv,M,Yk,_,_}) when K < Yk -> if K > Xk -> case prev(K, M) of error -> {ok,{Xk,Xv}}; Prev -> Prev end; K < Xk -> prev(K, L); true -> last(L) %when K == Xk end; prev(_, {_,Xk,Xv,M,_,_,_}) -> %when K == Yk case last(M) of error -> {ok,{Xk,Xv}}; Prev -> Prev end. %% Deprecated interface. %% dict_to_list(Dictionary) -> [{Key,Value}]. dict_to_list(D) -> to_list(D). %% list_to_dict([{Key,Value}]) -> Dictionary. list_to_dict(L) -> from_list(L). -ifdef(DEBUG). %% Check the depth of all the leaves, should all be the same. check_depth(T) -> check_depth(T, 1, orddict:new()). check_depth(empty, D, Dd) -> orddict:update_counter(D, 1, Dd); check_depth({L,_,_,R}, D, Dd0) -> Dd1 = orddict:update_counter(two, 1, Dd0), Dd2 = check_depth(L, D+1, Dd1), check_depth(R, D+1, Dd2); check_depth({L,_,_,M,_,_,R}, D, Dd0) -> Dd1 = orddict:update_counter(three, 1, Dd0), Dd2 = check_depth(L, D+1, Dd1), Dd3 = check_depth(M, D+1, Dd2), check_depth(R, D+1, Dd3). -endif. luerl-1.2.3/src/luerl.hrl0000664000175000017500000002005214677012037015647 0ustar debalancedebalance%% Copyright (c) 2013-2024 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl.hrl %% Author : Robert Virding %% Purpose : The basic macros/records for Luerl. %% We include the whole environment in one structure even if fields %% come from logically different parts. This make it easier to pass %% around but does mean that there will be more explicit fiddleling to %% get it right. See block/2 and functioncall/4 for examples of this. -record(luerl, {tabs, %Table table envs, %Environment table usds, %Userdata table fncs, %Function table g, %Global table %% stk=[], %Current stack cs=[], %Current call stack %% meta=[], %Data type metatables rand, %Random state tag, %Unique tag trace_func=none, %Trace function trace_data %Trace data }). %% Table structure. -record(tstruct, {data, %Data table/array free, %Index free list next %Next index }). %% Metatables for atomic datatypes. -record(meta, {nil=nil, boolean=nil, number=nil, string=nil }). %% Frames for the call stack. %% Call return frame -record(call_frame, {func,args, %Function, arguments lvs, %Local variables env, %Environment is=[], %Instructions cont=[] %Continuation }). %% Loop break frame -record(loop_frame, {lvs, %Local variables stk, %Stack env, %Environment is=[], %Instructions cont=[] %Continuation }). %% Current line -record(current_line, {line, %Line file %File name }). %% Return -record(return, {rets %Return values }). %% Data types. -record(tref, {i}). %Table reference, index -define(IS_TREF(T), is_record(T, tref)). -record(table, {a,d=[],meta=nil}). %Table type, array, dict, meta -record(eref, {i}). %Environment reference, index -define(IS_EREF(E), is_record(E, eref)). -record(usdref, {i}). %Userdata reference, index -define(IS_USDREF(U), is_record(U, usdref)). -record(userdata, {d,meta=nil}). %Userdata type, data and meta -record(thread, {}). %Thread type %% There are two function types, the Lua one, and the Erlang one. %% The environment with upvalues is defined when the function is %% referenced and can vary if the function is referenced many %% times. Hence it is in the reference not in the the definition. -record(funref, {i,env=[]}). %Function reference -define(IS_FUNREF(F), is_record(F, funref)). -record(lua_func,{anno=[], %Annotation funrefs=[], %Functions directly referenced lsz, %Local var size %% loc=not_used, %Local var block template esz, %Env var size %% env=not_used, %Local env block template pars, %Parameter types body}). %Code block -define(IS_LUAFUNC(F), is_record(F, lua_func)). -record(erl_func,{code}). %Erlang code (fun) -define(IS_ERLFUNC(F), is_record(F, erl_func)). -record(erl_mfa,{m,f,a}). %Erlang code (MFA) -define(IS_ERLMFA(F), is_record(F, erl_mfa)). %% Test if it a function, of either sort. -define(IS_FUNCTION(F), (?IS_FUNREF(F) orelse ?IS_ERLFUNC(F) orelse ?IS_ERLMFA(F))). %% Testing for integers/integer floats or booleans. -define(IS_FLOAT_INT(N), (round(N) == N)). -define(IS_FLOAT_INT(N,I), ((I=round(N)) == N)). -define(IS_TRUE(X), (((X) =/= nil) and ((X) =/= false))). %% Different methods for storing tables in the global data #luerl{}. %% Access through macros to allow testing with different storage %% methods. This is inefficient with ETS tables where it would %% probably be better to use bags and access with match/select. %% Set which table store to use. We check if we have full maps before %% we use them just to protect ourselves. -ifdef(HAS_FULL_KEYS). -define(TS_USE_MAPS, true). -else. -define(TS_USE_ARRAY, true). -endif. %% -define(TS_USE_ARRAY, true). -ifdef(TS_USE_MAPS). -define(MAKE_TABLE(), maps:new()). -define(GET_TABLE(N, Ts), maps:get(N, Ts)). -define(SET_TABLE(N, T, Ts), maps:put(N, T, Ts)). -define(UPD_TABLE(N, Upd, Ts), maps:update_with(N, Upd, Ts)). -define(DEL_TABLE(N, Ts), maps:remove(N, Ts)). -define(CHK_TABLE(N, Ts), maps:is_key(N, Ts)). -define(FILTER_TABLES(Pred, Ts), maps:filter(Pred, Ts)). -define(FOLD_TABLES(Fun, Acc, Ts), maps:fold(Fun, Acc, Ts)). -endif. -ifdef(TS_USE_ARRAY). %% Use arrays to handle tables. We leave the default value as undefined. -define(MAKE_TABLE(), array:new()). -define(GET_TABLE(N, Ar), array:get(N, Ar)). -define(SET_TABLE(N, T, Ar), array:set(N, T, Ar)). -define(UPD_TABLE(N, Upd, Ar), array:set(N, (Upd)(array:get(N, Ar)), Ar)). -define(DEL_TABLE(N, Ar), array:reset(N, Ar)). -define(CHK_TABLE(N, Ar), ((N >= 0) andalso (array:get(N, Ar) =/= undefined))). -define(FILTER_TABLES(Pred, Ar), ((fun (___Def) -> ___Fil = fun (___K, ___V) -> case Pred(___K, ___V) of true -> ___V; false -> ___Def end end, array:sparse_map(___Fil, Ar) end)(array:default(Ar)))). -define(FOLD_TABLES(Fun, Acc, Ar), array:sparse_foldl(Fun, Acc, Ar)). -endif. -ifdef(TS_USE_ORDDICT). %% Using orddict to handle tables. -define(MAKE_TABLE(), orddict:new()). -define(GET_TABLE(N, Ts), orddict:fetch(N, Ts)). -define(SET_TABLE(N, T, Ts), orddict:store(N, T, Ts)). -define(UPD_TABLE(N, Upd, Ts), orddict:update(N, Upd, Ts)). -define(DEL_TABLE(N, Ts), orddict:erase(N, Ts)). -define(CHK_TABLE(N, Ts), orddict:is_key(N, Ts)). -define(FILTER_TABLES(Pred, Ts), orddict:filter(Pred, Ts)). -define(FOLD_TABLES(Fun, Acc, Ts), orddict:fold(Fun, Acc, Ts)). -endif. -ifdef(TS_USE_PD). %% Use the process dictionary to handle tables. -define(MAKE_TABLE(), ok). -define(GET_TABLE(N, Pd), get(N)). -define(SET_TABLE(N, T, Pd), put(N, T)). -define(UPD_TABLE(N, Upd, Pd), put(N, (Upd)(get(N)))). -define(DEL_TABLE(N, Pd), erase(N)). -define(CHK_TABLE(N, Pd), (get(N) =/= undefined)). -define(FILTER_TABLES(Pred, Pd), Pd). %This needs work -define(FOLD_TABLES(Fun, Acc, Pd), Pd). %This needs work -endif. -ifdef(TS_USE_ETS). %% Use ETS to handle tables. Must get return values right! -define(MAKE_TABLE(),ets:new(luerl_tables, [set])). -define(GET_TABLE(N, E), ets:lookup_element(E, N, 2)). -define(SET_TABLE(N, T, E), begin ets:insert(E, {N,T}), E end). -define(UPD_TABLE(N, Upd, E), begin ets:update_element(E, N, {2,(Upd)(ets:lookup_element(E, N, 2))}), E end). -define(DEL_TABLE(N, E), begin ets:delete(E, N), E end). -define(FILTER_TABLES(Pred, E), E). %This needs work -define(FOLD_TABLES(Fun, Acc, E), ets:foldl(fun ({___K, ___T}, ___Acc) -> Fun(___K, ___T, ___Acc) end, Acc, E)). -endif. %% Define CATCH to handle deprecated get_stacktrace/0 -ifdef(NEW_STACKTRACE). -define(CATCH(C, E, S), C:E:S ->). -else. -define(CATCH(C, E, S), C:E -> S = erlang:get_stacktrace(),). -endif. luerl-1.2.3/src/luerl_comp.hrl0000664000175000017500000000736114677012037016675 0ustar debalancedebalance%% Copyright (c) 2013-2019 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_comp.hrl %% Author : Robert Virding %% Purpose : Internal LUA 5.2 compiler definitions. %% Common compiler information -record(cinfo, {lfile=[], %Lua file name vfile=[], %Virtual file name opts=[] %Compiler options }). %% Some useful macros. -define(IF(Test,True,False), case Test of true -> True; false -> False end). -define(WHEN_OPT(Opt,Opts,Fun), ?IF(member(Opt, Opts), Fun(), ok)). -define(DEBUG_PRINT(Format,Args,Opts), ?WHEN_OPT(debug_print, Opts, fun () -> io:fwrite(Format, Args) end)). %% Variable data. -record(vars, {local=[], %Local variables free=[], %Free variables used=[], %Used in sub blocks fused=[] %Used in sub-functions }). %% Define internal data macros. %% Statements. %% The line number here, 'l', can be a line number or annotation list. -record(assign_stmt, {l,vars,exps}). -record(call_stmt, {l,call}). -record(return_stmt, {l,exps}). -record(break_stmt, {l}). -record(block_stmt, {l, body=[], %Block body statements vars=none, %Variable info lsz=none, %Local frame size loc=not_used, %Local var block template esz=none, %Env frame size env=not_used, %Local env block template %%local=none, %Local variables locf=false}). %Local functions -record(while_stmt, {l,exp,body=[]}). -record(repeat_stmt, {l,body=[]}). -record(nfor_stmt, {l, var, %Loop variable init,limit,step, %The init, limit, step values body=[]}). %Loop body -record(gfor_stmt, {l, vars, %Loop variables gens, %Generators body=[]}). %Loop body -record(if_stmt, {l,tests=[],else_block}). -record(local_assign_stmt, {l,vars,exps}). -record(local_fdef_stmt, {l,var,func}). -record(expr_stmt, {l,exp}). %Pseudo stmt for expressions -record(block, {l, body=[], %Block body statements vars=none, %Variable info lsz=none, %Local frame size loc=not_used, %Local var block template esz=none, %Env frame size env=not_used, %Local env block template locf=false}). %% Expressions. %% The line number here, 'l', can be a line number or annotation list. -record(fdef, {l, pars=[], %Parameters body=[], %Function body statements vars=none, %Variable info lsz=none, %Local frame size loc=not_used, %Local var block template esz=none, %Env frame size env=not_used, %Local env block template %%local=none, %Local variables locf=false}). %Local function -record(lit, {l,val}). %Literal value -record(op, {l,op,args=[]}). -record(dot, {l,exp,rest}). -record(single, {l,exp}). -record(var, {l,name}). -record(fcall, {l,args=[]}). %Function call -record(mcall, {l,meth,args=[]}). %Method call -record(key, {l,key}). -record(tabcon, {l,fields=[]}). %Table constructor -record(efield, {l,val}). -record(kfield, {l,key,val}). %% Variable types. %% The line number here, 'l', can be a line number or annotation list. -record(lvar, {l,n,d,i}). %Local name, depth, index -record(evar, {l,n,d,i}). %Environment name, depth, index -record(gvar, {l,n}). %Global name luerl-1.2.3/src/luerl_lib_basic.erl0000664000175000017500000003500314677012037017635 0ustar debalancedebalance%% Copyright (c) 2013-2024 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_lib_basic.erl %% Author : Robert Virding %% Purpose : The basic library for Luerl. -module(luerl_lib_basic). -include("luerl.hrl"). %% The basic entry point to set up the function table. -export([install/1,assert/3,error_call/3,collectgarbage/3,dofile/3, eprint/3,getmetatable/3,ipairs/3,ipairs_next/3, load/3,loadfile/3,loadstring/3, next/3,pairs/3,pcall/3,print/3, rawequal/3,rawget/3,rawlen/3,rawset/3, select/3,setmetatable/3,tonumber/3,tostring/3,type/3,unpack/3]). %% Export some functions which can be called from elsewhere. -export([print/2,tostring/1,tostring/2,type/1]). -import(luerl_lib, [lua_error/2,badarg_error/3]). %Shorten these install(St) -> luerl_heap:alloc_table(table(), St). %% table() -> [{FuncName,Function}]. %% Caller will convert this list to the correct format. table() -> [{<<"_VERSION">>,<<"Lua 5.3">>}, %We are optimistic {<<"assert">>,#erl_mfa{m=?MODULE,f=assert}}, {<<"collectgarbage">>,#erl_mfa{m=?MODULE,f=collectgarbage}}, {<<"dofile">>,#erl_mfa{m=?MODULE,f=dofile}}, {<<"eprint">>,#erl_mfa{m=?MODULE,f=eprint}}, {<<"error">>,#erl_mfa{m=?MODULE,f=error_call}}, {<<"getmetatable">>,#erl_mfa{m=?MODULE,f=getmetatable}}, {<<"ipairs">>,#erl_mfa{m=?MODULE,f=ipairs}}, {<<"load">>,#erl_mfa{m=?MODULE,f=load}}, {<<"loadfile">>,#erl_mfa{m=?MODULE,f=loadfile}}, {<<"loadstring">>,#erl_mfa{m=?MODULE,f=loadstring}}, %For Lua 5.1 compatibility {<<"next">>,#erl_mfa{m=?MODULE,f=next}}, {<<"pairs">>,#erl_mfa{m=?MODULE,f=pairs}}, {<<"pcall">>,#erl_mfa{m=?MODULE,f=pcall}}, {<<"print">>,#erl_mfa{m=?MODULE,f=print}}, {<<"rawequal">>,#erl_mfa{m=?MODULE,f=rawequal}}, {<<"rawget">>,#erl_mfa{m=?MODULE,f=rawget}}, {<<"rawlen">>,#erl_mfa{m=?MODULE,f=rawlen}}, {<<"rawset">>,#erl_mfa{m=?MODULE,f=rawset}}, {<<"select">>,#erl_mfa{m=?MODULE,f=select}}, {<<"setmetatable">>,#erl_mfa{m=?MODULE,f=setmetatable}}, {<<"tonumber">>,#erl_mfa{m=?MODULE,f=tonumber}}, {<<"tostring">>,#erl_mfa{m=?MODULE,f=tostring}}, {<<"type">>,#erl_mfa{m=?MODULE,f=type}}, {<<"unpack">>,#erl_mfa{m=?MODULE,f=unpack}} %For Lua 5.1 compatibility ]. assert(_, As, St) -> case luerl_lib:boolean_value(As) of true -> {As,St}; false -> M = case As of [_,M0|_] -> M0; _ -> <<"assertion failed">> end, lua_error({assert_error,M}, St) end. collectgarbage(_, [], St) -> collectgarbage(nil, [<<"collect">>], St); collectgarbage(_, [<<"collect">>|_], St) -> {[],luerl_heap:gc(St)}; %% {[],St}; %No-op for the moment collectgarbage(_, _, St) -> %Ignore everything else {[],St}. eprint(_, Args, St) -> lists:foreach(fun (#tref{}=Tref) -> Tab = luerl_heap:get_table(Tref, St), io:format("~w ", [Tab]); (A) -> io:format("~w ", [A]) end, Args), io:nl(), {[],St}. -spec error_call(_, _, _) -> no_return(). %% error_call(Args, State) -> no_return(). %% Generate an error with an error string. error_call(_, [{tref, _}=T|_]=As, St0) -> case luerl_heap:get_metamethod(T, <<"__tostring">>, St0) of nil -> lua_error({error_call, As}, St0); Meta -> {Rets, St1} = luerl_emul:functioncall(Meta, [T], St0), lua_error({error_call, Rets}, St1) end; error_call(_, As, St) -> %Never returns! lua_error({error_call, As}, St). %% ipairs(Args, State) -> {[Func,Table,FirstKey],State}. %% Return a function which on successive calls returns successive %% key-value pairs of integer keys. We check that it is a table first %% when we access it. ipairs(_, [Tref|_], St) -> case luerl_heap:get_metamethod(Tref, <<"__ipairs">>, St) of nil -> {[#erl_mfa{m=?MODULE,f=ipairs_next},Tref,0],St}; Meta -> luerl_emul:functioncall(Meta, [Tref], St) end; ipairs(_, As, St) -> badarg_error(ipairs, As, St). ipairs_next(_, [A], St) -> ipairs_next(nil, [A,0], St); ipairs_next(_, [Tref,K|_], St) when ?IS_TREF(Tref), is_integer(K) -> %% Get the table. #table{a=Arr} = luerl_heap:get_table(Tref, St), Next = K + 1, case array:get(Next, Arr) of nil -> {[nil],St}; V -> {[Next,V],St} end; ipairs_next(_, As, St) -> badarg_error(ipairs, As, St). %% pairs(Args, State) -> {[Func,Table,Key],State}. %% Return a function to step over all the key-value pairs in a %% table. We check that it is a table first when we access it. pairs(_, [Tref|_], St) -> case luerl_heap:get_metamethod(Tref, <<"__pairs">>, St) of nil -> {[#erl_mfa{m=?MODULE,f=next},Tref,nil],St}; Meta -> luerl_emul:functioncall(Meta, [Tref], St) end; pairs(_, As, St) -> badarg_error(pairs, As, St). %% next(Args, State) -> {[Key,Value] | [nil], State}. %% Given a table and a key return the next key-value pair in the %% table, or nil if there is no next key. The key 'nil' gives the %% first key-value pair. next(_, [A], St) -> next(nil, [A,nil], St); next(_, [#tref{}=Tref,K|_], St) -> %% Get the table. #table{a=Arr,d=Dict} = luerl_heap:get_table(Tref, St), if K == nil -> %% Find the first, start with the array. next_index(0, Arr, Dict, St); is_integer(K), K >= 1 -> next_index(K, Arr, Dict, St); is_float(K) -> case ?IS_FLOAT_INT(K, I) of true when I >= 1 -> next_index(I, Arr, Dict, St); _NegFalse -> %Not integer or negative next_key(K, Dict, St) end; true -> next_key(K, Dict, St) end; next(_, As, St) -> badarg_error(next, As, St). next_index(I0, Arr, Dict, St) -> case next_index_loop(I0+1, Arr, array:size(Arr)) of {I1,V} -> {[I1,V],St}; none -> %% Nothing in the array, take table instead. first_key(Dict, St) end. next_index_loop(I, Arr, S) when I < S -> case array:get(I, Arr) of nil -> next_index_loop(I+1, Arr, S); V -> {I,V} end; next_index_loop(_, _, _) -> none. first_key(Dict, St) -> case ttdict:first(Dict) of {ok,{K,V}} -> {[K,V],St}; error -> {[nil],St} end. next_key(K, Dict, St) -> case ttdict:next(K, Dict) of {ok,{N,V}} -> {[N,V],St}; error -> {[nil],St} end. %% print(Args, State) -> {[],State}. %% Receives any number of arguments and prints their values to %% stdout, using the tostring function to convert each argument to a %% string. print is not intended for formatted output, but only as a %% quick way to show a value, for instance for debugging. print(_, Args, St0) -> St1 = lists:foldl(fun (A, S0) -> {[Str],S1} = tostring([A], S0), io:format("~ts ", [Str]), S1 end, St0, Args), io:nl(), {[],St1}. print(Args, St0) -> print(nil, Args, St0). %% rawequal([Arg,Arg|_], State) -> {[Bool],State}. %% rawlen([Object|_], State) -> {[Length],State}. %% rawget([Table,Key|_], State) -> {[Val],State)}. %% rawset([Table,Key,Value|_]], State) -> {[Table],State)}. rawequal(_, [A1,A2|_], St) -> {[A1 =:= A2],St}; rawequal(_, As, St) -> badarg_error(rawequal, As, St). rawlen(_, [A|_], St) when is_binary(A) -> {[float(byte_size(A))],St}; rawlen(_, [#tref{}=T|_], St) -> {[luerl_lib_table:raw_length(T, St)],St}; rawlen(_, As, St) -> badarg_error(rawlen, As, St). rawget(_, [#tref{}=Tref,Key|_], St) -> Val = luerl_heap:raw_get_table_key(Tref, Key, St), {[Val],St}; rawget(_, As, St) -> badarg_error(rawget, As, St). rawset(_, [Tref,nil=Key,_|_], St) -> lua_error({illegal_index,Tref,Key}, St); rawset(_, [#tref{}=Tref,Key,Val|_], St0) -> St1 = luerl_heap:raw_set_table_key(Tref, Key, Val, St0), {[Tref],St1}; rawset(_, As, St) -> badarg_error(rawset, As, St). %% select(Args, State) -> {[Element],State}. select(_, [<<$#>>|As], St) -> {[float(length(As))],St}; select(_, [A|As], St) -> Len = length(As), case luerl_lib:arg_to_integer(A) of N when is_integer(N), N > 0 -> {select_front(N, As, Len),St}; N when is_integer(N), N < 0 -> {select_back(-N, As, Len),St}; _ -> badarg_error(select, [A|As], St) end; select(_, As, St) -> badarg_error(select, As, St). select_front(N, As, Len) when N =< Len -> lists:nthtail(N-1, As); select_front(_, _, _) -> []. select_back(N, As, Len) when N =< Len -> lists:nthtail(Len-N, As); select_back(_, As, _) -> As. tonumber(_, [Arg], St) -> {[tonumber(luerl_lib:arg_to_number(Arg))],St}; tonumber(_, [Arg,B|_], St) -> {[tonumber(luerl_lib:arg_to_number(Arg, B))],St}; tonumber(_, As, St) -> badarg_error(tonumber, As, St). tonumber(Num) when is_number(Num) -> Num; tonumber(_) -> nil. tostring(_, [Arg|_], St) -> case luerl_heap:get_metamethod(Arg, <<"__tostring">>, St) of nil -> {[tostring(Arg)],St}; M when ?IS_FUNCTION(M) -> luerl_emul:functioncall(M, [Arg], St) %Return {R,St1} end; tostring(_, As, St) -> badarg_error(tostring, As, St). tostring(As, St) -> tostring(nil, As, St). %% tostring([Arg|_], Stated) -> {String,State}. %% Return the type as a string. tostring(nil) -> <<"nil">>; tostring(false) -> <<"false">>; tostring(true) -> <<"true">>; tostring(N) when is_number(N) -> %% A = abs(N), %% %% Print really big/small "integers" as floats as well. %% S = if ?IS_FLOAT_INT(N), A < 1.0e14 -> %% integer_to_list(round(N)); %% true -> io_lib:write(N) %% end, iolist_to_binary(io_lib:write(N)); tostring(S) when is_binary(S) -> S; tostring(#tref{i=I}) -> iolist_to_binary([<<"table: ">>,integer_to_list(I)]); tostring(#usdref{i=I}) -> iolist_to_binary([<<"userdata: ">>,integer_to_list(I)]); tostring(#funref{i=I}) -> %Functions defined in Lua iolist_to_binary([<<"function: ">>,integer_to_list(I)]); tostring(#erl_func{code=C}) -> %Erlang functions iolist_to_binary([<<"function: ">>,io_lib:write(C)]); tostring(#erl_mfa{m=M,f=F}) -> %Erlang MFA triplets iolist_to_binary([<<"function: ">>,io_lib:write_atom(M),<<":">>,io_lib:write_atom(F)]); tostring(#thread{}) -> <<"thread">>; tostring(_) -> <<"unknown">>. %% type([Data|_], State) -> {Type,State}. %% Return the type of the argument. type(_, [Arg|_], St) -> {[type(Arg)],St}; %Only one return value! type(_, As, St) -> badarg_error(type, As, St). type(nil) -> <<"nil">>; type(N) when is_number(N) -> <<"number">>; type(S) when is_binary(S) -> <<"string">>; type(B) when is_boolean(B) -> <<"boolean">>; type(#tref{}) -> <<"table">>; type(#usdref{}) -> <<"userdata">>; type(#funref{}) -> <<"function">>; %Functions defined in Lua type(#erl_func{}) -> <<"function">>; %Internal functions type(#erl_mfa{}) -> <<"function">>; type(#thread{}) -> <<"thread">>; type(_) -> <<"unknown">>. %% getmetatable([Value|_], State) -> {Table,State}. %% setmetatable([Table,Table|nil|_], State) -> {Table,State}. %% Can only set the metatable of tables here. Return tables for all %% values, for tables and userdata it is the table of the object, %% else the metatable for the type. getmetatable(_, [Obj|_], St) -> case luerl_heap:get_metatable(Obj, St) of #tref{}=Meta -> #table{d=Dict} = luerl_heap:get_table(Meta, St), case ttdict:find(<<"__metatable">>, Dict) of {ok,MM} -> {[MM],St}; error -> {[Meta],St} end; nil -> {[nil],St} end; getmetatable(_, As, St) -> badarg_error(getmetatable, As, St). setmetatable(_, [#tref{}=T,#tref{}=M|_], St) -> do_setmetatable(T, M, St); setmetatable(_, [#tref{}=T,nil|_], St) -> do_setmetatable(T, nil, St); setmetatable(_, As, St) -> badarg_error(setmetatable, As, St). do_setmetatable(#tref{}=Tref, Meta, St0) -> case luerl_heap:get_metamethod(Tref, <<"__metatable">>, St0) of nil -> Upd = fun (Tab) -> Tab#table{meta=Meta} end, St1 = luerl_heap:upd_table(Tref, Upd, St0), {[Tref],St1}; _ -> badarg_error(setmetatable, [Tref], St0) end. %% Do files. dofile(_, As, St) -> case luerl_lib:conv_list(As, [erl_string]) of [File] -> %% Compile the file so it returns errors. Ret = luerl_comp:file(File, [verbose,return]), dofile_ret(Ret, As, St); _ -> badarg_error(dofile, As, St) end. dofile_ret({ok,Chunk}, _, St0) -> {Func,St1} = luerl_emul:load_chunk(Chunk, St0), luerl_emul:call(Func, [], St1); dofile_ret({error,[{_,Mod,E}|_],_}, _As, St) -> Msg = unicode:characters_to_binary(Mod:format_error(E)), lua_error({error_message,Msg}, St). %% Load string and files. load(_, As, St) -> case luerl_lib:conv_list(As, [erl_string,lua_string,lua_string,lua_any]) of [S|_] -> %% Compile the string so it returns errors. Ret = luerl_comp:string(S, [verbose,return]), load_ret(Ret, St); error -> badarg_error(load, As, St) end. loadfile(_, As, St) -> case luerl_lib:conv_list(As, [erl_string,lua_string,lua_any]) of [F|_] -> %% Compile the file so it returns errors. Ret = luerl_comp:file(F, [verbose,return]), load_ret(Ret, St); error -> badarg_error(loadfile, As, St) end. loadstring(_, As, St) -> case luerl_lib:conv_list(As, [erl_string]) of [S] -> %% Compile the string so it returns errors. Ret = luerl_comp:string(S, [verbose,return]), load_ret(Ret, St); error -> badarg_error(loadstring, As, St) end. load_ret({ok,Chunk}, St0) -> {Func,St1} = luerl_emul:load_chunk(Chunk, St0), {[Func],St1}; load_ret({error,[{_,Mod,E}|_],_}, St) -> Msg = unicode:characters_to_binary(Mod:format_error(E)), {[nil,Msg],St}. pcall(_, [F|As], St0) -> try {Rs,St1} = luerl_emul:functioncall(F, As, St0), {[true|Rs],St1} catch %% Only catch Lua errors here, signal system errors. error:{lua_error,{error_call, Eas},St2} -> Msg = case Eas of [E|_] -> tostring(E); [] -> <<"nil">> end, {[false,Msg],St2}; error:{lua_error,E,St2} -> %% Basic formatting for now. Msg = unicode:characters_to_binary(luerl_lib:format_error(E)), {[false,Msg],St2} end. %% Lua 5.1 compatibility functions. unpack(_, As, St) -> luerl_lib_table:unpack(As, St). luerl-1.2.3/src/luerl_sandbox.erl0000664000175000017500000001220314677012037017361 0ustar debalancedebalance%% Copyright (c) 2013-2017 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_sandbox.erl %% Authors : Tyler Butchart %% Purpose : Reduction limiting luerl sandbox. -module(luerl_sandbox). -include("luerl.hrl"). -export([init/0,init/1,init/2, run/1,run/2,run/3,run/4,run/5]). -define(LUERL_GLOBAL, '_G'). -define(SANDBOXED_VALUE, sandboxed). -define(SANDBOXED_GLOBALS, [ [?LUERL_GLOBAL, io], [?LUERL_GLOBAL, file], [?LUERL_GLOBAL, os, execute], [?LUERL_GLOBAL, os, exit], [?LUERL_GLOBAL, os, getenv], [?LUERL_GLOBAL, os, remove], [?LUERL_GLOBAL, os, rename], [?LUERL_GLOBAL, os, tmpname], [?LUERL_GLOBAL, package], [?LUERL_GLOBAL, load], [?LUERL_GLOBAL, loadfile], [?LUERL_GLOBAL, require], [?LUERL_GLOBAL, dofile], [?LUERL_GLOBAL, load], [?LUERL_GLOBAL, loadfile], [?LUERL_GLOBAL, loadstring] ]). -define(MAX_TIME, 100). %% Define IS_MAP/1 macro for is_map/1 bif. -ifdef(HAS_MAPS). -define(IS_MAP(T), is_map(T)). -else. -define(IS_MAP(T), false). -endif. %% init([, State|TablePaths[, TablePaths]]) -> State init() -> init(luerl:init()). init(TablePaths) when is_list(TablePaths) -> init(luerl:init(), TablePaths); init(St) -> init(St, ?SANDBOXED_GLOBALS). init(St, []) -> luerl:gc(St); init(St0, [Path|Tail]) -> St1 = luerl:set_table(Path, ?SANDBOXED_VALUE, St0), init(St1, Tail). %% The default flags for running the sandboxed process. default_flags() -> [{max_time, ?MAX_TIME}, {max_reductions, none}, {spawn_opts, []}]. %% run(String|Binary) -> {Term,State} | {error,Term}. %% run(String|Binary, State) -> {Term,State} | {error,Term}. %% run(String|Binary, Flags, State) -> {Term,State} | {error,Term}. %% The new interface where Flags is a map which can contain: %% %% #{max_time => Time, (100 msec) %% max_reductions => Reductions, (none) %% spawn_opts => Spawn_Options} ([]) %% %% Any other fields are ignored. The default values are shown above. %% This can also be given as a keyword list. %% run(String|Binary|Form[, State[, MaxReductions|Flags[, Flags[, Timeout]]]]) -> {Term,State}|{error,Term} %% This is the old interface which still works. run(S) -> run(S, init()). run(S, St) -> do_run(S, default_flags(), St). %% The new interface. run(S, Flags, St) when ?IS_MAP(Flags) -> run(S, maps:to_list(Flags), St); run(S, Flags, #luerl{}=St) when is_list(Flags) -> do_run(S, Flags ++ default_flags(), St); %% The old interface. run(S, St, MaxR) when is_integer(MaxR) -> run(S, St, MaxR, []); run(S, St, Flags) when is_list(Flags) -> run(S, St, 0, Flags). run(S, St, MaxR, Flags) -> run(S, St, MaxR, Flags, ?MAX_TIME). run(S, St, 0, Opts, MaxT) -> %% Need to get the old no reductions to the new no reductions. run(S, St, none, Opts, MaxT); run(S, St, MaxR, Opts, MaxT) -> Flags = [{max_time,MaxT},{max_reductions,MaxR},{spawn_opts,Opts}], do_run(S, Flags, St). do_run(S, Flags, St) -> MaxT = proplists:get_value(max_time, Flags), Opts = proplists:get_value(spawn_opts, Flags), Runner = start(self(), S, Opts, St), case proplists:get_value(max_reductions, Flags) of none -> receive_response(Runner, MaxT); MaxR when is_integer(MaxR), MaxR > 0 -> case wait_reductions(Runner, MaxR) of {killed, R} -> {error, {reductions, R}}; ok -> receive_response(Runner, MaxT) end; _Other -> exit(badarg) end. start(Parent, S, Opts, St) -> spawn_opt(fun() -> try Reply = luerl:do(S, St), erlang:send(Parent, {self(), Reply}) catch error:Reason -> erlang:send(Parent, {self(), {error, Reason}}) end end, Opts). wait_reductions(Runner, MaxR) -> case process_info(Runner, reductions) of undefined -> %% The process has died. ok; {reductions, R} when R >= MaxR -> exit(Runner, kill), {killed, R}; {reductions, _} -> %% We only check every default MAX_TIME so we don't %% overload the runner process too much. receive after ?MAX_TIME -> ok end, wait_reductions(Runner, MaxR) end. receive_response(Runner, Timeout) -> receive {Runner, Reply} -> %% The runner has terminated. Reply; {error, Error} -> Error after Timeout -> %% Kill the runner as its time is up. exit(Runner, kill), {error, timeout} end. luerl-1.2.3/src/luerl_comp_lint.erl0000664000175000017500000001723514677012037017721 0ustar debalancedebalance%% Copyright (c) 2019 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_lint.erl %% Author : Robert Virding %% Purpose : A basic LUA 5.3 error checker for Luerl. %% There isn't much checking which can be done here as most is allowed %% and generates run-time errors or strangeness. So far all we can %% check is the legal use of varargs ... and warn if assignments have %% different number of variables and expressions. -module(luerl_comp_lint). -include("luerl.hrl"). -include("luerl_comp.hrl"). -export([chunk/2,format_error/1]). -record(lint, {opts=[], %Options pars=[], %Local function parameters errors=[], %Errors warnings=[] %Warnings }). %% format_error(Error) -> String. format_error(illegal_varargs) -> "cannot use '...' outside a vararg function"; format_error(assign_mismatch) -> "assign mismatch variables and expressions". %% chunk(Code, Compinfo) -> {ok,Warnings} | {error,Errors,Warnings}. chunk(Code, #cinfo{opts=Opts}=_Ci) -> St0 = #lint{opts=Opts}, St1 = functiondef(Code, St0), return_status(St1). return_status(#lint{errors=[]}=St) -> {ok,St#lint.warnings}; return_status(#lint{errors=Es,warnings=Ws}) -> {error,Es,Ws}. %% stmts(Stmts, State) -> State. stmts([S|Ss], St0) -> St1 = stmt(S, St0), stmts(Ss, St1); stmts([], St) -> St. %% stmt(Stmt, State) -> State. stmt(#assign_stmt{}=A, St) -> assign_stmt(A, St); stmt(#call_stmt{}=C, St) -> call_stmt(C, St); stmt(#return_stmt{}=R, St) -> return_stmt(R, St); stmt(#break_stmt{}, St) -> St; stmt(#block_stmt{}=B, St) -> block_stmt(B, St); stmt(#while_stmt{}=W, St) -> while_stmt(W, St); stmt(#repeat_stmt{}=R, St) -> repeat_stmt(R, St); stmt(#if_stmt{}=If, St) -> if_stmt(If, St); stmt(#nfor_stmt{}=For, St) -> numfor_stmt(For, St); stmt(#gfor_stmt{}=For, St) -> genfor_stmt(For, St); stmt(#local_assign_stmt{}=For, St) -> local_assign_stmt(For, St); stmt(#local_fdef_stmt{}=For, St) -> local_fdef_stmt(For, St); stmt(#expr_stmt{}=E, St) -> expr_stmt(E, St). %% assign_stmt(Assign, State) -> State. %% call_stmt(Call, State) -> State. %% return_stmt(Return, State) -> State. %% block_stmt(Block, State) -> State. %% while_stmt(While, State) -> State. %% repeat_stmt(Repeat, State) -> State. %% if_stmt(If, State) -> State. %% numfor_stmt(Numfor, State) -> State. %% genfor_stmt(Genfor, State) -> State. %% local_assign_stmt(Assign, State) -> State. %% local_fdef_stmt(Fdef, State) -> State. %% expr_stmt(Expr, State) -> State. assign_stmt(#assign_stmt{vars=Vs,exps=Es}, St0) -> %% Must work more on this to get it right. %% St1 = ?IF(length(Vs) =/= length(Es), %% assign_mismatch_warning(Anno, St0), St0), St1 = St0, St2 = lists:foldl(fun (V, S) -> assign_var(V, S) end, St1, Vs), explist(Es, St2). assign_var(#dot{exp=Exp,rest=Rest}, St0) -> St1 = prefixexp_first(Exp, St0), assign_var_rest(Rest, St1); assign_var(#var{l=Anno,name='...'}, St) -> %% Not allowed to bind ... . illegal_varargs_error(Anno, St); assign_var(_Var, St) -> St. assign_var_rest(#dot{exp=Exp,rest=Rest}, St0) -> St1 = prefixexp_element(Exp, St0), assign_var_rest(Rest, St1); assign_var_rest(Exp, St) -> assign_var_last(Exp, St). assign_var_last(#key{key=Exp}, St) -> exp(Exp, St). call_stmt(#call_stmt{call=Exp}, St) -> exp(Exp, St). return_stmt(#return_stmt{exps=Es}, St) -> explist(Es, St). block_stmt(#block_stmt{body=Ss}, St) -> stmts(Ss, St). while_stmt(#while_stmt{exp=Exp,body=Ss}, St0) -> St1 = exp(Exp, St0), block(Ss, St1). repeat_stmt(#repeat_stmt{body=Ss}, St) -> block(Ss, St). if_stmt(#if_stmt{tests=Ts,else_block=Else}, St0) -> Fun = fun ({E,B}, S0) -> S1 = exp(E, S0), block(B, S1) end, St1 = lists:foldl(Fun, St0, Ts), block(Else, St1). numfor_stmt(#nfor_stmt{init=I,limit=L,step=S,body=B}, St0) -> St1 = explist([I,L,S], St0), block(B, St1). genfor_stmt(#gfor_stmt{gens=Gs,body=B}, St0) -> St1 = explist(Gs, St0), block(B, St1). local_assign_stmt(#local_assign_stmt{exps=Es}, St0) -> %% Must work more on this to get it right. %% St1 = ?IF(length(Vs) =/= length(Es), %% assign_mismatch_warning(Anno, St0), St0), St1 = St0, explist(Es, St1). local_fdef_stmt(#local_fdef_stmt{func=F}, St) -> functiondef(F, St). expr_stmt(#expr_stmt{exp=Exp}, St) -> exp(Exp, St). %% block(Block, State) -> State. block(#block{body=Ss}, St) -> stmts(Ss, St). %% explist(Exprs, State) -> State. %% exp(Expr, State) -> State. %% prefixexp(Expr, State) -> State. explist(Es, St) -> lists:foldl(fun (E, S) -> exp(E, S) end, St, Es). exp(#lit{}, St) -> St; exp(#fdef{}=F, St) -> functiondef(F, St); exp(#op{args=Es}, St) -> explist(Es, St); exp(#tabcon{fields=Fs}, St) -> tableconstructor(Fs, St); exp(E, St) -> prefixexp(E, St). prefixexp(#dot{exp=Exp,rest=Rest}, St0) -> St1 = prefixexp_first(Exp, St0), prefixexp_rest(Rest, St1); prefixexp(Exp, St) -> prefixexp_first(Exp, St). prefixexp_first(#single{exp=Exp}, St) -> exp(Exp, St); prefixexp_first(#var{}=V, St) -> var(V, St). prefixexp_rest(#dot{exp=Exp,rest=Rest}, St0) -> St1 = prefixexp_element(Exp, St0), prefixexp_rest(Rest, St1); prefixexp_rest(Exp, St) -> prefixexp_element(Exp, St). prefixexp_element(#key{key=Exp}, St) -> exp(Exp, St); prefixexp_element(#fcall{args=Es}, St) -> explist(Es, St); prefixexp_element(#mcall{meth=Lit,args=Es}, St0) -> St1 = lit(Lit, St0), explist(Es, St1). %% functiondef(FuncDef, State) -> State. functiondef(#fdef{pars=Ps,body=Ss}, #lint{pars=Pars}=St0) -> St1 = St0#lint{pars=Ps}, %Use current parameters St2 = stmts(Ss, St1), St2#lint{pars=Pars}. %Reset previous parameters %% tableconstructor(Fields, State) -> State. tableconstructor(Fs, St) -> Fun = fun (#efield{val=Exp}, S) -> exp(Exp, S); (#kfield{key=Key,val=Val}, S0) -> S1 = exp(Key, S0), exp(Val, S1) end, lists:foldl(Fun, St, Fs). %% var(Var, State) -> State. var(#var{l=Anno,name='...'}, St) -> case lists:keymember('...', #var.name, St#lint.pars) of true -> St; false -> illegal_varargs_error(Anno, St) end; var(_Var, St) -> St. %% lit(Lit, State) -> State. lit(#lit{l=Anno,val='...'}, St) -> case lists:keymember('...', #var.name, St#lint.pars) of true -> St; false -> illegal_varargs_error(Anno, St) end; lit(_Lit, St) -> St. %% add_error(Annotation, Error, State) -> State. %% add_warning(Annotation, Warning, State) -> State. %% Add errors/warnings to the state. add_error(Anno, E, #lint{errors=Errs}=St) -> L = luerl_anno:line(Anno), St#lint{errors=Errs ++ [{L,?MODULE,E}]}. %% add_warning(Anno, W, #lint{warnings=Warns}=St) -> %% L = luerl_anno:line(Anno), %% St#lint{warnings=Warns ++ [{L,?MODULE,W}]}. illegal_varargs_error(Anno, St) -> add_error(Anno, illegal_varargs, St). %% assign_mismatch_warning(Anno, St) -> %% add_warning(Anno, assign_mismatch, St). luerl-1.2.3/src/luerl_lib_os.erl0000664000175000017500000002353414677012037017203 0ustar debalancedebalance%% Copyright (c) 2013-2024 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_lib_os.erl %% Author : Robert Virding %% Purpose : The os library for Luerl. -module(luerl_lib_os). -include("luerl.hrl"). -export([install/1, clock/3, date/3, difftime/3, execute/3, lua_exit/3, getenv/3, remove/3, rename/3, time/3, tmpname/3]). -import(luerl_lib, [lua_error/2,badarg_error/3]). %Shorten this %% For `remove/2'. -include_lib("kernel/include/file.hrl"). %% For `tmpname/2' in `luerl_lib_os'. -define(TMPNAM_MAXTRIES, 100). -define(TMPNAM_TEMPLATE(S), "/tmp/lua_" ++ S). install(St) -> luerl_heap:alloc_table(table(), St). table() -> [{<<"clock">>,#erl_mfa{m=?MODULE,f=clock}}, {<<"date">>,#erl_mfa{m=?MODULE,f=date}}, {<<"difftime">>,#erl_mfa{m=?MODULE,f=difftime}}, {<<"execute">>,#erl_mfa{m=?MODULE,f=execute}}, {<<"exit">>,#erl_mfa{m=?MODULE,f=lua_exit}}, {<<"getenv">>,#erl_mfa{m=?MODULE,f=getenv}}, {<<"remove">>,#erl_mfa{m=?MODULE,f=remove}}, {<<"rename">>,#erl_mfa{m=?MODULE,f=rename}}, {<<"time">>,#erl_mfa{m=?MODULE,f=time}}, {<<"tmpname">>,#erl_mfa{m=?MODULE,f=tmpname}}]. getenv(_, [<<>>|_], St) -> {[nil],St}; getenv(_, [A|_], St) when is_binary(A) ; is_number(A) -> case os:getenv(luerl_lib:arg_to_list(A)) of Env when is_list(Env) -> {[list_to_binary(Env)],St}; false -> {[nil],St} end; getenv(_, As, St) -> badarg_error(getenv, As, St). %% execute([Command|_], State) -> {[Ret,Type,Stat],State}. %% Execute a command and get the return code. We cannot yet properly %% handle if our command terminated with a signal. execute(_, [], St) -> {true,St}; %We have a shell execute(_, [A|_], St) -> case luerl_lib:arg_to_string(A) of S when is_binary(S) -> Opts = [{arg0,"sh"},{args,["-c", S]}, hide,in,eof,exit_status,use_stdio,stderr_to_stdout], P = open_port({spawn_executable,"/bin/sh"}, Opts), N = execute_handle(P), Ret = if N =:= 0 -> true; %Success true -> nil %Error end, {[Ret,<<"exit">>,N],St}; error -> badarg_error(execute, [A], St) end; execute(_, As, St) -> badarg_error(execute, As, St). execute_handle(P) -> receive {P,{data,D}} -> %% Print stdout/stderr like Lua does. io:put_chars(D), execute_handle(P); {P, {exit_status,N}} -> %% Wait for the eof then close the port. receive {P, eof} -> port_close(P), N end end. %% exit([ExitCode,CloseState|_], State) -> nil. %% Exit the host program. If ExitCode is true, the return code is 0; %% if ExitCode is false, the return code is 1; if ExitCode is a number, the %% return code is this number. The default value for ExitCode is true. %% NOT IMPLEMENTED: %% If the optional second argument CloseState is true, it will close the Lua %% state before exiting. lua_exit(_, [], St) -> lua_exit(nil, [true,false], St); lua_exit(_, [C], St) -> lua_exit(nil, [C,false], St); lua_exit(_, [Co0|_], St) -> %% lua_exit([Co0,Cl0], St) -> Co1 = case luerl_lib:arg_to_number(Co0) of X when is_integer(X) -> X; error -> case Co0 of false -> 1; true -> 0; error -> badarg_error(exit, [Co0], St) end end, %% Uncomment this if you need the second argument to determine whether to %% destroy the Lua state or not. %% Cl1 = case Cl0 of %% true -> true; %% false -> false; %% _ -> badarg_error(exit, [Cl0], St) %% end, erlang:halt(Co1). %% tmpname([], State) %% Faithfully recreates `tmpnam'(3) in lack of a NIF. tmpname(_, [_|_], St) -> %% Discard extra arguments. tmpname(nil, [], St); tmpname(_, [], St) -> Out = tmpname_try(randchar(6, []), 0), %% We make an empty file the programmer will have to close themselves. %% This is done for security reasons. file:write_file(Out, ""), {[list_to_binary(Out)],St}. %% Support function for `tmpname/2' - generates a random filename following a %% template. tmpname_try(_, ?TMPNAM_MAXTRIES) -> %% Exhausted... false; tmpname_try(A, N) -> case file:read_file_info(?TMPNAM_TEMPLATE(A)) of {error,enoent} -> ?TMPNAM_TEMPLATE(A); %% Success, at last! _ -> tmpname_try(randchar(6, []), N+1) end. %% Support function for `tmpname_try/2'. randchar(0, A) -> A; randchar(N, A) -> randchar(N-1, [rand:uniform(26)+96|A]). %% rename([Source,Destination|_], State) %% Renames the file or directory `Source' to `Destination'. If this function %% fails, it returns `nil', plus a string describing the error code and the %% error code. Otherwise, it returns `true'. rename(_, [S,D|_], St) -> case {luerl_lib:arg_to_string(S), luerl_lib:arg_to_string(D)} of {S1,D1} when is_binary(S1) , is_binary(D1) -> case file:rename(S1,D1) of ok -> {[true],St}; {error,R} -> #{errno := En, errstr := Er} = luerl_util:errname_info(R), {[nil,Er,En],St} end; %% These are for throwing a `badmatch' error on the correct argument. {S1,D1} when not is_binary(S1) , not is_binary(D1) -> badarg_error(rename, [S1,D1], St); {S1,D1} when not is_binary(S1) , is_binary(D1) -> badarg_error(rename, [S1], St); {S1,D1} when is_binary(S1) , not is_binary(D1) -> badarg_error(rename, [D1], St) end; rename(_, As, St) -> badarg_error(rename, As, St). %% remove([Path|_], State) %% Deletes the file (or empty directory) with the given `Path'. If this %% function fails, it returns `nil' plus a string describing the error, and the %% error code. Otherwise, it returns `true'. remove(_, [A|_], St) -> case luerl_lib:arg_to_string(A) of A1 when is_binary(A1) -> %% Emulate the underlying call to `remove(3)'. case file:read_file_info(A1) of {ok,#file_info{type=T}} when T == directory ; T == regular -> %% Select the corresponding function. Op = if T == directory -> del_dir; true -> delete end, case file:Op(A) of ok -> {[true],St}; {error,R} -> {remove_geterr(R, A), St} end; {error,R} -> %% Something went wrong. {remove_geterr(R, A), St} end; error -> badarg_error(remove, [A], St) end; remove(_, As, St) -> badarg_error(remove, As, St). %% Utility function to get a preformatted list to return from `remove/2'. remove_geterr(R, F) -> F1 = binary_to_list(F), #{errno := En, errstr := Er} = luerl_util:errname_info(R), [nil, list_to_binary(F1 ++ ": " ++ Er), En]. %% Time and date functions. clock(_, As, St) -> Type = case As of %Choose which we want [<<"runtime">>|_] -> runtime; _ -> wall_clock end, {Tot,_} = erlang:statistics(Type), %Milliseconds {[Tot*1.0e-3],St}. date(ConfArg, [], St) -> date(ConfArg, [<<"%c">>], St); date(ConfArg, [Fmt], St) when is_binary(Fmt) -> date(ConfArg, [Fmt, current_timestamp()], St); date(_, [Fmt, TimeStamp], St) when is_binary(Fmt) and is_number(TimeStamp) -> DateTime = timestamp_to_datetime(TimeStamp), Formatted = luerl_lib_os_date:format(DateTime, Fmt), {Enc, St1} = luerl:encode(Formatted, St), {[Enc],St1}; date(_, As, St) -> badarg_error(date, As, St). difftime(_, [T2,T1|_], St) -> {[T2 - T1],St}; difftime(_, As, St) -> badarg_error(difftime, As, St). time(_, As=[#tref{}=Tref], St) -> L = luerl_new:decode(Tref, St), compute_time(proplists:to_map(L), As, St); time(_, _, St) -> %Time since 1 Jan 1970 {[current_timestamp()],St}. compute_time(Map=#{<<"year">> := Y, <<"month">> := Mth, <<"day">> := D}, _, St) -> H = maps:get(<<"hour">>, Map, 12), Min = maps:get(<<"min">>, Map, 0), S = maps:get(<<"sec">>, Map, 0), LocalEpoch = calendar:universal_time_to_local_time({{1970,1,1},{0,0,0}}), Result = calendar:datetime_to_gregorian_seconds({{Y, Mth, D}, {H, Min, S}}) - calendar:datetime_to_gregorian_seconds(LocalEpoch), {[Result],St}; compute_time(Map, _As, St) -> MissingArg = lists:foldl(fun(K,Acc=undefined) -> case maps:is_key(K, Map) of false -> K; true -> Acc end; (_,Acc) -> Acc end, undefined, [<<"day">>, <<"month">>, <<"year">>]), badarg_error(time, MissingArg, St). current_timestamp() -> {Mega,Sec,Micro} = os:timestamp(), 1.0e6*Mega+Sec+Micro*1.0e-6. timestamp_to_datetime(Timestamp) -> SecondsSinceEpoch = round(Timestamp), calendar:system_time_to_local_time(SecondsSinceEpoch, second). luerl-1.2.3/src/luerl.erl0000664000175000017500000003342214677012037015651 0ustar debalancedebalance%% Copyright (c) 2013-2020 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl.erl %% Authors : Robert Virding, Henning Diedrich %% Purpose : The original basic LUA 5.2 interface. -module(luerl). -include("luerl.hrl"). -export([eval/2,evalfile/2, do/2,dofile/2, load/2,load/3, loadfile/2,loadfile/3, path_loadfile/2,path_loadfile/3,path_loadfile/4, load_module/3,load_module1/3, call/3,call_chunk/3, call_function/3,call_function1/3,function_list/2, call_method/3,call_method1/3,method_list/2, get_table/2,get_table1/2,set_table/3,set_table1/3,set_table1/4, init/0,stop/1,gc/1, set_trace_func/2,clear_trace_func/1, set_trace_data/2,get_trace_data/1, get_stacktrace/1, externalize/1,internalize/1 ]). %% Encoding and decoding. -export([encode/2,encode_list/2,decode/2,decode_list/2]). %% luerl:eval(String|Binary|Form, State) -> Result. eval(Chunk, St0) -> try do(Chunk, St0) of {Ret,St1} -> {ok, decode_list(Ret, St1)} catch ?CATCH(_C, E, S) {error, E, S} %{error, {E, R}} ? <- todo: decide end. %% luerl:evalfile(Path, State) -> {ok, Result} | {error,Reason}. evalfile(Path, St0) -> try dofile(Path, St0) of {Ret,St1} -> {ok, decode_list(Ret, St1)} catch ?CATCH(_C, E, S) {error, E, S} %{error, {E, R}} ? <- todo: decide end. %% luerl:do(String|Binary|Form, State) -> {Result, NewState} do(S, St0) when is_binary(S); is_list(S) -> {ok,Func,St1} = load(S, St0), luerl_emul:call(Func, St1); do(Func, St) -> luerl_emul:call(Func, St). %% luerl:dofile(Path, State) -> {Result, NewState}. dofile(Path, St0) -> {ok,Func,St1} = loadfile(Path, St0), luerl_emul:call(Func, St1). %% load(String|Binary, State) -> {ok,Function,NewState}. %% load(String|Binary, Options, State) -> {ok,Function,NewState}. load(Bin, St) -> load(Bin, [return], St). load(Bin, Opts, St) when is_binary(Bin) -> load(binary_to_list(Bin), Opts, St); load(Str, Opts, St0) when is_list(Str) -> case luerl_comp:string(Str, Opts) of {ok,Chunk} -> {Func,St1} = luerl_emul:load_chunk(Chunk, St0), {ok,Func,St1}; {error,_,_}=E -> E end. %% loadfile(FileName, State) -> {ok,Function,NewState}. %% loadfile(FileName, Options, State) -> {ok,Function,NewState}. loadfile(Name, St) -> loadfile(Name, [return], St). loadfile(Name, Opts, St0) -> case luerl_comp:file(Name, Opts) of {ok,Chunk} -> {Func,St1} = luerl_emul:load_chunk(Chunk, St0), {ok,Func,St1}; {error,_,_}=E -> E end. %% path_loadfile(FileName, State) -> {ok,Function,FullName,State}. %% path_loadfile(Path, FileName, State) -> {ok,Function,FullName,State}. %% path_loadfile(Path, FileName, Options, State) -> %% {ok,Function,FullName,State}. %% When no path is given we use the value of LUA_LOAD_PATH. %% We manually step down the path to get the correct handling of %% filenames by the compiler. path_loadfile(Name, St) -> Path = case os:getenv("LUA_LOAD_PATH") of false -> []; %You get what you asked for Env -> %% Get path separator depending on os type. Sep = case os:type() of {win32,_} -> ";"; _ -> ":" %Unix end, string:tokens(Env, Sep) %Split into path list end, path_loadfile(Path, Name, [return], St). path_loadfile(Dirs, Name, St) -> path_loadfile(Dirs, Name, [return], St). path_loadfile([Dir|Dirs], Name, Opts, St0) -> Full = filename:join(Dir, Name), case loadfile(Full, Opts, St0) of {ok,Func,St1} -> {ok,Func,Full,St1}; {error,[{_,_,enoent}],_} -> %Couldn't find the file path_loadfile(Dirs, Name, St0); Error -> Error end; path_loadfile([], _, _, _) -> {error,[{none,file,enoent}],[]}. %% load_module(TablePath, ModuleName, State) -> State. %% load_module1(LuaTablePath, ModuleName, State) -> State. %% Load module and add module table to the path. load_module(Fp, Mod, St0) when is_list(Fp) -> {Lfp,St1} = encode_list(Fp, St0), load_module1(Lfp, Mod, St1); load_module(_, _,_) -> error(badarg). load_module1(Lfp, Mod, St0) -> {Tab,St1} = Mod:install(St0), luerl_emul:set_table_keys(Lfp, Tab, St1). %% init() -> State. init() -> luerl_emul:init(). %% call(Chunk, Args, State) -> {Result,State} call(C, As, St) -> call_chunk(C, As, St). call_chunk(C, As, St0) -> {Las,St1} = encode_list(As, St0), {Lrs,St2} = luerl_emul:call(C, Las, St1), Rs = decode_list(Lrs, St2), {Rs,St2}. %% call_function(TablePath, Args, State) -> {Result,State}. %% call_function1(LuaTablePath | Func, LuaArgs, State) -> {LuaResult,State}. call_function(Fp, As, St0) -> %% Encode the input arguments. {Lfp,St1} = encode_list(Fp, St0), {Las,St2} = encode_list(As, St1), %% Find the function definition and call function. {Lrs,St3} = call_function1(Lfp, Las, St2), Rs = decode_list(Lrs, St3), {Rs,St3}. call_function1(Lfp, Las, St0) when is_list(Lfp) -> {F,St1} = luerl_emul:get_table_keys(Lfp, St0), luerl_emul:functioncall(F, Las, St1); call_function1(F, Las, St) -> luerl_emul:functioncall(F, Las, St). %% function_list(Keys, State) -> {V,State}. %% Go down a list of keys and return final value. function_list(Ks, St) -> luerl_emul:get_table_keys(Ks, St). %% call_method(FuncPath, Args, State) -> {Result,State}. %% call_method1(FuncPath | FuncPath, Args, State) -> {Result,State}. call_method(Fp, As, St0) -> %% Encode the input arguments. {Lfp,St1} = encode_list(Fp, St0), {Las,St2} = encode_list(As, St1), %% Find the object and method definition and call method. {O,M,St3} = method_list(Lfp, St2), {Lrs,St4} = luerl_emul:functioncall(M, [O|Las], St3), Rs = decode_list(Lrs, St4), {Rs,St4}. call_method1(Fp, Las, St0) -> %% Find the object and method definition and call method. {O,M,St1} = method_list(Fp, St0), luerl_emul:functioncall(M, [O|Las], St1). method_list([G|Ks], St0) -> {First,St1} = luerl_emul:get_global_key(G, St0), method_list(First, Ks, St1). method_list(Tab, [K], St0) -> {Func,St1} = luerl_emul:get_table_key(Tab, K, St0), {Tab,Func,St1}; method_list(Tab, [K|Ks], St0) -> {Next,St1} = luerl_emul:get_table_key(Tab, K, St0), method_list(Next, Ks, St1); method_list(_, _, _) -> error(badarg). %% get_table(TablePath, State) -> {Result, State}. %% Go down a list of keys and return decoded final value. get_table(Fp, St0) when is_list(Fp) -> {Lfp,St1} = encode_list(Fp, St0), {V,St2} = luerl_emul:get_table_keys(Lfp, St1), Vd = decode(V, St2), {Vd,St2}; get_table(_,_) -> error(badarg). %% get_table1(LuaTablePath, State) -> {LuaResult, State}. get_table1(Fp, St) when is_list(Fp) -> luerl_emul:get_table_keys(Fp, St); get_table1(_,_) -> error(badarg). %% set_table(TablePath, Value, State) -> State. %% Go down a list of keys and set final key to Value. set_table(Fp, V, St0) when is_list(Fp) -> {Lfp,St1} = encode_list(Fp, St0), {Lv, St2} = encode(V, St1), set_table1(Lfp, Lv, St2); set_table(_,_,_) -> error(badarg). %% set_table1(LuaTablePath, Value, State) -> State. %% Must explicitly read table key to get set_table1(Lfp, Lv, St) -> luerl_emul:set_table_keys(Lfp, Lv, St). %% set_table1(Table, Key, Value, State) -> State. %% Must explicitly read table key to get set_table1(Tab, Key, Lv, St) -> luerl_emul:set_table_key(Tab, Key, Lv, St). %% stop(State) -> GCedState. stop(St) -> luerl_heap:gc(St). %% gc(State) -> State. gc(St) -> luerl_heap:gc(St). %% set_trace_func(TraceFunction, State) -> State. %% clear_trace_func(State) -> State. %% get_trace_data(State) -> TraceData. %% set_trace_data(TraceData, State) -> State. %% Set the trace function and access the trace data. set_trace_func(Tfunc, St) -> St#luerl{trace_func=Tfunc}. clear_trace_func(St) -> St#luerl{trace_func=none}. get_trace_data(St) -> St#luerl.trace_data. set_trace_data(Tdata, St) -> St#luerl{trace_data=Tdata}. %% get_stacktrace(State) -> [{FuncName,[{file,FileName},{line,Line}]}]. get_stacktrace(#luerl{cs=Stack}=St) -> Fun = fun (Frame, Acc) -> do_stackframe(Frame, Acc, St) end, {_,Trace} = lists:foldl(Fun, {1,[]}, Stack), lists:reverse(Trace). do_stackframe(#call_frame{func=Funref,args=Args}, {Line,Trace}, St) -> case Funref of #funref{} -> {Func,_} = luerl_heap:get_funcdef(Funref, St), Anno = Func#lua_func.anno, Name = case luerl_anno:get(name, Anno) of undefined -> <<"-no-name-">>; N -> N end, File = luerl_anno:get(file, Anno), {Line,[{Name,Args,[{file,File},{line,Line}]} | Trace]}; #erl_func{code=Fun} -> {module,Module} = erlang:fun_info(Fun, module), {name,Name} = erlang:fun_info(Fun, name), FileName = get_filename(Module), {Line,[{{Module,Name},Args,[{file,FileName}]} | Trace]}; #erl_mfa{m=M,f=F,a=A} -> FileName = get_filename(M), %% {Line,[{{M,F},{A,Args},[{file,FileName}]} | Trace]}; %% {Line,[{{M,F},[A | Args],[{file,FileName}]} | Trace]}; {Line,[{{M,F,A},Args,[{file,FileName}]} | Trace]}; Other -> {Line,[{Other,Args,[{file,<<"-no-file-">>},{line,Line}]} | Trace]} end; do_stackframe(#current_line{line=Line}, {_,Trace}, _St) -> {Line,Trace}; do_stackframe(#loop_frame{}, Acc, _St) -> %Ignore these Acc. get_filename(Mod) -> Comp = erlang:get_module_info(Mod, compile), case lists:keyfind(source, 1, Comp) of {source,FileName} -> BaseName = filename:basename(FileName), list_to_binary(BaseName); false -> %The compiler doesn't know <<"-no-file-">> end. %% Define IS_MAP/1 macro for is_map/1 bif. -ifdef(HAS_MAPS). -define(IS_MAP(T), is_map(T)). -else. -define(IS_MAP(T), false). -endif. %% encode_list([Term], State) -> {[LuerlTerm],State}. %% encode(Term, State) -> {LuerlTerm,State}. encode_list(Ts, St) -> lists:mapfoldl(fun encode/2, St, Ts). encode(nil, St) -> {nil,St}; encode(false, St) -> {false,St}; encode(true, St) -> {true,St}; encode(B, St) when is_binary(B) -> {B,St}; encode(A, St) when is_atom(A) -> {atom_to_binary(A, utf8),St}; encode(N, St) when is_number(N) -> {N,St}; %Integers and floats encode(F, St) when ?IS_MAP(F) -> encode(maps:to_list(F), St); encode(L, St0) when is_list(L) -> {Es,{_,St1}} = lists:mapfoldl(fun ({K0,V0}, {I,S0}) -> {K1,S1} = encode(K0, S0), {V1,S2} = encode(V0, S1), {{K1,V1},{I,S2}}; (V0, {I,S0}) -> {V1,S1} = encode(V0, S0), {{I,V1},{I+1,S1}} end, {1,St0}, L), {T,St2} = luerl_heap:alloc_table(Es, St1), {T,St2}; %No more to do for now encode(F, St) when is_function(F, 2) -> F1 = fun(Args, State) -> Args1 = decode_list(Args, State), {Res, State1} = F(Args1, State), encode_list(Res, State1) end, {#erl_func{code=F1}, St}; encode(F, St) when is_function(F, 1) -> F1 = fun(Args, State) -> Args1 = decode_list(Args, State), Res = F(Args1), encode_list(Res, State) end, {#erl_func{code=F1}, St}; encode({M,F,A}, St) when is_atom(M) and is_atom(F) -> {#erl_mfa{m=M,f=F,a=A}, St}; encode({userdata,Data}, St) -> luerl_heap:alloc_userdata(Data, St); % Table refs should not be re-encoded encode(#tref{}=T, St) -> case luerl_heap:chk_table(T, St) of ok -> {T, St}; error -> error(badarg) end; encode(_, _) -> error(badarg). %Can't encode anything else %% decode_list([LuerlTerm], State) -> [Term]. %% decode(LuerlTerm, State) -> Term. %% In decode we track of which tables we have seen to detect %% recursive references and generate an error when that occurs. decode_list(Lts, St) -> lists:map(fun (Lt) -> decode(Lt, St) end, Lts). decode(LT, St) -> decode(LT, St, []). decode(nil, _, _) -> nil; decode(false, _, _) -> false; decode(true, _, _) -> true; decode(B, _, _) when is_binary(B) -> B; decode(N, _, _) when is_number(N) -> N; %Integers and floats decode(#tref{}=T, St, In) -> decode_table(T, St, In); decode(#usdref{}=U, St, _) -> decode_userdata(U, St); decode(#funref{}=Fun, State, _) -> F = fun(Args) -> {Args1, State1} = encode_list(Args, State), {Ret, State2} = luerl_emul:functioncall(Fun, Args1, State1), decode_list(Ret, State2) end, F; %Just a bare fun decode(#erl_func{code=Fun}, _, _) -> Fun; decode(#erl_mfa{m=M,f=F,a=A}, _, _) -> {M,F,A}; decode(_, _, _) -> error(badarg). %Shouldn't have anything else decode_table(#tref{i=N}=T, St, In0) -> case lists:member(N, In0) of true -> error({recursive_table,T}); %Been here before false -> In1 = [N|In0], %We are in this as well case luerl_heap:get_table(T, St) of #table{a=Arr,d=Dict} -> Fun = fun (K, V, Acc) -> [{decode(K, St, In1),decode(V, St, In1)}|Acc] end, Ts = ttdict:fold(Fun, [], Dict), array:sparse_foldr(Fun, Ts, Arr); _Undefined -> error(badarg) end end. decode_userdata(U, St) -> {#userdata{d=Data},_} = luerl_heap:get_userdata(U, St), {userdata,Data}. %% Externalize and Internalize ensure that the VM state passed in %% can be stored externally or can be recreated from external storage. %% Currently very simple: only random state needs special treatment. externalize(S) -> luerl_lib_math:externalize(S). internalize(S) -> luerl_lib_math:internalize(S). luerl-1.2.3/src/luerl_comp_locf.erl0000664000175000017500000002126614677012037017675 0ustar debalancedebalance%% Copyright (c) 2013 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_comp_locf.erl %% Author : Robert Virding %% Purpose : A basic LUA 5.3 compiler for Luerl. %% Does local function analysis. -module(luerl_comp_locf). -include("luerl.hrl"). -include("luerl_comp.hrl"). -export([chunk/2]). -import(ordsets, [add_element/2,is_element/2,union/1,union/2, subtract/2,intersection/2]). %% chunk(Code, CompInfo) -> %% {ok,Code} | {ok,Code,Warnings} | {error,Error}. chunk(Code0, #cinfo{opts=Opts}=_Ci) -> {Code1,_,nul} = exp(Code0, nul), %No local state here! luerl_comp:debug_print(Opts, "cf: ~p\n", [Code1]), {ok,Code1}. %% stmt(Stmts, State) -> {Stmts,LocalFunc,State}. stmts([S0|Ss0], St0) -> {S1,Slocf,St1} = stmt(S0, St0), {Ss1,Sslocf,St2} = stmts(Ss0, St1), Locf = Slocf or Sslocf, {[S1|Ss1],Locf,St2}; stmts([], St) -> {[],false,St}. %% stmt(Stmt, State) -> {Stmt,LocalFunc,State}. stmt(#assign_stmt{}=A, St) -> assign_stmt(A, St); stmt(#call_stmt{}=C, St) -> call_stmt(C, St); stmt(#return_stmt{}=R, St) -> return_stmt(R, St); stmt(#break_stmt{}=B, St) -> {B,false,St}; stmt(#block_stmt{}=B, St) -> block_stmt(B, St); stmt(#while_stmt{}=W, St) -> while_stmt(W, St); stmt(#repeat_stmt{}=R, St) -> repeat_stmt(R, St); stmt(#if_stmt{}=If, St) -> if_stmt(If, St); stmt(#nfor_stmt{}=For, St) -> numfor_stmt(For, St); stmt(#gfor_stmt{}=For, St) -> genfor_stmt(For, St); stmt(#local_assign_stmt{}=L, St) -> local_assign_stmt(L, St); stmt(#local_fdef_stmt{}=L, St) -> local_fdef_stmt(L, St); stmt(#expr_stmt{}=E, St) -> expr_stmt(E, St). %% assign_stmt(Assign, State) -> {Assign,LocalFunc,State}. assign_stmt(#assign_stmt{vars=Vs0,exps=Es0}=A, St0) -> {Vs1,Vlocf,St1} = assign_loop(Vs0, St0), {Es1,Elocf,St2} = explist(Es0, St1), Locf = Vlocf or Elocf, {A#assign_stmt{vars=Vs1,exps=Es1},Locf,St2}. assign_loop([V0|Vs0], St0) -> {V1,Vlocf,St1} = var(V0, St0), {Vs1,Vslocf,St2} = assign_loop(Vs0, St1), Locf = Vlocf or Vslocf, {[V1|Vs1],Locf,St2}; assign_loop([], St) -> {[],false,St}. var(#dot{exp=Exp0,rest=Rest0}=D, St0) -> {Exp1,Elocf,St1} = prefixexp_first(Exp0, St0), {Rest1,Rlocf,St2} = var_rest(Rest0, St1), {D#dot{exp=Exp1,rest=Rest1},Elocf or Rlocf,St2}; var(V, St) -> {V,false,St}. var_rest(#dot{exp=Exp0,rest=Rest0}=D, St0) -> {Exp1,Elocf,St1} = prefixexp_element(Exp0, St0), {Rest1,Rlocf,St2} = var_rest(Rest0, St1), {D#dot{exp=Exp1,rest=Rest1},Elocf or Rlocf,St2}; var_rest(Exp, St) -> var_last(Exp, St). var_last(#key{key=Exp0}=K, St0) -> {Exp1,Elocf,St1} = exp(Exp0, St0), {K#key{key=Exp1},Elocf,St1}. %% call_stmt(Call, State) -> {Call,LocalFunc,State}. call_stmt(#call_stmt{call=Exp0}=C, St0) -> {Exp1,Locf,St1} = exp(Exp0, St0), {C#call_stmt{call=Exp1},Locf,St1}. %% return_stmt(Return, State) -> {Return,LocalFunc,State}. return_stmt(#return_stmt{exps=Es0}=R, St0) -> {Es1,Locf,St1} = explist(Es0, St0), {R#return_stmt{exps=Es1},Locf,St1}. %% block_stmt(Block, State) -> {Block,LocalFunc,State}. block_stmt(#block_stmt{body=Ss0}=B, St0) -> {Ss1,Sslocf,St1} = stmts(Ss0, St0), {B#block_stmt{body=Ss1,locf=Sslocf},Sslocf,St1}. %% do_block(Block, State) -> {Block,LocalFunc,State}. do_block(#block{body=Ss0}=B, St0) -> {Ss1,Sslocf,St1} = stmts(Ss0, St0), {B#block{body=Ss1,locf=Sslocf},Sslocf,St1}. %% while_stmt(While, State) -> {While,LocalFunc,State}. %% The test expression is done in the context of the surrounding %% block. while_stmt(#while_stmt{exp=E0,body=B0}=W, St0) -> {E1,Elocf,St1} = exp(E0, St0), {B1,Blocf,St2} = do_block(B0, St1), {W#while_stmt{exp=E1,body=B1},Elocf or Blocf,St2}. %% repeat_stmt(Repeat, State) -> {Repeat,LocalFunc,State}. %% The test expression is done in the context of the repeat block. repeat_stmt(#repeat_stmt{body=B0}=R, St0) -> {B1,Blocf,St1} = do_block(B0, St0), {R#repeat_stmt{body=B1},Blocf,St1}. %% if_stmt(If, State) -> {If,LocalFunc,State}. %% The block info includes anything from the test expressions even %% though we keep them separate. if_stmt(#if_stmt{tests=Ts0,else_block=E0}=If, St0) -> {Ts1,Tlocf,St1} = if_tests(Ts0, St0), {E1,Elocf,St2} = do_block(E0, St1), Locf = Tlocf or Elocf, {If#if_stmt{tests=Ts1,else_block=E1},Locf,St2}. if_tests([{E0,B0}|Ts0], St0) -> {E1,Elocf,St1} = exp(E0, St0), {B1,Blocf,St2} = do_block(B0, St1), {Ts1,Tslocf,St3} = if_tests(Ts0, St2), Locf = Elocf or Blocf or Tslocf, {[{E1,B1}|Ts1],Locf,St3}; if_tests([], St) -> {[],false,St}. %% numfor_stmt(For, State) -> {For,LocalFunc,State}. numfor_stmt(#nfor_stmt{init=I0,limit=L0,step=S0,body=B0}=For, St0) -> {[I1,L1,S1],Eslocf,St1} = explist([I0,L0,S0], St0), {B1,Blocf,St2} = do_block(B0, St1), Locf = Eslocf or Blocf, {For#nfor_stmt{init=I1,limit=L1,step=S1,body=B1},Locf,St2}. %% genfor_stmt(For, State) -> {For,LocalFunc,State}. genfor_stmt(#gfor_stmt{gens=Gs0,body=B0}=For, St0) -> {Gs1,Glocf,St1} = explist(Gs0, St0), {B1,Blocf,St2} = do_block(B0, St1), Locf = Glocf or Blocf, {For#gfor_stmt{gens=Gs1,body=B1},Locf,St2}. %% local_assign_stmt(Local, State) -> {Local,LocalFunc,State}. local_assign_stmt(#local_assign_stmt{exps=Es0}=L, St0) -> {Es1,Eslocf,St1} = explist(Es0, St0), {L#local_assign_stmt{exps=Es1},Eslocf,St1}. %% local_fdef_stmt(Local, State) -> {Local,LocalFunc,State}. local_fdef_stmt(#local_fdef_stmt{func=F0}=L, St0) -> {F1,_,St1} = functiondef(F0, St0), %Don't care what's in func {L#local_fdef_stmt{func=F1},true,St1}. %% expr_stmt(Expr, State) -> {Expr,LocalFunc,State}. %% The expression pseudo statement. This will return a single value. expr_stmt(#expr_stmt{exp=Exp0}=E, St0) -> {Exp1,Locf,St1} = exp(Exp0, St0), {E#expr_stmt{exp=Exp1},Locf,St1}. %% explist(Exprs, State) -> {Exprs,LocalFunc,State}. %% exp(Expr, State) -> {Expr,LocalFunc,State}. explist([E0|Es0], St0) -> {E1,Elocf,St1} = exp(E0, St0), {Es1,Eslocf,St2} = explist(Es0, St1), {[E1|Es1],Elocf or Eslocf,St2}; explist([], St) -> {[],false,St}. %No expressions at all exp(#lit{}=L, St) -> {L,false,St}; %Nothing to do exp(#fdef{}=F0, St0) -> {F1,_,St1} = functiondef(F0, St0), %Don't care what's in func {F1,true,St1}; exp(#op{args=Es0}=Op, St0) -> {Es1,Eslocf,St1} = explist(Es0, St0), {Op#op{args=Es1},Eslocf,St1}; exp(#tabcon{fields=Fs0}=T, St0) -> {Fs1,Tlocf,St1} = tableconstructor(Fs0, St0), {T#tabcon{fields=Fs1},Tlocf,St1}; exp(E, St) -> prefixexp(E, St). prefixexp(#dot{exp=Exp0,rest=Rest0}=D, St0) -> {Exp1,Elocf,St1} = prefixexp_first(Exp0, St0), {Rest1,Rlocf,St2} = prefixexp_rest(Rest0, St1), {D#dot{exp=Exp1,rest=Rest1},Elocf or Rlocf,St2}; prefixexp(Exp, St) -> prefixexp_first(Exp, St). prefixexp_first(#single{exp=E0}=S, St0) -> {E1,Elocf,St1} = exp(E0, St0), {S#single{exp=E1},Elocf,St1}; prefixexp_first(V, St) -> {V,false,St}. prefixexp_rest(#dot{exp=Exp0,rest=Rest0}=D, St0) -> {Exp1,Elocf,St1} = prefixexp_element(Exp0, St0), {Rest1,Rlocf,St2} = prefixexp_rest(Rest0, St1), {D#dot{exp=Exp1,rest=Rest1},Elocf or Rlocf,St2}; prefixexp_rest(Exp, St) -> prefixexp_element(Exp, St). prefixexp_element(#key{key=E0}=K, St0) -> {E1,Elocf,St1} = exp(E0, St0), {K#key{key=E1},Elocf,St1}; prefixexp_element(#fcall{args=As0}=F, St0) -> {As1,Aslocf,St1} = explist(As0, St0), {F#fcall{args=As1},Aslocf,St1}; prefixexp_element(#mcall{args=As0}=M, St0) -> {As1,Aslocf,St1} = explist(As0, St0), {M#mcall{args=As1},Aslocf,St1}. %% functiondef(Func, State) -> {Func,LocalFunc,State}. %% We return if there are any internal function definitions within %% the function. functiondef(#fdef{body=Ss0}=F, St0) -> {Ss1,Sslocf,St1} = stmts(Ss0, St0), {F#fdef{body=Ss1,locf=Sslocf},Sslocf,St1}. %% tableconstructor(Fields, State) -> {Fields,LocalFunc,State}. tableconstructor(Fs0, St0) -> Fun = fun (#efield{val=V0}=F, {Locf,S0}) -> {V1,Vlocf,S1} = exp(V0, S0), {F#efield{val=V1},{Locf or Vlocf,S1}}; (#kfield{key=K0,val=V0}=F, {Locf,S0}) -> {K1,Klocf,S1} = exp(K0, S0), {V1,Vlocf,S2} = exp(V0, S1), {F#kfield{key=K1,val=V1},{Locf or Klocf or Vlocf,S2}} end, {Fs1,{Locf,St1}} = lists:mapfoldl(Fun, {false,St0}, Fs0), {Fs1,Locf,St1}. luerl-1.2.3/src/luerl_lib_os_date.erl0000664000175000017500000001733114677012037020176 0ustar debalancedebalance%% Copyright (c) 2023-2024 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : lib_date_support.erl %% Author : Mark Meeus %% Purpose : Date Support Module -module(luerl_lib_os_date). -export([format/2]). %% IMPLEMENTED FORMATS: %% %A - Full weekday name (eg. Wednesday) %% %a - Abbreviated weekday name (eg. Wed) %% %B - Full month name (eg. September) %% %b - Abbreviated month name (eg. Sep) %% %c - date and time (e.g. Wed Jan 24 12:27:59 2024) %% %D - date (e.g. 09/16/98) %% %d - Day of month as decimal number (01 - 31) %% %e - Day of month as decimal number ( 1 - 31) %% %F - date (e.g. 2024-01-31) %% %H - Hour in 24-hour format (00 - 23) %% %I - Hour in 12-hour format (01 - 12) %% %M - Minute as decimal number (00 - 59) %% %m - Month as decimal number (01 - 12) %% %n - Newline character %% %P - As %p but lowercase %% %p - Current locale’s A.M./P.M. indicator for 12-hour clock (eg. AM/PM) %% %S - Second as decimal number (00 - 59) %% %T - time (e.g. 23:48:10) %% %t - Tab character %% %u - Weekday as decimal number (1 - 7; Monday is 1) %% %V - IOS week number (01 - 53) %% %W - Week of year as decimal number, with Monday as first day of week 1 (00 - 53) %% %w - Weekday as decimal number (0 - 6; Sunday is 0) %% %X - time (e.g., 23:48:10) %% %x - date (e.g., 09/16/98) %% %Y - Year with century, as decimal number (eg. 2007) %% %y - Year without century, as decimal number (00 - 99) (eg. 07) %% %Z - Time-zone name or abbreviation; no characters if time zone is unknown %% %% - Percent sign %% NOT IMPLEMENTED: %% %j - Day of year as decimal number (001 - 366) %% %U - Week of year as decimal number, with Sunday as first day of week 1 (00 - 53) %% format(DateTime, Format) -> Formatted. %% *t format returns a table with the datetime values. format(DateTime, <<"*t">>) -> {{Ye,Mo,Da}=Date,{Ho,Mi,Sec}} = DateTime, [ {<<"year">>, Ye}, {<<"month">>, Mo}, {<<"day">>, Da}, {<<"hour">>, Ho}, {<<"min">>, Mi}, {<<"sec">>, Sec}, {<<"wday">>, get_day_number(Date)+1} ]; format(DateTime, Format) -> Patterns = [ <<"%A">>, <<"%a">>, <<"%B">>, <<"%b">>, <<"%c">>, <<"%D">>, <<"%d">>, <<"%e">>, <<"%F">>, <<"%H">>, <<"%I">>, <<"%M">>, <<"%m">>, <<"%n">>, <<"%P">>, <<"%p">>, <<"%S">>, <<"%T">>, <<"%t">>, <<"%u">>, <<"%V">>, <<"%W">>, <<"%w">>, <<"%X">>, <<"%x">>, <<"%Y">>, <<"%y">>, <<"%Z">>, <<"%%">> ], lists:foldl(fun(Pat, Str) -> replace_pattern(Str, DateTime, Pat) end, Format, Patterns). replace_pattern(Str, DateTime, Pat) -> case re:run(Str, Pat) of nomatch -> Str; {match, _} -> {Format, Val} = get_pattern_values(Pat, DateTime), Formatted = io_lib:fwrite(Format, Val), re:replace(Str, Pat, Formatted, [{return, binary}, global]) end. %% get_pattern_values(Patters, DateTime) -> {FormatString, Values}. get_pattern_values(<<"%A">>, {Date, _}) -> {"~s", [get_day_name(get_day_number(Date))]}; get_pattern_values(<<"%a">>, {Date, _}) -> {"~s", [get_abbreviated_day_name(get_day_number(Date))]}; get_pattern_values(<<"%B">>, {{_, Mo, _}, _}) -> {"~s", [get_month_name(Mo)]}; get_pattern_values(<<"%b">>, {{_, Mo, _}, _}) -> {"~s", [get_abbreviated_month_name(Mo)]}; get_pattern_values(<<"%c">>, {{Ye, Mo, Da}=Date, {Ho, Mi, Sec}}) -> {"~s ~s ~.2w ~.2.0w:~.2.0w:~.2.0w ~.4.0w", [get_abbreviated_day_name(get_day_number(Date)), get_abbreviated_month_name(Mo),Da, Ho,Mi,Sec, Ye]}; get_pattern_values(<<"%D">>, {{Ye, Mo, Da}, _}) -> {"~.2.0w/~.2.0w/~.2.0w", [Mo, Da, Ye rem 100]}; get_pattern_values(<<"%d">>, {{_, _, Da}, _}) -> {"~.2.0w", [Da]}; get_pattern_values(<<"%e">>, {{_, _, Da}, _}) -> {"~.2w", [Da]}; get_pattern_values(<<"%F">>, {{Ye, Mo, Da}, _}) -> {"~.4.0w-~.2.0w-~.2.0w", [Ye, Mo, Da]}; get_pattern_values(<<"%H">>, {_, {Ho, _, _}}) -> {"~.2.0w", [Ho]}; get_pattern_values(<<"%I">>, {_, {Ho, _, _}}) -> {"~.2.0w", [get_am_pm_hour(Ho)]}; get_pattern_values(<<"%M">>, {_, {_, Mi, _}}) -> {"~.2.0w", [Mi]}; get_pattern_values(<<"%m">>, {{_, Mo, _}, _}) -> {"~.2.0w", [Mo]}; get_pattern_values(<<"%n">>, _) -> {"\n", []}; get_pattern_values(<<"%P">>, {_, {Ho, _, _}}) -> Val = if Ho < 12 -> <<"am">>; true -> <<"pm">> end, {"~s", [Val]}; get_pattern_values(<<"%p">>, {_, {Ho, _, _}}) -> Val = if Ho < 12 -> <<"AM">>; true -> <<"PM">> end, {"~s", [Val]}; get_pattern_values(<<"%S">>, {_, {_, _, Sec}}) -> {"~.2.0w", [Sec]}; get_pattern_values(<<"%T">>, {_, {Ho, Mi, Sec}}) -> {"~.2.0w:~.2.0w:~.2.0w", [Ho, Mi, Sec]}; get_pattern_values(<<"%t">>, _) -> {"\t", []}; get_pattern_values(<<"%u">>, {Date, _}) -> {"~.1.0w", [calendar:day_of_the_week(Date)]}; % Mon = 1 Sun = 7 get_pattern_values(<<"%V">>, {Date, _}) -> {_Year,Week} = calendar:iso_week_number(Date), {"~.2.0w", [Week]}; get_pattern_values(<<"%W">>, {Date, _}) -> {_Year,Week} = calendar:iso_week_number(Date), {"~.2.0w", [Week]}; get_pattern_values(<<"%w">>, {Date, _}) -> {"~.1.0w", [get_day_number(Date)]}; % Sun = 0 Sat = 6 get_pattern_values(<<"%X">>, {_, {Ho, Mi, Sec}}) -> {"~.2.0w:~.2.0w:~.2.0w", [Ho, Mi, Sec]}; get_pattern_values(<<"%x">>, {{Ye, Mo, Da}, _}) -> {"~.2.0w/~.2.0w/~.2.0w", [Mo, Da, Ye rem 100]}; get_pattern_values(<<"%Y">>, {{Ye, _, _}, _}) -> {"~.4.0w", [Ye]}; get_pattern_values(<<"%y">>, {{Ye, _, _}, _}) -> {"~.2.0w", [Ye rem 100]}; get_pattern_values(<<"%Z">>, _) -> {"", []}; get_pattern_values(<<"%%">>, _) -> {"~c", [$%]}. %% get_day_number(Date) -> DayNumber. %% This is US so Sunday is day 1. get_day_number(Date) -> calendar:day_of_the_week(Date) rem 7. get_am_pm_hour(0) -> 12; get_am_pm_hour(H) when H > 12 -> H - 12; get_am_pm_hour(H) -> H. get_month_name(1) -> "January"; get_month_name(2) -> "February"; get_month_name(3) -> "March"; get_month_name(4) -> "April"; get_month_name(5) -> "May"; get_month_name(6) -> "June"; get_month_name(7) -> "July"; get_month_name(8) -> "August"; get_month_name(9) -> "September"; get_month_name(10) -> "October"; get_month_name(11) -> "November"; get_month_name(12) -> "December". get_abbreviated_month_name(1) -> "Jan"; get_abbreviated_month_name(2) -> "Feb"; get_abbreviated_month_name(3) -> "Mar"; get_abbreviated_month_name(4) -> "Apr"; get_abbreviated_month_name(5) -> "May"; get_abbreviated_month_name(6) -> "Jun"; get_abbreviated_month_name(7) -> "Jul"; get_abbreviated_month_name(8) -> "Aug"; get_abbreviated_month_name(9) -> "Sep"; get_abbreviated_month_name(10) -> "Oct"; get_abbreviated_month_name(11) -> "Nov"; get_abbreviated_month_name(12) -> "Dec". get_day_name(0) -> "Sunday"; get_day_name(1) -> "Monday"; get_day_name(2) -> "Tuesday"; get_day_name(3) -> "Wednesday"; get_day_name(4) -> "Thursday"; get_day_name(5) -> "Friday"; get_day_name(6) -> "Saturday". get_abbreviated_day_name(0) -> "Sun"; get_abbreviated_day_name(1) -> "Mon"; get_abbreviated_day_name(2) -> "Tue"; get_abbreviated_day_name(3) -> "Wed"; get_abbreviated_day_name(4) -> "Thu"; get_abbreviated_day_name(5) -> "Fri"; get_abbreviated_day_name(6) -> "Sat". luerl-1.2.3/src/luerl_comp.erl0000664000175000017500000002464414677012037016675 0ustar debalancedebalance%% Copyright (c) 2013-2019 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_comp.erl %% Author : Robert Virding %% Purpose : A basic LUA 5.3 compiler for Luerl. %% This is the main loop of the Luerl compiler. While we can handle %% errors in this loop they should never occur as Lua basically allows %% almost everything that gets past the parser. The only exception are %% goto's to undefined labels, but we don't handle goto's yet. %% %% We also have the first pass here. It normalises the code and %% converts to an internal form. -module(luerl_comp). -export([file/1,file/2,string/1,string/2,chunk/1,chunk/2]). -export([forms/1,forms/2]). -export([debug_print/3]). -import(lists, [member/2,keysearch/3,mapfoldl/3,foreach/2]). -include_lib("kernel/include/file.hrl"). -include("luerl.hrl"). -include("luerl_comp.hrl"). %% The main Lua compiler state. -record(luacomp, {base="", %Base name ldir="", %Lua file dir lfile="", %Lua file odir=".", %Output directory opts=[], %User options code=none, %Code after last pass. cinfo=none, %Common compiler info errors=[], warnings=[] }). -define(NOFILE, "-no-file-"). %% file(Name) -> %% {ok,Chunk} | {error,Error,Warnings} | error}. %% file(Name, Options) -> %% {ok,Chunk} | {error,Error,Warnings} | error}. file(Name) -> file(Name, [verbose,report]). file(Name, Opts) -> St0 = #luacomp{opts=Opts}, St1 = filenames(Name, St0), do_compile(file_passes(), St1). %% string(String) -> %% {ok,Chunk} | {error,Error,Warnings} | error}. %% string(String, Options) -> %% {ok,Chunk} | {error,Error,Warnings} | error}. string(Str) -> string(Str, [verbose,report]). string(Str, Opts) when is_binary(Str) -> string(binary_to_list(Str), Opts); string(Str, Opts) when is_list(Str) -> St0 = #luacomp{opts=Opts,code=Str}, File = prop(module, Opts, ?NOFILE), St1 = filenames(File, St0), do_compile(list_passes(), St1). %% chunk(Chunk) -> %% {ok,Chunk} | {error,Error,Warnings} | error}. %% chunk(Chunk, Options) -> %% {ok,Chunk} | {error,Error,Warnings} | error}. chunk(Chunk) -> chunk(Chunk, [verbose,report]). chunk(Chunk, Opts) -> St0 = #luacomp{opts=Opts,code=Chunk}, File = prop(module, Opts, ?NOFILE), St1 = filenames(File, St0), do_compile(chunk_passes(), St1). %% forms(Forms) %% forms(Forms, Options) %% The deprecated fuuncttions for compiling a chunk. forms(C) -> chunk(C). forms(C, Opts) -> chunk(C, Opts). %% do_compile(Passes, CompilerState) -> %% {ok,Code} | {error,Error,Warnings} | error. do_compile(Passes, St0) -> %% The compiler state already contains the filenames. Cinfo = compiler_info(St0), %The compiler info St1 = St0#luacomp{cinfo=Cinfo}, case do_passes(Passes, St1) of {ok,St2} -> do_ok_return(St2); {error,St2} -> do_error_return(St2) end. %% filenames(File, State) -> State. %% The default output dir is the current directory unless an %% explicit one has been given in the options. filenames(?NOFILE, St) -> St#luacomp{lfile=?NOFILE}; filenames(File, St) -> Suffix = ".lua", %% Test for explicit outdir. Odir = prop(outdir, St#luacomp.opts, "."), Ldir = filename:dirname(File), Base = filename:basename(File, Suffix), Lfile = luafile(Ldir, Base, Suffix), St#luacomp{base=Base, ldir=Ldir, lfile=Lfile, odir=Odir}. luafile(".", Base, Suffix) -> Base ++ Suffix; luafile(Dir, Base, Suffix) -> filename:join(Dir, Base ++ Suffix). %% prop(Key, PropList, Default) -> Value | Default. %% Find Key, Val from PropList else Default. prop(Key, [{Key,Val}|_], _Def) -> Val; prop(Key, [_|Plist], Def) -> prop(Key, Plist, Def); prop(_Key, [], Def) -> Def. %% compiler_info(State) -> CompInfo. %% Initialise the #cinfo record passed into all compiler passes. compiler_info(#luacomp{lfile=F,opts=Opts}) -> %% The file option may get a binary so we are helpful. Vfile = iolist_to_binary(prop(file, Opts, F)), #cinfo{lfile=F,vfile=Vfile,opts=Opts}. %% file_passes() -> [Pass]. %% list_passes() -> [Pass]. %% chunk_passes() -> [Pass]. %% Build list of passes. file_passes() -> %Reading from file [{do,fun do_scan_file/1}, {when_flag,to_scan,{done,fun(St) -> {ok,St} end}}, {do,fun do_parse/1} | chunk_passes()]. list_passes() -> %Scanning string [{do,fun do_scan_string/1}, {when_flag,to_scan,{done,fun(St) -> {ok,St} end}}, {do,fun do_parse/1}| chunk_passes()]. chunk_passes() -> %Doing the chunk [{when_flag,to_parse,{done,fun(St) -> {ok,St} end}}, {do,fun do_init_comp/1}, {do,fun do_comp_normalise/1}, {when_flag,to_norm,{done,fun(St) -> {ok,St} end}}, {do,fun do_comp_lint/1}, {do,fun do_comp_vars/1}, {when_flag,to_vars,{done,fun(St) -> {ok,St} end}}, %% {do,fun do_comp_locf/1}, {do,fun do_comp_env/1}, {when_flag,to_env,{done,fun(St) -> {ok,St} end}}, {do,fun do_code_gen/1}, {unless_flag,no_iopt,{do,fun do_peep_op/1}}]. %% do_passes(Passes, State) -> {ok,State} | {error,Reason}. %% Interpret the list of commands in a pass. %% %% Commands can be one of: %% %% {when_flag,Flag,Cmd} %% {unless_flag,Flag,Cmd} %% {do,Fun} %% {done,PrintFun,Ext} do_passes([{do,Fun}|Ps], St0) -> case Fun(St0) of {ok,St1} -> do_passes(Ps, St1); {error,St1} -> {error,St1} end; do_passes([{when_flag,Flag,Cmd}|Ps], St) -> case member(Flag, St#luacomp.opts) of true -> do_passes([Cmd|Ps], St); false -> do_passes(Ps, St) end; do_passes([{unless_flag,Flag,Cmd}|Ps], St) -> case member(Flag, St#luacomp.opts) of true -> do_passes(Ps, St); false -> do_passes([Cmd|Ps], St) end; do_passes([{done,Fun}|_], St) -> Fun(St); do_passes([], St) -> {ok,St}. %% do_scan_file(State) -> {ok,State} | {error,State}. %% do_scan_string(State) -> {ok,State} | {error,State}. %% do_parse(State) -> {ok,State} | {error,State}. %% do_init_comp(State) -> {ok,State} | {error,State}. %% do_comp_normalise(State) -> {ok,State} | {error,State}. %% do_comp_lint(State) -> {ok,State} | {error,State}. %% do_comp_vars(State) -> {ok,State} | {error,State}. %% do_comp_env(State) -> {ok,State} | {error,State}. %% do_comp_cg(State) -> {ok,State} | {error,State}. %% do_comp_peep(State) -> {ok,State} | {error,State}. %% The actual compiler passes. do_scan_file(#luacomp{lfile=Name,opts=Opts}=St) -> %% Read the bytes in a file skipping an initial # line or Windows BOM. case file:open(Name, [read,{encoding,unicode}]) of {ok,F} -> %% Check if first line a script or Windows BOM, if so skip it. case io:get_line(F, '') of "#" ++ _ -> ok; %Skip line [239,187,191|_] -> file:position(F, 3); %Skip BOM _ -> file:position(F, bof) %Get it all end, %% Now read the file. Ret = case io:request(F, {get_until,unicode,'',luerl_scan,tokens,[1]}) of {ok,Ts,_} -> debug_print(Opts, "scan: ~p\n", [Ts]), {ok,St#luacomp{code=Ts}}; {error,E,_} -> {error,St#luacomp{errors=[E]}} end, file:close(F), Ret; {error,E} -> {error,St#luacomp{errors=[{none,file,E}]}} end. do_scan_string(#luacomp{code=Str,opts=Opts}=St) -> case luerl_scan:string(Str) of {ok,Ts,_} -> debug_print(Opts, "scan: ~p\n", [Ts]), {ok,St#luacomp{code=Ts}}; {error,E,_} -> {error,St#luacomp{errors=[E]}} end. do_parse(#luacomp{code=Ts,opts=Opts}=St) -> case luerl_parse:chunk(Ts) of {ok,Chunk} -> debug_print(Opts, "parse: ~p\n", [Chunk]), {ok,St#luacomp{code=Chunk}}; {error,E} -> {error,St#luacomp{errors=[E]}} end. do_init_comp(#luacomp{}=St) -> %% Nothing to do here now. {ok,St}. do_comp_normalise(#luacomp{code=Code0,cinfo=Cinfo}=St) -> {ok,Code1} = luerl_comp_normalise:chunk(Code0, Cinfo), {ok,St#luacomp{code=Code1}}. do_comp_lint(#luacomp{code=Code,cinfo=Cinfo}=St) -> case luerl_comp_lint:chunk(Code, Cinfo) of {ok,Ws} -> {ok,St#luacomp{warnings=Ws}}; {error,Es,Ws} -> {error,St#luacomp{errors=Es,warnings=Ws}} end. do_comp_vars(#luacomp{code=Code0,cinfo=Cinfo}=St) -> {ok,Code1} = luerl_comp_vars:chunk(Code0, Cinfo), {ok,St#luacomp{code=Code1}}. %% do_comp_locf(#luacomp{code=Code0,cinfo=Cinfo}=St) -> %% case luerl_comp_locf:chunk(Code0, Cinfo) of %% {ok,Code1} -> {ok,St#luacomp{code=Code1}}; %% {ok,Code1,Ws} -> {ok,St#luacomp{code=Code1,warnings=Ws}}; %% {error,Es} -> {error,St#luacomp{errors=Es}} %% end. do_comp_env(#luacomp{code=Code0,cinfo=Cinfo}=St) -> {ok,Code1} = luerl_comp_env:chunk(Code0, Cinfo), {ok,St#luacomp{code=Code1}}. do_code_gen(#luacomp{code=Code0,cinfo=Cinfo}=St) -> {ok,Code1} = luerl_comp_cg:chunk(Code0, Cinfo), {ok,St#luacomp{code=Code1}}. do_peep_op(#luacomp{code=Code0,cinfo=Cinfo}=St) -> {ok,Code1} = luerl_comp_peep:chunk(Code0, Cinfo), {ok,St#luacomp{code=Code1}}. do_ok_return(#luacomp{lfile=Lfile,opts=Opts,code=C,warnings=Ws}) -> Report = lists:member(report, Opts), ?IF(Report, list_warnings(Lfile, Ws), ok), {ok,C}. do_error_return(#luacomp{lfile=Lfile,opts=Opts,errors=Es,warnings=Ws}) -> Report = lists:member(report, Opts), Return = lists:member(return, Opts), ?IF(Report, begin list_errors(Lfile, Es), list_warnings(Lfile, Ws) end, ok), ?IF(Return, {error,Es,Ws}, error). debug_print(Opts, Format, Args) -> ?DEBUG_PRINT(Format, Args, Opts). list_warnings(F, Ws) -> foreach(fun ({Line,Mod,Warn}) -> Cs = Mod:format_error(Warn), io:format("~s:~w: Warning: ~s\n", [F,Line,Cs]); ({Mod,Warn}) -> Cs = Mod:format_error(Warn), io:format("~s: Warning: ~s\n", [F,Cs]) end, Ws). list_errors(F, Es) -> foreach(fun ({Line,Mod,Error}) -> Cs = Mod:format_error(Error), io:format("~s:~w: ~s\n", [F,Line,Cs]); ({Mod,Error}) -> Cs = Mod:format_error(Error), io:format("~s: ~s\n", [F,Cs]) end, Es). luerl-1.2.3/src/luerl_lib_package.erl0000664000175000017500000001574314677012037020160 0ustar debalancedebalance%% Copyright (c) 2013-2020 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_lib_package.erl %% Author : Robert Virding %% Purpose : The package library for Luerl. %% These functions sometimes behave strangely in the Lua 5.2 %% libraries, but we try to follow them. Most of these functions KNOW %% that a table is a ttdict! We know that the erlang array has default %% value 'nil'. -module(luerl_lib_package). -include_lib("kernel/include/file.hrl"). -include("luerl.hrl"). %% The basic entry point to set up the function table. -export([install/1,require/3,searchpath/3,preload_searcher/3,lua_searcher/3]). %% Export some functions which can be called from elsewhere. -export([search_path/5]). -import(luerl_lib, [lua_error/2,badarg_error/3]). %Shorten this install(St0) -> St1 = luerl_emul:set_global_key(<<"require">>, #erl_mfa{m=?MODULE,f=require}, St0), {S,St2} = luerl_heap:alloc_table(searchers_table(), St1), {L,St3} = luerl_heap:alloc_table(loaded_table(), St2), {P,St4} = luerl_heap:alloc_table(preload_table(), St3), {T,St5} = luerl_heap:alloc_table(table(S, L, P), St4), {T,St5}. %% table() -> [{FuncName,Function}]. %% meta_table() -> [{TableName,Function}]. %% searchers_table() %% preloaded_table() %% loaded_table() table(S, L, P) -> [{<<"config">>,config()}, {<<"loaded">>,L}, {<<"preload">>,P}, {<<"path">>,path()}, {<<"searchers">>,S}, {<<"searchpath">>,#erl_mfa{m=?MODULE,f=searchpath}} ]. searchers_table() -> [{1.0,#erl_mfa{m=?MODULE,f=preload_searcher}}, {2.0,#erl_mfa{m=?MODULE,f=lua_searcher}}]. preload_table() -> []. loaded_table() -> []. %% meta_table() -> %% [{<<"__index">>,#erl_func{code=fun meta_values/2}} %% ]. %% config() %% path() %% meta_values() %% Generate initial data for tables. config() -> <<"/\n",";\n","?\n","!\n","-\n">>. %The defaults path() -> case os:getenv("LUA_PATH") of false -> <<"./?.lua;./?/init.lua">>; %Default path Path -> list_to_binary(Path) end. %% meta_values([_,<<"bert">>], St) -> %% {[<<"/\n",";\n","?\n","!\n","-\n">>],St}; %% meta_values(_, St) -> {[nil],St}. %Default undefined key %% searchpath(Name, Path [, Sep [, Rep]]) -> [File] | [nil|Files]. searchpath(_, As, St) -> case luerl_lib:conv_list(search_args(As), [lua_string,lua_string,lua_string,lua_string]) of [N,P,S,R] -> %Name, path, sep, rep Ret = case search_path(N, P, S, R, []) of {ok,File} -> [File]; {error,Tried} -> [nil,Tried] end, {Ret,St}; _ -> badarg_error(searchpath, As, St) end. search_args([N,P]) -> [N,P,<<".">>,<<"/">>]; search_args([N,P,S]) -> [N,P,S,<<"/">>]; search_args(As) -> As. %% search_path(Name, Path, Sep, Rep, Tried) -> {ok,File} | {error,Tried}. %% Search for a file in a path. Callable from Erlang. search_path(N0, P, S, R, Tried) -> N1 = binary:replace(N0, S, R, [global]), Ts = binary:split(P, <<";">>, [global]), search_path_loop(N1, Ts, Tried). search_path_loop(Name, [T|Ts], Tried) -> File = binary:replace(T, <<"?">>, Name, [global]), %% Test if file can be opened for reading. case file:read_file_info(File) of {ok,#file_info{access=A}} when A =:= read; A =:= read_write -> {ok,File}; _ -> search_path_loop(Name, Ts, Tried ++ [$',File,$',$\s]) end; search_path_loop(_, [], Tried) -> %Couldn't find it {error,unicode:characters_to_binary(Tried)}. -spec require(_, [_], _) -> {_,_} | no_return(). %To keep dialyzer quiet %% require([File|_], State) ->{Value,State}. %% Main require interface. require(_, As, St) -> case luerl_lib:conv_list(As, [lua_string]) of [Mod] -> do_require(Mod, St); error -> badarg_error(require, As, St) end. do_require(Mod, St0) -> {Pt,St1} = luerl_emul:get_global_key(<<"package">>, St0), case luerl_emul:get_table_keys(Pt, [<<"loaded">>,Mod], St1) of {nil,St2} -> %Not loaded {Ss,St3} = luerl_emul:get_table_key(Pt, <<"searchers">>, St2), {[Ldr|Extra],St4} = search_loaders(Mod, Ss, St3), {Val,St5} = luerl_emul:functioncall(Ldr, [Mod|Extra], St4), require_ret(Mod, Val, Pt, St5); {Val,St2} -> {[Val],St2} %Already loaded end. require_ret(Mod, Val, Pt, St0) -> Res = case luerl_lib:first_value(Val) of nil -> true; %Assign true to loaded entry __tmp -> __tmp end, St1 = luerl_emul:set_table_keys(Pt, [<<"loaded">>,Mod], Res, St0), {[Res],St1}. search_loaders(Mod, Tref, St) -> #table{a=Arr} = luerl_heap:get_table(Tref, St), Ls = array:sparse_to_list(Arr), search_loaders_loop(Mod, Ls, <<>>, St). search_loaders_loop(Mod, [nil|Ls], Estr, St) -> %Could find some of these search_loaders_loop(Mod, Ls, Estr, St); search_loaders_loop(Mod, [L|Ls], Estr, St0) -> %Try the next loader %% Call the searcher function case luerl_emul:functioncall(L, [Mod], St0) of %% Searcher found a loader. {[F|_],_}=Ret when ?IS_FUNCTION(F) -> Ret; %% Searcher found no loader. {[S|_],St1} when is_binary(S) -> Estr1 = <>, %Append new info string search_loaders_loop(Mod, Ls, Estr1, St1); {_,St1} -> %Should be nil or [] search_loaders_loop(Mod, Ls, Estr, St1) end; search_loaders_loop(Mod, [], Estr, St) -> %No successful loader found lua_error({no_module,Mod,Estr}, St). %% preload_searcher() %% lua_searcher() %% Predefined search functions in package.searchers. These must be Lua %% callable functions as they are visible. preload_searcher(_, As, St0) -> case luerl_lib:conv_list(As, [lua_string]) of [Mod] -> {Pre,St1} = luerl_emul:get_table_keys([<<"package">>,<<"preload">>], St0), case luerl_emul:get_table_key(Pre, Mod, St1) of {nil,St2} -> {[],St2}; {Val,St2} -> {[Val],St2} %Return the chunk end; error -> badarg_error(preload_searcher, As, St0) end. lua_searcher(_, As, St0) -> case luerl_lib:conv_list(As, [lua_string]) of [Mod] -> {Path,St1} = luerl_emul:get_table_keys([<<"package">>,<<"path">>], St0), case search_path(Mod, Path, <<".">>, <<"/">>, []) of {ok,File} -> Ret = luerl_comp:file(binary_to_list(File)), lua_searcher_ret(Ret, File, St1); {error,Tried} -> {[Tried],St1} end; error -> badarg_error(lua_searcher, As, St0) end. lua_searcher_ret({ok,Chunk}, File, St0) -> %% Wrap chunk in function to be consistent. {Func,St1} = luerl_emul:load_chunk(Chunk, St0), {[Func,File],St1}; lua_searcher_ret({error,[{_,Mod,E}|_],_}, _, St) -> Msg = unicode:characters_to_binary(Mod:format_error(E)), {[Msg],St}. luerl-1.2.3/src/luerl_lib_debug.erl0000664000175000017500000000454214677012037017646 0ustar debalancedebalance%% Copyright (c) 2015-2020 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl_lib_debug.erl %% Author : Robert Virding %% Purpose : The debug library for Luerl. %% This is a very rudimentary debug module which contains those %% functions which need no detailed information about the internals. -module(luerl_lib_debug). -include("luerl.hrl"). %% The basic entry point to set up the function table. -export([install/1,getmetatable/3,getuservalue/3,setmetatable/3,setuservalue/3]). -import(luerl_lib, [lua_error/2,badarg_error/3]). %Shorten this install(St) -> luerl_heap:alloc_table(table(), St). %% table() -> [{FuncName,Function}]. table() -> [{<<"getmetatable">>,#erl_mfa{m=?MODULE,f=getmetatable}}, {<<"getuservalue">>,#erl_mfa{m=?MODULE,f=getuservalue}}, {<<"setmetatable">>,#erl_mfa{m=?MODULE,f=setmetatable}}, {<<"setuservalue">>,#erl_mfa{m=?MODULE,f=setuservalue}} ]. %% getmetatable([Value|_], State) -> {[Table],State}. %% setmetatable([Table,Table|nil|_], State) -> {[Table],State}. %% Can set the metatable of all types here. Return tables for all %% values, for tables and userdata it is the table of the object, %% else the metatable for the type. getmetatable(_, [O|_], St) -> {[luerl_heap:get_metatable(O, St)],St}; getmetatable(_, As, St) -> badarg_error(getmetatable, As, St). setmetatable(_, [T,M|_], St0) -> St1 = luerl_heap:set_metatable(T, M, St0), {[T],St1}; setmetatable(_, As, St) -> badarg_error(setmetatable, As, St). %% getuservalue([User|_], State) -> {[Value],State}. %% setuservalue([User,Value|_], State) -> {[User],State}. %% These are basically no-ops. getuservalue(_, [_|_], St) -> {[nil],St}; getuservalue(_, As, St) -> badarg_error(getuservalue, As, St). setuservalue(_, [U,_|_], St) -> {[U],St}; setuservalue(_, As, St) -> badarg_error(setuservalue, As, St). luerl-1.2.3/Makefile0000664000175000017500000001163314677012037014673 0ustar debalancedebalance# Copyright (c) 2016-2023 Robert Virding # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Makefile for Luerl # Building from .xrl, .yrl and .erl # Intermediaries from leex and yecc stay in ./src BINDIR = ./bin EBINDIR = ./ebin SRCDIR = ./src LIB = luerl # To run erl as bash FINISH = -run init stop -noshell # Scripts to be evaluated GET_VERSION = '{ok,[App]}=file:consult("src/$(LIB).app.src"), \ V=proplists:get_value(vsn,element(3,App)), \ io:format("~p~n",[V])' \ $(FINISH) ## The .erl, .xrl, .yrl and .beam files ESRCS := $(notdir $(wildcard $(SRCDIR)/*.erl)) XSRCS := $(notdir $(wildcard $(SRCDIR)/*.xrl)) YSRCS := $(notdir $(wildcard $(SRCDIR)/*.yrl)) EBINS = $(ESRCS:.erl=.beam) $(XSRCS:.xrl=.beam) $(YSRCS:.yrl=.beam) ERLCFLAGS = -W1 ERLC ?= erlc all: compile .PHONY: all compile clean echo examples debug docs compile: comp_opts.mk $(addprefix $(EBINDIR)/, $(EBINS)) $(EBINDIR)/%.beam: $(SRCDIR)/%.erl $(SRCDIR)/luerl.hrl comp_opts.mk @ mkdir -p $(EBINDIR) $(ERLC) $(ERLCFLAGS) -o $(EBINDIR) $(COMP_OPTS) $(ERLCFLAGS) $< %.erl: %.xrl $(ERLC) -o $(SRCDIR) $< %.erl: %.yrl $(ERLC) -o $(SRCDIR) $< comp_opts.mk: get_comp_opts.escript escript get_comp_opts.escript -include comp_opts.mk clean: @ rm -f $(EBINDIR)/*.beam @ rm -f *.beam @ rm -f erl_crash.dump @ rm comp_opts.mk $(MAKE) -C examples clean clean-all: clean rm -rf _build echo: echo $(OBJECTS) get-version: @echo @echo "Getting version info ..." @echo @echo -n app.src: '' @erl -eval $(GET_VERSION) examples: all $(MAKE) -C examples debug: ERLCFLAGS="+debug_info" make all ############### ### TESTING ### ############### # XXX for some reason, the first pass of eunit doesn't run the tests?! eunit: @rebar3 as test do compile,eunit,eunit common-test: @rebar3 as test do compile,ct ct: common-test tests: @rebar3 as test do compile,eunit,eunit,ct # this protects the intermediate .erl files from make's auto deletion #.SECONDARY: $(XRL_INTERM) $(YRL_INTERM) ##################### ### DOCUMENTATION ### ##################### # Targets for generating docs and man pages DOCDIR = doc DOCSRC = $(DOCDIR)/src MANDIR = $(DOCDIR)/man PDFDIR = $(DOCDIR)/pdf EPUBDIR = $(DOCDIR)/epub MANINSTDIR ?= $(PREFIX)/share/man MAN1_SRCS = $(notdir $(wildcard $(DOCSRC)/*1.md)) MAN1S = $(MAN1_SRCS:.1.md=.1) TXT1S = $(MAN1_SRCS:.1.md=.txt) PDF1S = $(MAN1_SRCS:.1.md=.pdf) MAN3_SRCS = $(notdir $(wildcard $(DOCSRC)/*3.md)) MAN3S = $(MAN3_SRCS:.3.md=.3) PDF3S = $(MAN3_SRCS:.3.md=.pdf) TXT3S = $(MAN3_SRCS:.3.md=.txt) MAN7_SRCS = $(notdir $(wildcard $(DOCSRC)/*7.md)) MAN7S = $(MAN7_SRCS:.7.md=.7) TXT7S = $(MAN7_SRCS:.7.md=.txt) PDF7S = $(MAN7_SRCS:.7.md=.pdf) # For pandoc for generating PDFs as it omly accepts a few options. # xelatex is a reasonable default or wkhtmltopdf. PANDOCPDF ?= xelatex # Just generate the docs that are tracked in git docs: docs-txt docs-man: \ $(addprefix $(MANDIR)/, $(MAN1S)) \ $(addprefix $(MANDIR)/, $(MAN3S)) \ $(addprefix $(MANDIR)/, $(MAN7S)) $(MANDIR)/%.1: $(DOCSRC)/%.1.md pandoc -f markdown -s -t man -o $@ $< $(MANDIR)/%.3: $(DOCSRC)/%.3.md pandoc -f markdown -s -t man -o $@ $< $(MANDIR)/%.7: $(DOCSRC)/%.7.md pandoc -f markdown -s -t man -o $@ $< clean-docs: rm -f $(DOCDIR)/*.txt $(MANDIR)/*.[0-9] $(PDFDIR)/*.pdf $(EPUBDIR)/*.epub docs-txt: docs-man \ $(addprefix $(DOCDIR)/, $(TXT1S)) \ $(addprefix $(DOCDIR)/, $(TXT3S)) \ $(addprefix $(DOCDIR)/, $(TXT7S)) @if [ -f $(DOCDIR)/luerl_guide.txt ]; then \ cp $(DOCDIR)/luerl_guide.txt $(DOCDIR)/user_guide.txt ; \ fi $(DOCDIR)/%.txt: export GROFF_NO_SGR=1 $(DOCDIR)/%.txt: $(MANDIR)/%.1 groff -t -e -mandoc -Tutf8 $< | col -bx > $@ $(DOCDIR)/%.txt: $(MANDIR)/%.3 groff -t -e -mandoc -Tutf8 $< | col -bx > $@ $(DOCDIR)/%.txt: $(MANDIR)/%.7 groff -t -e -mandoc -Tutf8 $< | col -bx > $@ $(PDFDIR): @$(INSTALL_DIR) $(PDFDIR) docs-pdf: $(PDFDIR) \ $(addprefix $(PDFDIR)/, $(PDF1S)) \ $(addprefix $(PDFDIR)/, $(PDF3S)) \ $(addprefix $(PDFDIR)/, $(PDF7S)) $(PDFDIR)/%.pdf: $(DOCSRC)/%.1.md pandoc -f markdown --pdf-engine=$(PANDOCPDF) -o $@ $< $(PDFDIR)/%.pdf: $(DOCSRC)/%.3.md pandoc -f markdown --pdf-engine=$(PANDOCPDF) -o $@ $< $(PDFDIR)/%.pdf: $(DOCSRC)/%.7.md pandoc -f markdown --pdf-engine=$(PANDOCPDF) -o $@ $< ################ ### RELEASES ### ################ hex-publish: clean-all compile rebar3 hex publish package tags: git tag $(shell erl -eval $(GET_VERSION)|tr -d '"') git tag v$(shell erl -eval $(GET_VERSION)|tr -d '"') git push --tags luerl-1.2.3/LICENSE0000664000175000017500000002613614677012037014244 0ustar debalancedebalance Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. luerl-1.2.3/rebar.config.script0000664000175000017500000000723614677012037017024 0ustar debalancedebalance%% -*- mode: erlang; indent-tabs-mode: nil -*- Conf0 = CONFIG, %The original config %% Do a deep set stepping down a list of keys replacing/adding last %% with value. Named funs would be nicer but not always available. SetConf = fun ([K], Val, Ps, _F) -> %% Replace the whole K field with Val. [Val|proplists:delete(K, Ps)]; ([K|Ks], Val, Ps, F) -> %% Step down and build coming up. case lists:keyfind(K, 1, Ps) of {K,Kps} -> lists:keyreplace(K, 1, Ps, {K,F(Ks, Val, Kps, F)}); false -> Ps ++ [{K,F(Ks, Val, [], F)}] end end, %% Get the release number. %% We have stolen the idea and most of the code from rebar3. OTPRelease = fun () -> case erlang:system_info(otp_release) of [$R,N1|Rest] when is_integer(N1) -> %% If OTP <= R16, take the digits. [N1|Rest]; Rel -> %% If OTP >= 17.x, erlang:system_info(otp_release) returns %% just the major version number. File = filename:join([code:root_dir(),"releases",Rel,"OTP_VERSION"]), case file:read_file(File) of {error, _} -> Rel; {ok, Vsn} -> Size = byte_size(Vsn), %% The shortest vsn string consists of at least %% two digits followed by "\n". Therefore, it's %% safe to assume Size >= 3. case binary:part(Vsn, {Size, -3}) of <<"**\n">> -> binary:bin_to_list(Vsn, {0, Size - 3}); _ -> binary:bin_to_list(Vsn, {0, Size - 1}) end end end end, Version = OTPRelease(), %% Collect the macro definitions we will add to the compiler options. %% Named funs would be nicer but not always available. AppendCopts = fun (Version, [{Ver,Opt}|Opts], F) -> Rest = F(Version, Opts, F), if Version >= Ver -> [{d,Opt,true}|Rest]; true -> Rest end; (_Version, [], _F) -> [] end, Copts0 = [{d,'ERLANG_VERSION',Version}], Copts = Copts0 ++ AppendCopts(Version, [{"17",'HAS_MAPS'}, {"18",'HAS_FULL_KEYS'}, {"19",'NEW_REC_CORE'}, {"19",'NEW_RAND'}, {"20",'NEW_BOOL_GUARD'}, {"20",'HAS_FLOOR'}, {"20",'HAS_CEIL'}, {"21",'NEW_STACKTRACE'}, {"23",'EEP48'}], AppendCopts), %% Ensure they are in erl_opts. Conf1 = case lists:keyfind(erl_opts, 1, Conf0) of {erl_opts,Opts} -> %Existing erl_opts NewOpts = {erl_opts,Opts ++ Copts}, lists:keyreplace(erl_opts, 1, Conf0, NewOpts); false -> %No erl_opts Conf0 ++ [{erl_opts,Copts}] end, %% TestConfig = [{cover_enabled, true}, {cover_opts, [verbose]}], %% Aliases = [{alias, [ %% {test, [eunit, {ct, "--cover"}, cover]} %% ]}], %% Conf1 ++ TestConfig ++ Aliases. Conf1. luerl-1.2.3/rebar.lock0000664000175000017500000000000414677012037015166 0ustar debalancedebalance[]. luerl-1.2.3/ebin/0000775000175000017500000000000014677012037014144 5ustar debalancedebalanceluerl-1.2.3/ebin/luerl.app0000664000175000017500000000254714677012037016001 0ustar debalancedebalance{application,luerl, [{description,"Luerl - an implementation of Lua on Erlang"}, {vsn,"1.2.3"}, {modules,['Elixir.Luerl.New','Elixir.Luerl',luerl,luerl_anno, luerl_app,luerl_comp,luerl_comp_cg,luerl_comp_env, luerl_comp_lint,luerl_comp_locf,luerl_comp_normalise, luerl_comp_peep,luerl_comp_vars,luerl_emul,luerl_heap, luerl_lib,luerl_lib_basic,luerl_lib_bit32, luerl_lib_debug,luerl_lib_io,luerl_lib_math, luerl_lib_os,luerl_lib_os_date,luerl_lib_package, luerl_lib_string,luerl_lib_string_format, luerl_lib_table,luerl_lib_utf8,luerl_new,luerl_old, luerl_parse,luerl_sandbox,luerl_scan,luerl_sup, luerl_util,ttdict,ttsets]}, {registered,[]}, {applications,[kernel,stdlib]}, {env,[]}, {mod,{luerl_app,[]}}, {licenses,["Apache-2.0"]}, {links,[{"Github","https://github.com/rvirding/luerl"}]}, {files,["README.md","LICENSE","VERSION","src","doc", "ebin/luerl.app","include","rebar.*","*akefile", "*.escript"]}, {exclude_files,["priv/images/*"]}]}. luerl-1.2.3/README.md0000664000175000017500000000477514677012037014523 0ustar debalancedebalance# Luerl *An implementation of Lua in Erlang* [![Build Status][gh-actions-badge]][gh-actions] [![Luerl Versions][luerl-badge]][luerl] [![Erlang Versions][erlang-badge]][versions] [![Tag][github-tag-badge]][github-tag] [![Project Logo][logo]][logo-large] **Alert**: The migration from Lua 5.2 to 5.3 is very much Work-In-Progress. Please test it but there are as yet no guratantees. ## About Luerl is an implementation of standard Lua 5.3 written in Erlang/OTP. Lua is a powerful, efficient, lightweight, embeddable scripting language common in games, IoT devices, AI bots, machine learning and scientific computing research. It supports procedural, object-oriented, functional, data-driven, reactive, organizational programming and data description. Being an extension language, Lua has no notion of a "main" program: it works as a library embedded in a host simple called the embedding program. The host program can invoke functions to execute a piece of Lua code, can write and read Lua variables, and can call Erlang functions by Lua code. Through the use of Erlang functions, Luerl can be augmented to cope with a wide range of different domains, creating a customized language sharing a syntactical framework. Luerl is implemented as a library, written in clean Erlang/OTP. For more information, read the [documentation](https://github.com/rvirding/luerl/wiki) and follow the [get started](https://github.com/rvirding/luerl/wiki/0.2-Getting-started) tutorial. You may also browse the [examples](https://github.com/rvirding/luerl/tree/develop/examples). ## Join the Community [Luerl on Slack](https://luerl.slack.com), join by requesting an invite [here](https://erlef.org/slack-invite/luerl) [Luerl Forum - Erlang Forums](https://erlangforums.com/luerl) Luerl embraces both [#Erlang](https://twitter.com/hashtag/erlang?src=hash) and [#LuaLang](https://twitter.com/hashtag/lualang?src=hash) communities and ecosystems. [//]: ---Named-Links--- [logo]: priv/images/logo.png [logo-large]: priv/images/logo-large.png [gh-actions-badge]: https://github.com/rvirding/luerl/workflows/Test/badge.svg [gh-actions]: https://github.com/rvirding/luerl/actions [luerl]: https://github.com/rvirding/luerl [luerl-badge]: https://img.shields.io/badge/luerl-1.1-blue.svg [erlang-badge]: https://img.shields.io/badge/erlang-24%20to%2026-blue.svg [versions]: https://github.com/rvirding/luerl/blob/master/.github/workflows/ci.yml [github-tag]: https://github.com/rvirding/luerl/tags [github-tag-badge]: https://img.shields.io/github/tag/rvirding/luerl.svg luerl-1.2.3/doc/0000775000175000017500000000000014677012037013774 5ustar debalancedebalanceluerl-1.2.3/doc/pdf/0000775000175000017500000000000014677012037014545 5ustar debalancedebalanceluerl-1.2.3/doc/pdf/luerl.pdf0000664000175000017500000014067714677012037016402 0ustar debalancedebalance%PDF-1.4 1 0 obj << /Title (þÿluerl\(3\)) /Creator (þÿwkhtmltopdf 0.12.6) /Producer (þÿQt 4.8.7) /CreationDate (D:20230820165315+02'00') >> endobj 3 0 obj << /Type /ExtGState /SA true /SM 0.02 /ca 1.0 /CA 1.0 /AIS false /SMask /None>> endobj 4 0 obj [/Pattern /DeviceRGB] endobj 11 0 obj [0 /XYZ 141 723.500000 0] endobj 12 0 obj [0 /XYZ 141 633.500000 0] endobj 13 0 obj [0 /XYZ 141 262.250000 0] endobj 14 0 obj [0 /XYZ 141 474.500000 0] endobj 15 0 obj [0 /XYZ 141 220.250000 0] endobj 16 0 obj [0 /XYZ 141 364.250000 0] endobj 17 0 obj [0 /XYZ 141 177.500000 0] endobj 18 0 obj [0 /XYZ 141 134.750000 0] endobj 19 0 obj << /Type /Annot /Subtype /Link /Rect [365.250000 503 395.250000 512 ] /Border [0 0 0] /A << /Type /Action /S /URI /URI (https://lua.org) >> >> endobj 20 0 obj << /Type /Annot /Subtype /Link /Rect [167.250000 493.250000 181.500000 502.250000 ] /Border [0 0 0] /A << /Type /Action /S /URI /URI (https://www.lua.org/manual/5.3/manual.html#3.3.2) >> >> endobj 21 0 obj << /Type /Annot /Subtype /Link /Rect [252 493.250000 309.750000 502.250000 ] /Border [0 0 0] /A << /Type /Action /S /URI /URI (https://www.lua.org/manual/5.3/manual.html) >> >> endobj 5 0 obj << /Type /Page /Parent 2 0 R /Contents 22 0 R /Resources 24 0 R /Annots 25 0 R /MediaBox [0 0 595 842] >> endobj 24 0 obj << /ColorSpace << /PCSp 4 0 R /CSp /DeviceRGB /CSpg /DeviceGray >> /ExtGState << /GSa 3 0 R >> /Pattern << >> /Font << /F6 6 0 R /F7 7 0 R /F8 8 0 R /F9 9 0 R /F10 10 0 R >> /XObject << >> >> endobj 25 0 obj [ 19 0 R 20 0 R 21 0 R ] endobj 22 0 obj << /Length 23 0 R /Filter /FlateDecode >> stream xœí]Koì¶ÞϯÐ:ÀÕI=( (0Ûº(`Ø@EÅMÓ °/z›Eÿ~%4#‰ú(òˆ”8c%Hl‹3yxÞ/~ýËë?£ÿ}=½þ'úÖþ<½’¸È’ó?Qýï—þƒ2‰ŠŒGß>?¢‡—ÃKõÿîgýáC–‰¸þ(cÕŸïý?¥”±àŒ—¬zžŒÿ¬?üÛá矢ïÕ„Ýš’¸,9Ër™søûß¾¾ž÷R}3‰e’pY¦Õ*›õþ®V^ÿÈ«·2Æ’è¿ÿ:üZ¯ßü«Iôzú[õÛÿ"ýµúï÷èïÿ¨þâ ¹Œ%OeÉe”',NX! YMJ‹"•¼ì?<Eœˆ$MDõ¼?zÞŸçrnà\],(¸MíÈrÏÈre‡,aež2…¿÷Ù¡ÉçÁ+_úðvøúœG<Þ~ØY„œ¼}*|о,zû%úS}ŽÞ~?1g²‘1õ‡Î#¼aiœf‚ñ¬7"Î#,>ôFR8‚ß“5#2γœGòólâú¤hž<½Ugºd‹ˆ¥S噌Ïbºz˜Ãgq*ÎB| á<æÉZŽœ!\ŒÁ'âžÆ0_YÑ•MRŒ'Áï“põx¤O?xh-[½æ:r‚ÛÁ}„UVò4~€Ïà¹IU¼d \}·F.ÎP¹~‡µkäít×gÃ+£mh&# KC¦!Qñ› ‰Ž†X6ÞD>~0Fi&ÇJÍùÙ•OC"bñ2¾pΆ„Êê©Ê+Çä1Åâ)S˜ÿœí¤°øG8 ~óSKÄ*kÀoÆâ C¯ Ãë ¾–ô÷ßܲ@‰¶Á·ìB¬̳4—…^î`î›…°ál˜1>Ø1‡ˆ·§_œÌWDÓ„|ë¸ýÄ$GÄÓÔéñGE F¸ÅФj¬0eÇX©‚‡=v\T«qE vh¶Ž¥?VÒðlxÕÖô;¥­Á%i^Œ…b¼¶±¾ÈžìOCƒwæÏg*ºóüôHûœPx+„xwËÐM±Nœ¶2=gð£ðô9‡wÌÅ[@…f%ÊaSà‡1ÓÂúÁ°À0Ǭ‹`éR([±‹4ÛHI`ô¶áŒÙk JP£õ¢[+›9®)õeŽÒ§Fà{ZÃv ýžáÚJ¸6ü¬Iep$hÇKåà()´ûzðE¸*Žsfà›1R4QìüÁâ×cÔ¨Äc„øŠb@Á I,[ á1•jàˆ§WHr¢ß ¡M›CWN¯Ñ‰žxKnBhtt ³4 ÁIð[»µ#ÚS Y£c%DC$îc56…Gs¶¾W7,Esuâž·à[$½›Âå°R‹Ì 7³­Ã¯ìР…²s  .Z¤yŸ°ïÚ…5DkáÌ6W:4ïSÈÚB•ñ‹c”ä, ÝQ,'êª9iª¢â&S–æTPb7³>½u‘Ak!(–ëZ^' ¯” šû´)oÁ©Hv'LÏBÕìoA°M—âÞ7W6Ãe½ ûÄ,&¡8¬)ÀÁlXAE-P×z‰¹°¼M•wEl lfox\Œsd5Q ¹@°n°1¯bá\8#dÍ"cóø2øQ’$í¡æ*^¤E4È‚åQjã÷rùÆ2Òo´0ÓÙ‚ «¼•’)ëÂ]è6ë•+µÖI7æ­2b|²Œ©HÌu®Ê2P!¤lãÈêN¢½n& 4MÜ~hcÝ9P6Ñh’²ãüy‚ NmK,§øµVÉ 4Ù›å²ÆmAì”¶­È¨Æyà0 »+ë º"’³¬.à|€ìâ”òë9ØÌÓ´(Àæ$ëÛÜm…U!~‚gíÖ¿éÄ+Eˆ x–¾ç¥ÉIÆš*…¬dÚi¡£³4ÓÙVš*E,òGȼתô„<Ô  P­¢tQØn\!•„¯(–—²yŹEÀTo¶¹w’Gv‘U©ð8R`f«Ü*O9Á$ΪkÁA-6ì‚ûº9ÐÍY¸oFíÔT™û||+ÕCtX«Ñ·(œ‡ý,ò® 8?+‹ŽÝŽÃVNgSQɼTÉÒp­"™=¶àuœ”‰yd°(þ´ð/QÌ'¶Øx%$™E)$rašß–z•¬«ð¾]† ‹ýx†lTB·¡X )®\±Wsݓɱ4+ûrLƒ˜ǤP 9´Pæ³ø˜ ¾zŸéµéèÇ!KÞ¯žN½ÈþéP,dÌ%\d>kd…ÅôVø~ tÖ¨‹¼«Y´I˜/e²èë4/b¼ìÉq»BûË >R¯1É•°Lô„ÉGêEö!»™~u‹%³H£ŠQêž¶j0"ؘö¡ÛŒT ´Ïëþ¯Ëhÿ¶Ò»üÖ—Û`¡.n‚1Ö8`Œ"/ÂgŒõ"ûr9—SñÉlÓF‡—SÛ'wŽñ+I4ÒbAy¹gê:òGžZmBÅÔ¶y†0uj¶3¶ñ URÌ;§"5¦öƒ¿s´Oש¼9Œ¼$]ÏÎŒ]°Çö4Ծ唎™Š‹ 6ñdA—Ü2^ô¡DâÈEÔw¾¹ûKp¨¬PœÈK.åêÎ Þ!›`•ÓÖVJîBfFâ"¶ö”R=Wª Õ×½p¥%m* 74yÊ$uâ‚ßӡ湼†I9%^Ò”n€Ù¦åh[ŸóJ6€ÅýsR¿¾§ísÄ<÷\[W³1”ð¦Êl@sw7JÈ¿Á9QïƒÓMLáºã›ÒÌ·»ün³. KOxõËÚõ_»•(.þ\ý2Œ•rŠÂ¹./1†kóü¢[œ÷Ç„˜9ïb*§¨âÄÚOŸ¢Z$l–à¸Ò'@ѳ‚Ø'Ö’ÁF}ú¿=êÆyïº$£D‚PO².¢29É{¿—,ÄwÖu¢&:§§[]´×vÜÙvåû„¹!m³a³ì”ÝËNÅβ#8·kÔÀÂâ2·½ä1„jÛ(ó×J*ó ‹Fâíy®[9˜•I¬LXv·&#o„¯Iaâ.µ¶—Zn]åJ{=¿ª9Îv[©µ$î¿ Ê wLU; *DÝÜ@ëÖœ¶¾.7‹Y{«ã¸ÄhÌEž!*»”tÛK"(.µµ!^*ì$°¶ ÅOùËÜôê{9¼D?õ´‡,qýŽ&âñÞÿSJ ÎxɪçÉøÏúÿ~þ)ú~Èe,y*K.£k˜·9$Sñ@bc3˜©Ä4¬uöNE³ˆðà“¸iÚÎVfÓ‘…°Ò¸äcWîJG©>[uõ˜UnFüg1Õ[FÈËqtŸ±ù‹5‚¢7ºk£¤äOWŽ{Jòwù¸µ‘º$œÕ‘ÉØs2Žbú¹7ʼԲh'UÅNRIûr{í[0Mv=p7jtœOh&”8 Ÿ¤·ÈÿXíâæðÆ¡uiô‚Ò¸÷áý9/àû°Õg›ãÝSÜÖa§¦ Ôúݦßmúݦßmúݦ÷hÓ—"í‹íXEóž»ÿo¡Õ³D™57—I-í-.æ^Ëÿ°VïÍÝ`Ù[oÚN) %fs;e¶ TA¿=r:Ù#§ŸØÊ Ú ¢Ø'ûýðGôÍPæ–UdVñÙv±{ÜË„#îq¯e÷Ÿ}^¥ùózùñ®|[.{Û‚EL<|3‹%é¥ÌØY{g7?vóc7?¶1?Š|^¸í.z(çÝšJžÕ#ßú‹—Ëz=çÇùùö——íßnñíßnñlñéU”K•=ö ŪR5dn¼«..Ð"Q‘¢œ™7}VŲŸäj'.n ™‡f¹È k G(Î#ÁJ* †0î„&`‚–㵡¬pz³n°ÖÇS0p6ø½­Ó µu ¨É„w›á®¬Ef ¨GFôrø?É Ì endstream endobj 23 0 obj 3600 endobj 27 0 obj [1 /XYZ 141 123.500000 0] endobj 28 0 obj [1 /XYZ 141 576.500000 0] endobj 29 0 obj [1 /XYZ 141 533.750000 0] endobj 30 0 obj [1 /XYZ 141 491 0] endobj 31 0 obj [1 /XYZ 141 449 0] endobj 32 0 obj [1 /XYZ 141 322.250000 0] endobj 33 0 obj [1 /XYZ 141 427.250000 0] endobj 34 0 obj [1 /XYZ 141 270.500000 0] endobj 35 0 obj [1 /XYZ 141 374.750000 0] endobj 36 0 obj [1 /XYZ 141 752 0] endobj 37 0 obj [1 /XYZ 141 218 0] endobj 38 0 obj [1 /XYZ 141 700.250000 0] endobj 39 0 obj [1 /XYZ 141 166.250000 0] endobj 40 0 obj [1 /XYZ 141 647.750000 0] endobj 26 0 obj << /Type /Page /Parent 2 0 R /Contents 41 0 R /Resources 43 0 R /Annots 44 0 R /MediaBox [0 0 595 842] >> endobj 43 0 obj << /ColorSpace << /PCSp 4 0 R /CSp /DeviceRGB /CSpg /DeviceGray >> /ExtGState << /GSa 3 0 R >> /Pattern << >> /Font << /F6 6 0 R /F7 7 0 R /F10 10 0 R >> /XObject << >> >> endobj 44 0 obj [ ] endobj 41 0 obj << /Length 42 0 R /Filter /FlateDecode >> stream xœí]KÛ6¾ëWè\ ^‘õŠ»ÞÝ=XdŠФi4A·9ôïW¶$ËõQ☶({²H²6%>†Ãy}òîÇ÷¿Ç~‹ï¶ïÿ‰?4ÿoßGÉ&×Iý'Þý¼;þ¢Lâ\ËøÃ—è-~‹^¢—êß·¨~ðýöçê·ÿbÿTýýÿú[õåÇæ¡Ý_"­ÕfWÕÇ¿?E±QRÈRTß'û‡ÿŠ~ù.þºkmS$‰,Ê´êȾåÞçwG¯VÝœèÚ[Ô?Ù”¥:+2 ÿöáktW“ͽBˆ$ΪOû_þý#ú´#k=]wE"Ê,É‹þ~ÜÝ9Ï*½‘}xîž³X¤ñë§XÔÜTÿ÷ú%*²êƒ2~ý¿c‚â×Ï‘Ú ·ížªKä¾$ßä…ºW¢ö%ÙF&j_Ô•¤°¶#êwÒM¦³A;ø¤î[÷èvð…°÷µ'|çöøR¶DíH9†j*Išg»ÎÖ]*+&-NoØ —xöñ G¦MOŽ$[Sý*õôˆs—ªžtQW"DÛrWRÀbâà•ù]>·m^šÓÌK°o&¿Ã™õ0ô&Uƒ.©Äëß¹³ˆcƒž£×B\Û0aÒØZµçížeƒTЕk‚Ô#%j˜ˆl©%-Õà lFæÍFX(C]jÒ¨Ç:û„¾˜Ê5,J‚ç†Ðá†T´{ÐB†ßχ¨»b6cÙ)àek>VØ1H€¨{M¿±cZöj?Óq6K#u¬äÖ¦aIK ØŽ„%–ÜÆS„0™ˆŸeÒgèKG˜]¼\JR9î4ö’(0†¥oÔ‡2RgÑò0éF‡*à”Jû®œXÜc‚Š A}­f©m)‘xQ…ž)^ólÌ‘9ò²ëÀ³{ì"s@¥"škt­‹5ìl¿]×Z4ûÚìk³¯Í¾¶G_[KÁ¾öØ×^¹¯ÝÍ%ûÚìk³¯½÷µûÚ'ùÚsÄËUøÚú¯išôf§8áœÈf¯z |–æÉ\5Hì#PV©í[ݦæê \€ßÁ® ô«ØK TÔ\\¶©·ê Õ ÝBIðºíßa£¦EE.v44LÝ£Xª–w†iÚDš6E™d'³¤¬'BªŠÅÆp0a¼ÎºTu_ºê´jš Ùvÿ4{ëÌ. ƒÂÇ‹2|ä"“íMA«s|䀡°iý”CqQ"9Þ£?ˆLÆå&:u ž£‚{`ÄàqŠ9‡Â=¾J9 O ï€ ÷ ‰ ee–²¬4Ï/ƒía“rì >ø†Å7‹oß,¾'|þ¬<\/QsÊØ^ˆ aB|Àr7Gù¸GÉâ×O÷œtHÏdŠ)él|úÌšÎ9±ð˜×…n$Mž™¹ gk_Š–…çqLÙ¸j@Ù˜a|œ9`Î –Š†Ð¥êàãòa]YÉ ‰%,MI77´KÐûgöVG~Ⱥ=þ¦DÌ-ÚÄá~@((^ðE+¢æú€-s``È áXÇ©³W¾UœCö%È! Ï!Šëºo+hÓ£ËJZeÀcMN6i䘎”ÍósÁÁG‘Y+9óQd^·+PvÇLÆ…ÂÞ‚ÝI7Þ‚}Úì#=q©$cÊf8‚¿IZdó#Ç”ƒKM ä÷8o¿‰#óÃê‹Xž-°ZÁº·‹¤ÝËr•*W…Ê{”œ ؇Ê"Õ}–x„Ó9qf´%ò´?‰çL •d5üðdâlZ,G(9³A¯|9X0$¦¡x”v†šÓÁ Å> ÚöR°¥ƒKJ–X÷hŠÑ€ùµòi> Hñžø«…sní( Æwìk’ñÆwVŠïy{­ã;çŽé0¾Ãøã;—Äw:éÆqÈÓð#=ÁøÎ¹ñ‡mÁ¦˜fðfqE¿Z©Y›„Åá:*š§7J®¼éXâöÀ›no¼éˆÀàÍðæ4¦¡ƒ7ÆÄåþü¼Ž*×wB J’¹óÎØÏuc?¥\Å%‰Æ~ð“貚ár Âãû„=Í.Ñ©is…rȹ #˞Ȳ\¸‚K¦¢ˆ7­TEÞW ñp mÄË¡@K«þÕÊÑÚòËùŽ,FýãiÚ£ñzA-ûÌrK O!ú“x› OÙ'ƒ>vÐg°`8cgŽúåŒFm‚Amd"ùvŒÚ }›P‡ì†qÆé̆qÆY[‚ŽLÒÃ]‰ Ö0XC2ò¬a°ær`Í‘Èâ(ã™ÀšcµÀ` çã0³!©³¾]ç7Ë&ìèº.u_x­"©móLõWÃm $B÷Æ~“‰HUŸŒLÀjÙéLs}i1Bô¨r}i12sç–+Xº»X,±U¹‚¿×å&˜ÛŽ« 7QŒ©«ÅÆ`šÅâÌÁ'H¡Ú‹©Õ³;Í-ªyþpb~ÈÑË §¤à8AÐ[Ü^¿Áëˆ~žÕŸãx(¥ËΣ½áJ£Ê«ÏíòØÉöün¶È6ÂõŒ0®žrE ¹DÑSË „á[a"Ÿ¶Ž–·ÂŒ–}/lQ´Õb–ŽLtŸ©ÆõÉ3¥TݦýÄöšg{ÍË-Éç9(”-º9³BÁ¦ Y€«_”pØØa1íæ¶c#¬ú‰ß*m’ì5P6/ñKô?¯jP endstream endobj 42 0 obj 2768 endobj 46 0 obj [2 /XYZ 141 752 0] endobj 47 0 obj [2 /XYZ 141 710 0] endobj 48 0 obj [2 /XYZ 141 667.250000 0] endobj 49 0 obj [2 /XYZ 141 624.500000 0] endobj 50 0 obj << /__WKANCHOR_q 29 0 R /__WKANCHOR_s 30 0 R /__WKANCHOR_10 32 0 R /__WKANCHOR_u 31 0 R /__WKANCHOR_12 34 0 R /__WKANCHOR_w 33 0 R /__WKANCHOR_14 37 0 R /__WKANCHOR_y 35 0 R /__WKANCHOR_16 39 0 R /__WKANCHOR_18 27 0 R /__WKANCHOR_1a 46 0 R /__WKANCHOR_1c 47 0 R /__WKANCHOR_1e 48 0 R /__WKANCHOR_a 13 0 R /__WKANCHOR_1g 49 0 R /__WKANCHOR_c 15 0 R /__WKANCHOR_e 17 0 R /__WKANCHOR_g 18 0 R /__WKANCHOR_2 11 0 R /__WKANCHOR_i 36 0 R /__WKANCHOR_4 12 0 R /__WKANCHOR_k 38 0 R /__WKANCHOR_6 14 0 R /__WKANCHOR_m 40 0 R /__WKANCHOR_8 16 0 R /__WKANCHOR_o 28 0 R >> endobj 52 0 obj <> endobj 54 0 obj <> endobj 56 0 obj < {ok, Result} | {error, Reason, StackTrace}.) /Parent 55 0 R /Dest /__WKANCHOR_a /Count 0 /Next 57 0 R >> endobj 57 0 obj < {ok, Result} | {error, Reason, StackTrace}.) /Parent 55 0 R /Dest /__WKANCHOR_c /Count 0 /Next 58 0 R /Prev 56 0 R >> endobj 58 0 obj < {Result, NewState}.) /Parent 55 0 R /Dest /__WKANCHOR_e /Count 0 /Next 59 0 R /Prev 57 0 R >> endobj 59 0 obj < {Result, NewState}.) /Parent 55 0 R /Dest /__WKANCHOR_g /Count 0 /Next 60 0 R /Prev 58 0 R >> endobj 60 0 obj < {ok,Function,NewState} | {error, Reason}.) /Parent 55 0 R /Dest /__WKANCHOR_i /Count 0 /Next 61 0 R /Prev 59 0 R >> endobj 61 0 obj < {ok,Function,NewState} | {error, Reason}.) /Parent 55 0 R /Dest /__WKANCHOR_k /Count 0 /Next 62 0 R /Prev 60 0 R >> endobj 62 0 obj < {ok,Function,FullName,State} | {error, Reason}.) /Parent 55 0 R /Dest /__WKANCHOR_m /Count 0 /Next 63 0 R /Prev 61 0 R >> endobj 63 0 obj < State.) /Parent 55 0 R /Dest /__WKANCHOR_o /Count 0 /Next 64 0 R /Prev 62 0 R >> endobj 64 0 obj < State.) /Parent 55 0 R /Dest /__WKANCHOR_q /Count 0 /Next 65 0 R /Prev 63 0 R >> endobj 65 0 obj < State.) /Parent 55 0 R /Dest /__WKANCHOR_s /Count 0 /Next 66 0 R /Prev 64 0 R >> endobj 66 0 obj < {Result,State}) /Parent 55 0 R /Dest /__WKANCHOR_u /Count 0 /Next 67 0 R /Prev 65 0 R >> endobj 67 0 obj < {Result,State}) /Parent 55 0 R /Dest /__WKANCHOR_w /Count 0 /Next 68 0 R /Prev 66 0 R >> endobj 68 0 obj < {Result,NewState}) /Parent 55 0 R /Dest /__WKANCHOR_y /Count 0 /Next 69 0 R /Prev 67 0 R >> endobj 69 0 obj < {Result,NewState}) /Parent 55 0 R /Dest /__WKANCHOR_10 /Count 0 /Next 70 0 R /Prev 68 0 R >> endobj 70 0 obj < {Result,NewState}.) /Parent 55 0 R /Dest /__WKANCHOR_12 /Count 0 /Next 71 0 R /Prev 69 0 R >> endobj 71 0 obj < {Result,NewState}) /Parent 55 0 R /Dest /__WKANCHOR_14 /Count 0 /Next 72 0 R /Prev 70 0 R >> endobj 72 0 obj < GCedState.) /Parent 55 0 R /Dest /__WKANCHOR_16 /Count 0 /Next 73 0 R /Prev 71 0 R >> endobj 73 0 obj < State.) /Parent 55 0 R /Dest /__WKANCHOR_18 /Count 0 /Next 74 0 R /Prev 72 0 R >> endobj 74 0 obj < State.) /Parent 55 0 R /Dest /__WKANCHOR_1a /Count 0 /Next 75 0 R /Prev 73 0 R >> endobj 75 0 obj < State.) /Parent 55 0 R /Dest /__WKANCHOR_1c /Count 0 /Next 76 0 R /Prev 74 0 R >> endobj 76 0 obj < {Result,State}.) /Parent 55 0 R /Dest /__WKANCHOR_1e /Count 0 /Next 77 0 R /Prev 75 0 R >> endobj 77 0 obj < {Result,State}.) /Parent 55 0 R /Dest /__WKANCHOR_1g /Count 0 /Prev 76 0 R >> endobj 55 0 obj <> endobj 53 0 obj <> endobj 51 0 obj <> endobj 78 0 obj << /Type /Catalog /Pages 2 0 R /Outlines 51 0 R /PageMode /UseOutlines /Dests 50 0 R >> endobj 45 0 obj << /Type /Page /Parent 2 0 R /Contents 79 0 R /Resources 81 0 R /Annots 82 0 R /MediaBox [0 0 595 842] >> endobj 81 0 obj << /ColorSpace << /PCSp 4 0 R /CSp /DeviceRGB /CSpg /DeviceGray >> /ExtGState << /GSa 3 0 R >> /Pattern << >> /Font << /F6 6 0 R /F7 7 0 R /F10 10 0 R >> /XObject << >> >> endobj 82 0 obj [ ] endobj 79 0 obj << /Length 80 0 R /Filter /FlateDecode >> stream xœí\KoÜ6¾ëWð\À29|ˆŠöÚ[ ‡†è!è¡p^ê ›ò÷+­(ïJÚKqåJ¶éÀÙÇP£áÌÇá|C%—¿ÝÿÍ>ÿ`—«ûÙƒ{]Ýg¢¹FçJ6…Xp…´ÉF[0”¯zCe}ý‡mÔpÆ7;‰à­ºmâºg¬h¬·¹Vf§Ï »@4cRnÆÙÊi»u’MÄöþ³Î$§ÌgÒ¤€ 0v Þ'1ž¡¼KKÔF°lP°è©SâÛM•šçË™…7gš¢5öz‰à*åÖf9 Á{*·CJÑVr ½ê+3Æ–‚êU_=tVÒ‚ø<q¼~ŒQ¿†9zàáˆX{܆ç…w| œ:´­µz°K¸ýþ˜SÕi—mßXÏËþИ¢ªÇ3&­ ”í;‡´ŸI<Öž@CîgÞȼſä2ÿ³ÿr°Å%6Ø@b/Œ HiHl ±iØÀÌK]p&èØZ§Bu»pµbN¢ŸF-’ˆ+(¹†ÚÖP²‚ÚVKp%Êš’tÇ“Q鬟†‹{Ùp’Zvát 4Î¥BÖçCc ËŒS y¡\M‰nê¡UË/ëD¾Ï®kÄèj 3DqWJ…Æ=ñüž_í]ËçùΑAÎ  ÷¯žÍ/‡%ÎO‰Ò¹º½Ä¢dí 6îxáUŠ! =Šƒ<á/¡#—ß P¼lSÉF=µ,I­€Ô ˜{©{ZEg±§V@|+Àv<ùF[ݽ£ÍcàÄ1q+mÙ )ËóAß$H§ùþí?æÏÄò•Ò§¹@bùé?ÑþDûÊ—MûíS6H´ÿ¬B*ÑþDûç^ê§hÿÓbO´ÿLÚoàúêi¿ígDû½´ÿ<м¾gHu¼ò Ÿ Ð*4î‹ë(Lõ¾©‡·ÐÖâɱ䪤â¤O†e.„c:a p ŸKpÿ¼…é´ÿ˜É=»v,«f¾cZ™Ãà‡GgDg6&¹ÆÃ “Sxn3)<&p uÌr[ |žMѾÛ>Fœ„çÍ 1 ^ž9³Ž˜NÇå°gㆴ@jhõ"ÊnÈÞšz„LwµŽ"bB# qxÍ ”((ÁÄÓGx.¡?Âû1½ L‡ÇY ýÆa|<Ú ”,…Þ¿¸\¸h*£ÛÔáÎŽ´éYñ~zï†?koí˜Ö1e.Ɇîë[?<€˜öÅsX;¢Á&…J×úøìÙˆš&jêƒÊW!“ÔÍ…‘çl’ZÂnH'}h;<Ñ@J‚Q‰qõˆÌ^åÿïÇ pñ¶âÂþ‡Gv—ýÛ†:A endstream endobj 80 0 obj 1275 endobj 83 0 obj << /Type /FontDescriptor /FontName /QFDAAA+Menlo-Bold /Flags 4 /FontBBox [-445.800781 -517.578125 731.445312 928.222656 ] /ItalicAngle 0 /Ascent 928.222656 /Descent -235.839843 /CapHeight 729.980468 /StemV 43.9453125 /FontFile2 84 0 R >> endobj 84 0 obj << /Length1 1564 /Length 87 0 R /Filter /FlateDecode >> stream xœ…SMle~¿™ÙšâÖB£Hóm [$ívw m’†EKhÛ¦&^ØÙÝÙ-;?™™í1¦Ñ Ï$’@41FŒ'o$œ´"zâ`£¨hbÄPvy¾ÙÙRÒ&Îä›}Þç}ßçýù²Äˆh­L”ŸÍ^è¿ùÌ8…j}¹òYëÛOÿĹaèZ¹tR'b_À3@tM4°ïÃ>`˜þR·C?I;`wÕí’FÔ€Ý+ª˜Ú’CQ‚ýlni¦ÞÏÖoÁ>A$ÿL²²&]£QäHäC¨ö·å;T‘zµKÉQE’”ßi u›þz•C8t¶òZ™8ñÖãho³—]RMökؽ‰{DJ!rGTÑÈh^TŒÈ'˜V%z>žˆLĆBëž¼oý·æEµûáßnôeÂVšo+k­œØKdO⨲öhôúê*š"¿õ‹2y@aÄ&âQ5:¨ %ãÒøX"Û··/žJ¨ÑxoßÞñìø˜lÜd·ætÃoÞ½|…}|…¥Þzsnj"ÿFáêôÌÙü¥‘ÁÖÍö?|<{ú@’ýð=óØÒêw/¼˜n~•?|èÝ•ý÷Þû,¦Š®Ä¹ûÍê¹Ý'þ·õ}£;†Mwä¨fsÇT֥ͬÜ&‡p<Ø{po… J¦$öªlyvÓ×üâF Ã.†X"…Þ ±Œ[X ±B;é£G0Èç!Ž‚ÿ2Ä*º¸ÖÆøÄè§3zŽþ€SbÈì¡C£ ñNö:Ûâ]tL*…¸‹.H—OÙβ[«>¿Ê³éô+ü¤ãÔu>i•R|³O8Çxq™Ïj æ¼mUyN3ž AÄ‘«ùžïêš9Ü–9Y¯óiãñiÝÓݽœšÒ­º³ëåpŽóÌx*]Îè™ãÊfFÒÙ‘Lú©¿ã ˜‘§¹5k|ÖÕʺ©¹ç¹]Ù4™ZUó®î²MÓ¶ø†M9ª‘ öÉ%42é4×r†–©Σ)|-`l 6§""=°â/Ö  È'§<=`fài@¹ð• ÎÚZ•Ó Ìq¬@¹£ç@£ˆú5èpxlÄk°¬g4_Eì|?‡øÔÿViO¢uS†Gèºtœ åí†ÁN¢b †ƒnĆjT×ÞG{ãÛl1…i|¼£Q¼‹Á› 2ÅD:°:UøJáT{ûÌâ–îRA¦‰˜Î^Î>+èÓ v&ô`\#Ð÷Àÿ¢;y‚[wÕîÜÄOçÎ=ù endstream endobj 87 0 obj 956 endobj 85 0 obj << /Type /Font /Subtype /CIDFontType2 /BaseFont /Menlo-Bold /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> /FontDescriptor 83 0 R /CIDToGIDMap /Identity /DW 597 >> endobj 86 0 obj << /Length 378 >> stream /CIDInit /ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def /CMapName /Adobe-Identity-UCS def /CMapType 2 def 1 begincodespacerange <0000> endcodespacerange 2 beginbfrange <0000> <0000> <0000> <0001> <0002> [<005F> <0047> ] endbfrange endcmap CMapName currentdict /CMap defineresource pop end end endstream endobj 8 0 obj << /Type /Font /Subtype /Type0 /BaseFont /Menlo-Bold /Encoding /Identity-H /DescendantFonts [85 0 R] /ToUnicode 86 0 R>> endobj 88 0 obj << /Type /FontDescriptor /FontName /QKDAAA+TimesNewRomanPS-BoldMT /Flags 4 /FontBBox [-558.105468 -441.406250 2000 891.113281 ] /ItalicAngle 0 /Ascent 891.113281 /Descent -216.308593 /CapHeight 662.109375 /StemV 95.2148437 /FontFile2 89 0 R >> endobj 89 0 obj << /Length1 14372 /Length 92 0 R /Filter /FlateDecode >> stream xœízy|[Õ•ð»O›-ËÖ¾ËÒÓîM²,Y’my•÷-vÛÁYˆe[¶åØ–‘å$NXC i PBH ´CØ)L¡¥L ÒB ¦í´LYÚýè´ðõ7t¦´Ð¡4Ñóœwß“í,­é¯|ÿ~’ν÷ÜsÎ=û½†@Aä×<‚èÛRî×lÞvfn…ÏèÔìòäïï»ê ÀÿMfÓt<619Ýñ%‚°äÀ\h& ~E_ãF;¦çÒû~?]ðŒ'`üÎlr<öšòMØOuÀ8=Û·@Ô£0þ&Œ©ùØ\<áýl1€¿ mÁãÍß$DŽà” @ÈÉþòN“¤ H2‡'Hÿ?ˆ’ß¿@ìk*¹ð!{›)þ[9/ØM·¡€ÈŠþ¹‘@+++°ûQAÃà$2„À$€IBDV¹Uî„/dâç)Þ çÄ9‚⿬‰R‚ °S¹J«Ñª­ÁP8–»Ü.w}U«i¡Eu%BmTÐsnϸ±çp »f‚÷½X¡Aàd¨4¬¼Í¯à=J”¬£" ÝB â Ê+ZV¹4 CÏð~¨RÖÓ7¶D[úkëÕj¥º]ƒòrÕJ“£°¨ †¼G3ŽY½Q並ßáBÈïkj|-Îô¹ÎÌ qS¡TŠTú~ô?x† ‰M+oóvò^"ô#–5ËN ²ØA– + À¤ˆ9œËn ÕjÞÎÌJî¶–±ˆ¿¢ÊÖ»}Çò¿Í £ë¯}ü¶ÄÔïLáÔØ‚T}øÙ-Ènݪ¹·± Ý÷߽õZ\zàt]„R¶²ƒºAÝóÀۜՌ ýZzU 3†+Órk™ÑóÙímMa»Y¬Þ Û-Ê“˜õÅj ¡‰NSM‹jµj$ÊS¨Êy¾v‡Ï‹lö†F#v«@¨±×¥ZU-3J H‡ƒo6í'}ZcA>ô$yL°›P3r )ä2V`-—…Cä±éŠV§¯¬´»rç<öè#‚ÝÞÖÆmG¿Lÿ ýÓžh¯ô÷Ÿûµ †þô¬ ã#‚i" ô°«„ÂŒ5m"wˆÕ®ZL¸_« ´^ (l{?‹ŒÊSe¥V ª­9sv\µpäèŽí%eÛ–êëî¹—^ùÒ¦j+Uf-”w†*ÑhŒ|Ìn-4EjjêjÐñüG†ÑÐðbwk{eÍÀ൯¿«º¨Á Q~N_¤fÛá¥ET'aO®d%•ËX}ƒ,JR$ÔOù›Ý¾Ò²îàŽ÷{¡G£'½­MÛn} EûáãmAÿæÏÑÏÓ/|øãçÃä{-v‚p‚ ñy¸XqÙíA«š33ŽM€|/ñÔ8õR1Bâ<«½ÊC~Çq¤y±ÝZít:ÕùvÝ$ïê)£^­„QM7yþPBoPª€[AðÃàQþ¬Ga%ª×…)ZŒs]»8ºÐKѦÞíµµ*fîJ,7W­ÕoíT)ƒ´»Æ C8–79lUº« Ï1Áæºôãèô¢Ù,— ó¦B!ÌQšYRÆÈæZù#y‚Ÿ! ™ˆ¨í܉ýkv#SXnÇ gßz+G¨RÈ#æ©kå¡ý׎\ågèÇÇ3ßÐèó¥ãšü¾zÛ ô±ýŠñØ~ …hŠ‚í*¹ŒæÎG¶A7É`Zð1†_|,XÉÅ´VP£_ª,[3?o0êóć#´;ñÌÚätÕ )$äKäšB¥Š<ÂkÍìÝ¥uñ!¥äë´½ägÇZË?7:ê-{¬V£ÑšS(“©ò¤:}åS{ÇÀüÄŽ•xoUê‰Nð¡›ópgeÆü ËZNË)Iƒ³Ñ-gÐUŒâÈÎ'o® îØŽBHœo¡ŠšJ ¨Ð‰®š†’2T]=99Ó¦]>ðór ô&s 2ÜÜïñˆ÷׸­zOÅ‘»Q0Ð?³uðö+…F5dl“B§¶”¹ýV»ËYÙmd쮎–œ¤ïj’*D9È¥ë²Ú‘ËqU·o…ËmFÐ|/Ä÷.8ärgVN挺™ÆrsM‹†0à5ZšcãÉo&¯B“~vÇðÍ®uºs!X|¶ *)î wW”•¾¯»&RŽýî·Ž=ÕÙ5Rm³#·+^oÐzï;´oMÒj-wÒ.˜%¤„ <€cmçt­¼L¥r5z=žò†¦2§ì_/¬Z³Ùù¦†rÉ×jickItÁ¹¿ç–3QÎpdÓ7®ÀS‹S§š=0STBJ{ˆ^ž™® ¡‰o¼vUjiñ•€Ã%–ˆörÙU DJ•ÃÀ{©¡q1}ä{7=€î:þÒÙÇÛ³h!õýÝ;ÛÅ Öú+‘í‹M …L’&6¯¼M¾’ÔÁ@iÏV*̙ˮ¬„";/À¥Õ`%k• g)œšÈãR[}csc‰©Pe9~g¹×]ÔÖ1Ô’´ˆ­«ÌVÖßÛ^N™Í–©{<ÑîÎÛzÚrEžXÏ{‘~ñh°ÒXh7ê‹Çã-íC›º»‹ŠQ ¤± Ô(5›J}v[ÇLÕÀøî‘­NiŽˆ©€.è:ò!;2]oãìÈ­ òçz.Ê’¯FØ,)±ëG¯šíèV–£_Ў˦ËÓÓ&s~®Ë¹eóý ÃÌÊ/ùVÈí—ÓçEÂl Šìò×#dõ·^‡\÷À;“Wl^Hšª©U›š¼O¼·eàÐÍ?hªªòYŒ¦B…ÓYzÝÕÇ’-Q½¡2xãs›7—–íÝóµh½·µÙ¨—@¯VûÅÄT¨ªÍk+÷Z÷L%nzbùä8¨R]D?_H¡úºÍ>§¸¨i[SCß®R)Y¾ÅŠäÒzÆ;Ÿ\ù :Ï;ñ`Y‹¦µC&T^4FÃ-~ŸÏßÒêó3MSK«ßW±:âY[i¼Lªbý¸‚õÀ_ ¶‚Ë™ìËhÑÍZN¸ZÅqhزÚb ?^lu—í[>y}b·¯•{Çb_¸n6±7uàš‡þýÑǷ혜xòÏÜvz»Á¢×ä€fJž‹¡Î®¥»Ÿýúñ=½Uá#Kû*C[‡z๟zrtÕ9t¦àjXÞ…+Ç1›S/®†ÂËÖÞ¦ÆÖ+ê4JÄDW…AÁDC±Ó]*UFhW=™·û¡«ð7·œ¦ïÄý§CdÕO¢û-&…ÌXØBçÅuv.Š»y_c‹""Z@›³âZÅ6¾¸ë)¹¾íx"õ¥¾øóf¹L£m@Öz¼'qÈ` Ò…Y>*y®V¥l  WE<èõF³ÉdT(rœNžÞxÝý­ïhíÖ$’M’Fc_/"ø‘›îâC:‚‚üÎEâ™ÔºÖjhq®Áñ²–d„"ô”D¬×¶gþ+›aÑáŠ@çðäð`Y)ò”mémö‡‡ÆCöÊjWãdã.ú¡N½A"q:‘M㽉SîÊ‹PcS*}ãíé½µõÈ®xõà¿¿­¡;@R#d“«@›6îF ÅlÇÌdÿZ6ÄRòV[®Í3zj¬in6§ìúà®gvíô–wt]9z¤þà¶‘Êxddß@Ód§©”:‘Í,Ñúñíûö÷ö{+ôþʹ·•ª\iê4Á‚Ï/{,ÌͪteEP€åó1Ý â¤q²Î:#è“U%ˆ(`ð Drµê'®Ù9Þí/nZ8p7ý«LßN»µ ?¿ÀfßAùϱXU¡¶ŽÌ¯oki†ºesD›ï@¨ÐêkeÆ¥žž^òǞƟ»gb?r*d…¦yÞœÙ$—!'**زs¬§WAY 3‰T›Í(óÛMt¯?d,D[kó–+{»Íf&Æätïwpß תó‚«*•l›Ïy3"×µ7\nÅá> Ò —ô¾_©òŸž«A:Cª.7™›éãmS[A`¬  I”#’éŒE!ùO_p8 Àerk>†Œ'#­†t:fêË™nú|í ÏÛRãr"d¡šÝâ¼Â’Œ7C¤ñÆ6ðfožØ›/²?ë(<ùj²·“ÅùvÛŽ t݇ì×_7°åö±ßXåËÍÑhóAr’>Ø õR‚þ_¢T;LÊÛ‹Jî€Æö‰k=”Ó)”hKÒè3%ôm»õ… ]|ë@Ê«a’Þ†NœZ1¶(Õ{à$=p’%ÈCÜý×ÄÕÌ{ù{È…™w£”|¶§¹±o¤¾ÎÚ×ÝÙ?©Öj˜Ì\XmTˆóTZSYi™G®‰Ò&·V“#çitÆbÊWÉà˜Wï/¶Ø­%¥C#ÅE¨ÔÛÜz‚¾½Äð‹ cèØÕv›\f¡hñ¤ÞÅ4}J™A»»Ž²(jª‹[¨‹®7؆üG²™œ3UB{ö¦¸œÙZ ¾po«®*vKìvÕ–á7¾îy.¾ ò÷TGfkàÓ™W†¦†ùÌÖëëè¾^d&úÀáæ¨QÊx˜råÞ{¥æ £ýý‹ÖƒÞ÷Éte§T‚CV#™©0LÏD¾~СƒÈ´…®8}?*?²¨”vB£ñPÆF°/*üVЄƒ®F˜V-Ⱦî0/*œCd£M鲯o•ýaÞO„"¦Š^jWµ=35×”Û¦£ÁÊH®D§‹~¦{Æ¥uit½WS|Å&AϹÎ+­29ÏÚ{|ØB!tÿÁçOîÛS_‡ôÆFd˜Ñš¤P37߆”Toßé¯ ;Uè“‘{èVÞ›à¯ðÜ+™÷µ}µD@²‚oæõ%ög+÷>Åä06“¹¸7"¿ÈÆ!g³/{Q[íÉ/ ÈW}*]¸úÊX§0å1SLJ®ÿÒ¿õ/ Êàà ]75íñØ­»nDÁÊô͵µèª…/ï슸‹*v‡"ÅEª&2i­ŽÔº 1]1 ”ò€ü¾ƒt›ÈùÑ›Ì=›¾=LµÅo$ÁJÜëeo=ÙG¬ÉÅP¥T(”–FJËüC`Ž¡+è{Ê*6÷m‘É!³A¯WõW hËâíÉ$Pö£$¹LÖ3<‘5h%—3Ï‘í(ùcöå9þÿB\‘A#ü–sßäõžÿ*ÿºy€®»¢í€ù0=J¾’×r¯WŒ ¸¢Ï5ôØNZ5ÛÕcÄnȽKq÷ïùJÜëÓ銊{B‹WWuºœ Ïò²iûäöÞrDiàfãù5r»#5í!ÁnÊlj‹w¶´uTØÁÖ¶ºÚ³í ²œ¬(ïínoÝwE{_UH^'ÔliÞÓÐØÒ\R¬’Bä0·¡ŸCä”U­6­µ1ˆmË8ØÍHª@b·íÌt­«R{þ”Jut̶^ÚEazˆî©¾¥µ¥ØÝÑušœ¡]¶`ÙìÛv8«·ÐÁ E:ÉòžÌ“]Kt÷©îNºÞN‘7 æ˜{'ç ÙÇ*ÅW ¶8Áu˜“šíb¹»šëŶû@ר¸¨·réšp7¾âê<ž)ûÄÎí>¯Eë÷Á…Ck†[pM¤-LyÁ@´)>ÞÕÚÞæ·QnW µµ>ãH´Ð'ú|ݽí-ûFÚúÃUÒ:yud eh_]4ÚR\¢Ä9± ´-a_æP6 _.UãJd— $Ê]Ôì¾2©™Šx25Lj–‰ÑØ‘º+4.A}ÇuUa«âÜo×çb¾¦fó ”døÀ}ìQTIH/½!â‚ûª¼ô~U÷«“ ­‹é˜ò!ZkìØW«M9÷BLC¾±U, ¶2Ƶߪl£hË´Ü…e”¹|l_.«†ú.‘)ÜÅ»Îä'Î?°§¨2¼Ç3Ë{Þ1¿ÞÉWÞ< ¤‚© <;ï¢"âþ«E…÷Î q®òã*·Á~æS(¨Ï›5:/úe•TZxhŸ)U!¤.7Ké?›È'3ä#§|)ˆ‘_ Ñw¢9]·Z™ ÜU´]0Ñßap+ä§S¤7^Ñ32¾A!§AGJ&g­½9“¾Žy¢X‚9]‡‡>"Nßñ/ÿð£EU߈õ£ýC÷Lµn…äPèéì’œý>ý*M¿LŸÿèe”®w¡‚|£!.ŒØ”2T[W~G·ñ•ôY&—ò¬j«’ï:÷ïôÙÙiþŸCÕj§Ⱥ?«ª0f¸Ü{Ìj·â5^©–»\ùNw Cy¹}dóóé”ßYwn6Û³ðó ®¨‡ŸtVG«NAÏò³Í›ÿ!S³ØÝiÔÓ¯Ò¤r„F®x†Þœí\¶kl*““Nkj4+¸÷scSæe ]ò´.L‘}]ÆäÔ¶^tÞ+h,*«u òòÄv[uY¦FŒ ™t™?òËJwÒ¾Û­RJÓqÙìU¥d úïZ§ºÀªŸ8ð‚6ëwçJù?<ß×ø-Ð4“r©Aïïàm›2èUJ¦'ü è~\0;x³½ÍšÄÙ>W(r;É{óÄÛ&K&äv9 òsÁ´–@§ýQ0}î‰klД@Œª”Û ä·¯Ôi2dq¼Þ*ƒhü2p°±½q•Í(ÀÕ‡àj âæñxƒ´µºJ™a7]×YîmCÿW‰ÞmóØê3 Æ>J#$M3ß<-­6ÊEN§8Pq/¿æÜc÷QÐè#­Ì,WåFÿˆ^¥=ÌߊVþCèÌâû¬<ûzvÁ»Ï¥–Õ‡ È~UlAcŸ‚nr¶Ütó}÷LÄKJP¹gzò¨/aSTØÉ;{ ‘åÞxËÑ“g®½>6nG?}µO ”NÄ”&N%ØMÛ^žœ¾çÔé—î¼³µ5O¬B†>=\à^(•ÛUôo"&s°rxh÷‘'PÅk¯Êrœ.µ²†é[KWÞáÁÓ ñßãäÙ¿d{A—ŠW‚³Ö\-ºvzjÏ­»†‡|¾ºúøÔÁÞšHõ½6ÜHüèPìrÖú¡ Ó…ÜÑaAO&³ŒP¸fjú𩫯mŒêt¡8ÿá~•© Ÿtf¢G¯·E.ThÚ:ô«76×€Že“žɜٿǯsùvõ­¡ìŸÕ`^ðtWMéí±Ò僦Â>òˆfĢ͕#+’øòÄH&7—µ zœ’æÀ³çþ‡:c·AjÕÈL a&³“™u9 f­&š‚ù;8|Š+öëwIk?dþ(~ñ?È6­¥s€'\„="+ÝJle‡¢iLiý¿ja52’ÕD ?E4ðn%úàÓE>Nlæ¿zž‰(†µV€ði‚ù퀳‰„ÍxAtN¿`ˆpÞ à<%ø.ÑÏìO |\06À:ƒ+ãÿš¨V^áãD7À^˜SNüö 3Ä}@· hTðo'Šy.âaØë„ßm°¿ Ö¶ÁØà¼túá7Ê'VÞƒõbÑ­ +AÜ̬ÃÚÐ-a`U ¹öjâHˆ¼èFôèm²‚Œ‘Oò̼üwŠ÷K~„ ÿ]%˜ü³0_8&|Zd¥EßʱçœÎù}®3÷€8G¬GÅýâ¸øLž1o9ï+y¯Hd’1É!ÉË’ÿ”|˜ß“ÿxþ›¦‚ ~$-Àš®&v1ÙŸµÄ%ÿ¶ð~KÜú þæaL310 †>ÌÁê €2âó€WAÎó oÎ(†0/ιƒùDIÎݼ0ç ó WÎ÷0,bô–óƒ®rþ„ᘗäš9˜O”å–`˜ù¿4fr‡9ôŸûÜ·8ôŸûšâý‹÷s0è_|7ƒþÅ/s0è?ïƒþóÎp0è_Òa1sö‚_s0œ½à΃y…ÔÌÁ|Â/õaXÂÈ&ã`G:ƒá¦"Iq0ŸðIÀ° Óù 3tÞÁ°’Ñ¡LÃÁ C™ Ã*FY”ƒAY?†Õ0¯’]ËÁ|¢RÆòÒ`üïr0ƒÿ†õ ¾œä`À—³¼ŒŒMå] 6•b¸‘G~-ƒ<òC¶`üÇ9˜ÁÃL¿(‘¿ÅÁ`Sùo1\ÂèG¡á`Ђա‡¡£hã` £ÀçÊÁúWìç`_qÃø\Нq03m*añ?à`˜WÆvQz9ø*CÄ ŠðCEó!€‰i"¿½D’˜‡OšX&ðL3ŒR3ß1˜O` /¬4AìÏÂïÌMÁþ4±ˆGqøöøžÌAXŸÃ³± ~÷b¬$ÌÅ€R YÀ»˜sÍû¨Õ5Ä0æ·ÈÉFAàêƒ ©fÇa5 ëIbèbʉ®—ûÖQai¬Qè'¶žu'Üc¯Äà“Æzžf-Eì†9Fî¿ÝF ÕyL‘Ý7£Œ«P aãÆ9Îó0[Ž)P˜ö4>;ºKK°ÊÈ•ÀØÞ¿Y’KñW¡Œ¹Ë:ã>8ë$¶³êY•tt‡],×ÖCµ f†1~š“¾ëÑ #5öª{ù‰| ë•¡³„ý”Õ«ÿIL1õÁŒ°æ°Ö²zÃ{³:m­2ïóìÞÔº•ìsÀeSdm±ó‡ïËóeÇ î8œw Ÿbã&á{¯/À {Öj,¯Gaœ£Åžž‰Sê’“'±6—q|$ (ìmc«¼.'×ü%´?¹–Ö¨O¬Ú9…}‰õªñUO¹üé×üøB¹"ëtÀœ„=KóËú CŸ=ëÌìÅ'Oâ»üIYMÇ.Ðjœ‹Š‹cƒÑjð–ðNFÚ=«žËÒa0gã¯Úè‹”ßç QƒÓqª79ŸL//Ä©ædj!™Š¥Éy/Õ4;K $¦¦Ó‹Ô@|1žÚŸð&æâ‹Ô¦ø^j 9›&g'²›k.Z£˜Åšáxj¨QA¯¯‚*êMŒ§’‹ÉÉtñå×ãzû0 ``„þ-Ìlðâ‰E*F¥S±‰ø\,µ›JNþÅQ‰y* kCó‰t|‚Ú’Ž¥Rl~¢<™¢’°’¢Æ“KóéT"¾èýKDV癯–Tlob~Šê›œLŒÇ)Ct~6¾ [S‰Åä|5œOùžXj">Ÿ¦*ªþ‘ä5[¦–ã È?™„•Ø"µOÍ%ÒŒlcËXÒÖ¡ž&XMáÁB*9±4žfN±w:1>½n/ü&æÇg—&`k:IM$f v%a°€½—¢²Ì“ó³ËTQ¢˜ŠÏ1»ÖhÍg±/+FŸ`ΜŠ/‚ªÆ¥¬cuÌÑŠ` ŠÀ%Ÿc4˜J׉äÞùÙdl=S:ÆŠ FXµFr)½°”¦&â{åÎt|vá¢áº6…ãšÉ×U¼ ±ÓÄʇùw7Ü·†9‰³ÃFø,Væ“Þ›Ããæ=Ï{™÷møþÊF{.Àý´«ú´«ú´«ú´«ú´«úÿÞU­V˜ÄßTXìø†ß=€ÁÌ,m¸ÿÒíXS‹îÌâµAM›…Ìô' ñ.Ìm\«.ÄÏÒYäj]òs^Û1Œ¡ö±X0šÞ“ŸhÏ…Øý°Âh{ <˜õÑ-t¹=ë­¶ñy/Àæ[øõü¿™âWñùuün~õFþžOÚ»¬a¶}"±XÝŒæPÌl„¿†Ù3ÁxÇÆZY‡‹äįyvXÙ`Ï*^ÎÆ‰O`½5Ì¿'.ÿ{ÿ]|ÿÆXþ_äþ= endstream endobj 92 0 obj 7659 endobj 90 0 obj << /Type /Font /Subtype /CIDFontType2 /BaseFont /TimesNewRomanPS-BoldMT /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> /FontDescriptor 88 0 R /CIDToGIDMap /Identity /W [0 [772 276 551 440 440 330 496 330 386 551 330 330 496 440 248 276 496 386 661 551 330 716 551 551 551 716 661 496 605 772 826 605 496 551 496 218 248 330 565 390 716 390 661 248 716 716 330 772 330 496 661 936 496 716 772 551 716 ] ] >> endobj 91 0 obj << /Length 756 >> stream /CIDInit /ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def /CMapName /Adobe-Identity-UCS def /CMapType 2 def 1 begincodespacerange <0000> endcodespacerange 2 beginbfrange <0000> <0000> <0000> <0001> <0038> [<006C> <0075> <0065> <0072> <0028> <0033> <0029> <0049> <006E> <0074> <0066> <0061> <0063> <0009> <0069> <006F> <0073> <004C> <0053> <003A> <0043> <0068> <006B> <0070> <0044> <0042> <0079> <0050> <004B> <006D> <0046> <0076> <0064> <0067> <007C> <002C> <002D> <003E> <007B> <0052> <007D> <0054> <002E> <004E> <0077> <005B> <004F> <005D> <005F> <0045> <004D> <0031> <0041> <0047> <0062> <0056> ] endbfrange endcmap CMapName currentdict /CMap defineresource pop end end endstream endobj 6 0 obj << /Type /Font /Subtype /Type0 /BaseFont /TimesNewRomanPS-BoldMT /Encoding /Identity-H /DescendantFonts [90 0 R] /ToUnicode 91 0 R>> endobj 93 0 obj << /Type /FontDescriptor /FontName /QPDAAA+TimesNewRomanPS-ItalicMT /Flags 4 /FontBBox [-497.558593 -438.964843 1352.53906 891.113281 ] /ItalicAngle -16.3281250 /Ascent 891.113281 /Descent -216.308593 /CapHeight 662.109375 /StemV 48.8281250 /FontFile2 94 0 R >> endobj 94 0 obj << /Length1 6832 /Length 97 0 R /Filter /FlateDecode >> stream xœíV[lWþÏÎÎx}Ëú–5ñ-Çq¼vÜx³õ5‰›4Ávš¨Î¥±ãPŠJÆ;c{âÝ™íì¬/Q…ªBQUU•Š"õ!ñ‚¨ DEB¨HHP!„DAˆHQA°ùÏ?g×»ŽÃÚÍ ÞÕÎ~ç?ßûÎ93 Bð(ç'õý½féy´¼Š¿+sɕكúOÿ€½0oê†Ñræ€@mCóh¨zcõ Ž¿…ãýó)o¹ò:»‚ãŸá¸*é$t0á×8þ•È’Ò—Ó Á1ÿÇÜÖSæ›×*nâø@ã; (Ãìë BH½¡öÃAÖIÿÊ[0¨cj  *jP-W‚BÅÀò(FõÃÔÙQŽˆ¯ÝS_[=ÅúËÚÙ»'€ýø÷ÿPžS'D6B€µ¨-*¡  ½¶½¶/¬%÷¸rëÞ þ ¿§é‰SÎÞæêÁþÚGZ•WVþÒñcû:µ·µ }í‰Ó'¬óO±ŽªûÆã³ƒ=Ç»:F® ]eA¥¾á­þ¾\õÉ_¿~ìbãmüˆ¾p…"ÈÓòFô)k_‡ËþPmöW½à£hì90 —•æµ»8Þûî±x Wr;eÃgR¹Cñ¹êG"f@¼,±ixCâ îÏ Ä*´±¸ÄÄÙ9‰ËàìK‡ ˜¸¾x^âêÀ %¯mPý¦Ä Âê/%€¦~(±‡Õ?K„ˆÖ&± am@b >£J\sÚ3‡ÐþžÄå0ªýVâjv¶¬#ã2a®]¡«!Z&¬’ýÛ û;„5¡Oè£&¡»„Ë„½¼Ib´—G ‡È~Qba–p¹Ð¿üºÄ¨ùÇ#¿¢NbÔ¿¢Mbô­xMbÔ¿âG£þ¿‘õ¯ IŒúW~ 1ê_¥IŒúW½J¸BôŽJŒ=†W¢½!<#q‹„«Ð^þŽÄAˆ‡ýv¡=¾#qºÃ#\#â×4IŒñkº ד}Zba77ˆÞk^—û­¹Ix7ñß—Xðý~#Â^«IŒöÚÂ{DœÚÏJŒqjÏn&þ5‰ÿe­ÄÿÄ‚ÿá½d¿+±°ÿ‹ð~§.*1Æ©óuë!ûŒÄž&Ü+âÔÝ”ãÔ‘†!Ò¿î‰ÿO„©¯ú:‰Ñ^Ï®"~ý9‰…ý „i]ê¯KŒëRÞÆûÞÉã0„h æñþÀá,8`ãσ<ÙÂ2Š#±¸êh·ˆÙ“Ä/‡‹h›C242ñßDö"^ dNá|ЬÎáÿ±´éé úéÇ‚Ä}Ù–ðåEÞGašòfd1»èC7Æg2ø›E¿ÛŠþ Ø1è‡å‚H~œõ(`z7t9U2³E3:þ<ÒÝ@Ž˜sam¢þí¯™ˆjSDßïŽ,‰UâX¥G\Sf¶Ñzˆ"pŠ=Oýs¬ß,Ίº,bǶ]Éý¼©<#æÕ:‡ãóØë,é&f{ó•Ú¨¦‰^~V—Q¢ešøž¬~‚t Šª9< GpÍúàiê„“®"N–ö­¯¯ÿ,EôH1N“)R-§Û ùæ4GU'ðdø¾nÁLšöžYÑ_‹%Ê•Àëæyý±à&°ß,ua×Á«Aóiœñ;ðWÍÏeÉ Ëï^œ[~_穹BçÄÂsÁi·ÍäsmV—}_ì­«´Ýȯ³K{ÉßU‰üNÙ¼ûõ}\\×H¢¿òåö ˆï÷j e‰:wè„mÞ©¯´^¤ª)OÅÆ³!Tõ—%OQíb~çúq3‰Œÿ¹Foó¾x|ˆOÍ›ü¬c;ÞJÚ䣎›v\ݳ;ÆO&“ü¢57ïeøE3cº‹¦›²Rf†Ÿ3—øE'¥Ûg<=i%rîG7Ìrúè´éf0"ŒÅã¼û¬•pŒ3ëØœ^ÈŽõ/ 9D¹0Ù+SNmt¶2\çž«fJw¸3ûÀθesç.Ù–g|ÒÓ=Œ¤ÛÆ!Çåθ<ádmϵÌLìAAò¶)qsõ%Ëžãçgg­„É{EP;i® «keû Ÿ¶†ŸÐ]ô=þè‘þ¾§,Oé+<›1±¬ÖÁ=ÃÓ¦›²> /FontDescriptor 93 0 R /CIDToGIDMap /Identity /W [0 [771 275 385 ] ] >> endobj 96 0 obj << /Length 378 >> stream /CIDInit /ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def /CMapName /Adobe-Identity-UCS def /CMapType 2 def 1 begincodespacerange <0000> endcodespacerange 2 beginbfrange <0000> <0000> <0000> <0001> <0002> [<0069> <0073> ] endbfrange endcmap CMapName currentdict /CMap defineresource pop end end endstream endobj 9 0 obj << /Type /Font /Subtype /Type0 /BaseFont /TimesNewRomanPS-ItalicMT /Encoding /Identity-H /DescendantFonts [95 0 R] /ToUnicode 96 0 R>> endobj 98 0 obj << /Type /FontDescriptor /FontName /QUDAAA+TimesNewRomanPSMT /Flags 4 /FontBBox [-568.359375 -422.363281 2000 891.113281 ] /ItalicAngle 0 /Ascent 891.113281 /Descent -216.308593 /CapHeight 662.109375 /StemV 48.8281250 /FontFile2 99 0 R >> endobj 99 0 obj << /Length1 14508 /Length 102 0 R /Filter /FlateDecode >> stream xœízi`WµðÜ-Þ´YÖ.K#K#ɶ,ËZ-ïû¯‰·8I/’mÅk¼$q’¦i𥥴%¤´¥;-¤)M€Ò•BZ –¯<èò€òÊG¡t¡¯ðÊj{üÎÜÙNà{¿¾?X͹˜{îÙψ ˆâADGW¡_]¿5=7À50:±8rë)wüAØ2ŒÅßkú!A8ž…¾ðtÈì hÿÚŽ±ÉùýÅ›Á˜ eLL­–ž"§ÆOîŸ!‰ÝÐ>mzjp2þ™ÓS¿ö+¡ú9AQ!t!&RÄ·‹€áïÔ=Ä™‰Ä$)¡Ä"1I‰Þ"òþëYb5`I…‹èn«¥‰*‚^]ßÀ6 €Ô†ž®"Ðêê*<}JÜÊ­Fˆ]b³: )AØT6_È,"–iêÙå*1±DÐ"Ø"rWI©àI \²iì9R‰F•%•H%ö—3䌄~V§ ø#áˆ*èrºœö—Èú¢nFo³oîšÛ #£Íc5\ZƤ×"YºÕS(v1L‘mq%qûÎ] …Þ2ŸÑªÑlÛlÝÔ]£6C¦ž H¢eõmª‹:O¬.Ñ kG`í¬¬alNnYöS2;Ö_WS`ÕÆFn}`aBö?vûððÊ1ôe±Òè󇻫jÉÒ—çæýEû³NÌì¹úªŸ¾ô„b£gJ¶:"6+ªªæÖn^ý€:A#J‰&#,éâ¶„%Ñl3B—ìçØ åØ¼án-LÓHì K%ḥãÈ×’Ÿv„Ëw•WXÜ£±ßål©dœ$Ò§Vú·Þ½ØQ’)ÉÒ”Ê MÙž¸ßœ>Ÿßi³#äÉ/n9:¥4¢êªñmyY¯ãx0cÏ/)Ô‘ÑàíinBnºÚs”ýþQ³%-¡YYñid·BW”<>_´ÙëC Ó üŸñÞŽø7ÐÐØB˜ÉáŠgéÅý!AÂ9R@-÷|¶%¦µò4£¾†-UWõé"dÍiÝ·7]fÔ·°¥YõF½4E¡2d;(+ŸüÝsˆqõ”bû¬F™ÜáÈR;åhß¡’º†Í¾B›Íu:râ¨û‡].S8f€ÞæÕ·Ä ñ8QôªíÜú˜¥š¬5ÅÃ:!âÁk$–€èGVkÅÜü=Ç&§Ê+KKöïýüÑxì€uäø‰§ØGž8‰vl»÷îg>û™¼LS–!C<Î~¸c;ª­?}ú?Ÿ¼îXSS4r&ë±®n´ôÔò¿=³ëŠ&BY&P$þ·øF¢(R…“6p&bv¹8rÅ€1í†!ÌIÔ6]]UÓ^1«åiz]5[¡©VR •Í^膛ÓÓ²MlI¹]-ËÀìÔzå(S|ãÊТ#'ß³½ú ûÍ­VƒÀPe;ª;]è5h2;Xó.­N¡BÊJÍ6÷RåwrœUÚ9ÎÆVß&_M(áöaŒHÇQ ÿY¼³íª€Àé¿!l ¸Û y“ÍUR¾½1σhë®[þ íܵÐ=aÓèd6›©³c¨Þ“ïóßt‹§ ½õP¸- R¦¦fPçØï}6DŒÓSìÎõ6ßwek›% Pã§sÝÑúBosci´o¦­i(Eª«¬[ýõ$Ы& ˜³8¬ œ F°mêr’š¨%‰WïF¨¤ttìªWÇPeùèHW8®¦³ýÚÁÊÊDuÝyìÜÁÇ«ªÑ×åð•‡ÊJª¬tGçÁïÝ| êìxþã€W$x£êQÈñ*©z:±=$ø# ÛŒS²©x¢†S¤*…Îê’³ì+¯¨oDµ L2¹)»UäWå‡[ÌÙÛ¨S+¯Þ“ÃÈä*ûž Gl¶‚üƆ#è¶*£A.CÌÊGܹÈdl#¥mÙ&’cQÎJšh⨒$Õï“*vÉ3Œ†&¶²R§•ˤ)r•ÎèV!•øÆ¥ê^s6XšÉe–ì^ªêv&'©SìYôyâ{vuˆs}€1éú9~ƒÚk =5 Ô£VƒÇr2áêP54³g=9M ›3å©H ª,²ç héα¾~ÎÃÚ!Ad) Ê Ùç-%.n‹Ý=dÃæÅ)¤ ù<{yG,cO³¡ U.W(Q6ÓZy:ÐãԘݭôáëc#M hs×CH?P_?½\®–ËÒž‹ ¢ŽÍ×”‘Hv難aŠ­óÔÄUt>b¬twïüáíW0ìÁcùž ò‰º»®½ª³C z°šð$ðÜHä'=¨F0×F©R ’ ¨ôèŸN$î»á¡Î-Ý=Ò¥J—+Gêq8º­³½½s8Ì%ÿôÚà•?ž:’m.¥¾ñÁ\WÜ+?÷Œ(ûö¹¦,‚÷Cäã`^hhÖÄ!X-øœ‹BˆÏ.¬­³" sƒÑaÏ÷h25>”öZÁæ×Û97.IQª ´3 i¨s?|Ùìù.“ ¨ÎÝÉ6·9M™™ð´NiWnFÃwÓÐOÎYMY«¿'ËDÏ6N#ûš-Ö %¤²cm GЦ×^3êsiÚªrÙ«ªk ÍÍáÒh6Oôû㆕Gú­4Ò¨s‡ŠüFƒÏ#ÇlÚP°‰áÖÊ\ý¥øСnÿÜŽ‘ñÉä*|ÔE ¡KüHv³.†¹”F»³œÌÛeÊF¨õ£*/Bæìzq†¸•‘ÓþØÒaÑÍÛ²¬™J äiuÿîå_Sª9¯ÙlÈ@`z$§µ¤´@µ@ðEIËPÿ#[Ìͳ˜a5K^žÅb1_…äéF}5[[«Ó*d©)r¥!Û%GYâ“S¸o3›³B÷š-œç  ž*°Ê30×I¢võW"1Pã$"ëùJ„ÏKBur£çâý§™Bzòb]euóé™=]yè;û;±†óeHU€˜© ýÈ+±XŠÞþºR–‰m£Ù4:|è»Ï?p?j=“ .KoÞ'ø±ï£7j£‹¹#ñâvO È9ËÙêg µõD/1¼s Û¯’(ìÔív­_I„˜$|’¶&dcNÞ÷#Áï'£”â:$ëèr¢PwA‹ß{Íà…¼)%A"Jš’¿/‚ÐàÐõ “*¥Ï´çåŠ+Š#»ïüÛ…£-éʰtW(K‡²MHÛRä¯ v¶ø‹êƒOêõ¨4öÌ£½=Ðm¿Díî–æþãCƒ¨ !J’¦5¦‰)ªiæÈö(Ëi¶¨UJ•DLŠSå‘â-{†oé+ŠèõLMê°Å¨£s|^ò8*)[¼«¯&=p÷¶šå«ƒùÆç¨@Õ•MF,m÷@ÖqV<†ce ¾¸gO&!œ$¥6œ~D¨³»–ßB7ßÔÑ9oßÌ0†±Ñ;˜žD¾Mþ­ Mxòí9&$f—TóÒººk P1óDlx÷øgÆFîûû_‘©Q_ÀgÄïPÃêj"¢N´8‡£æ…™nD)äá5e‡‘M¨±a~ÛÀWÞŽPm]b|ðÂÕS/ÔG÷„JK,^Ÿ#š[Rl6É»~û廪ÐÝ/°ç>xàÁæô›çþ̾sþsÈï›=‹J~{ÇœÏVÞõµ¯>>H€.*FcKÓ¥…789Xü#´É†ÒS-–,¹+Ûœž†ÒRTYgµèÅ{—ŽÍš³åJÄ0H ©êòç§ò¬J…´ó ìó$`·EDµ A¡ÔปÔ@ ¯µŒ ƒkZª“ æ§v'îõŽÄº? ‡Ïž+iœ:a¼U”"ÿ~ÚÊå&##{˜ þ/NuA„o¬Ÿš¨5bɳG;;úŽìDhkÿl[{çîm£37ÅFÐùmý[_›¨,ïL”•p8:B÷øÍ›»®imGå}MÑÝÀ­.t„ÜJê¸ÊVmÓØºHñÊ©»•öÂNÁ“©iÂ΄ýÙ$ëYž.ÇxGÊ…dÌk!®•ôo=z_ÍS‡ª«fnaß?Qä×ks Fey™ŽÉ‹·µ £Õ³©¥rª‡£ªzà £¢MÇ[›ÑîÎþÏÝéß¶ãÀù«¿ŒÀ¦Í:-’Š­´$ò®‰Ž–ˆÅ ™%­Ð[[Ý9R]ù P]A¢óàómÉjhÀA†O82U| µ«E÷*œéjÚêú¶‰é,\yÎ×Ãhïßå9œ§RÜÊ^èvD³MK_iÍ]YçDH–ŠlGéÿÊn¢žOUU5A1Í3sáp¿žñk×Ë&.úŠ×<-fg $2:š:Oî˜AÇ÷œÙÎ-ÊH³˜[XÚq©A?¥©ÊL‹žAÁTYq¸+V±m¯î+ò2Ttöµý~ßħ~üáíGFQÀ¾»KoT(†Ô¥uqjh«AŸ„_Å>4“Sšïiyòß÷´ë3¹©"‰öǹJX膢E’,L6-˜RÝzÑâ_³­K2 ÿ¥á-€:c™žP0ÐSY®mlhmŽFr´Hžf2V°eê’mºÈä$¡²17²E­`ž"dótD‚]8BñXaÔË…xÈWÄŒVƒŠ;÷;ÆÙSzÝÛgÕɹâ†ÏDNNV!ƒ©)=ŸmI–=¨(»`Ä_…Ìž«Ùf2qAb¨¹í¼ÕC 1 ã∠K6Vrv0¯`’}šµT&éæ4š€=ÙgE×Ê›¹n`ýÚ×<ù;¶íë/,Ë¢3§…f ­6™üªuåÁ#9®^³ç ‘ۚʎì;®õF¬“JQÊRëþЫ5MøtþqÐyÎóë¨K’c{AŽ<½¢Ó¶ù¥ß$³`rd"ߣT!¤J7®þBeäçû¤ìMñ.Pã8ãeFk¥—î²jÒÒ‘N[Æ…\f%ù¬\9:ºÄÊøí‡lñCºu¦áqD5¬| fçcÝœÙ!µœqmAGÐèmt¤°Ï¹Y6g”ÏúúìÚ•?Š–÷®™!µ·?׬Q3K?1Lž]>¹>tréz ¬²ðM ×n sCæØ!¦Èçœ}R›œã“×Ü97õUß8Ö×§7æ—Z2EÒGy¼lóæŽ“ƒáÚñØÀе׼õƱcPôº´z§¦´„¶ æá{8tÕ€Õo^}M û#˜Kr?DxÁi!«Í ²¶Y/¬A…ÐÏñ4át?ð̳x²‡6°ˆ&÷¯<íëvêeéχÏÕŒl‰Î÷1À ¿õ 5ÏËðyÚò©1Ú¨ÒãÊ`õmñ£|µªÆ©0ð@­Þã6® ød§„äY†Ž„”*Õó/õ.])z´É’•òÊsj¤ÎŠ"ÛV7ûÃÜ_³dØŸf›³K©SŒX®0Óù+¿G_9V¦“´DZUN–fåh)L« ’aäcËï“Í+Sd3Ø4P‘›z¨+ß@DN!ÂðJ¥j!®óK˜%úæ— ËUªìiºê–&¤ÌdPØo÷w_ùv·Ãe;=FuÕuŸ­Ói ØW&fû³lrç–ÍH¦ÐŠT¶±±a£F¥5Céí{¾Ä>q@g$Á(ezíÎçŸß¡Ô«5àADóþÕåñldAJ¨ZÏ‹ÇAv\Íab¾@  õTH¦àïÌÊï°#‹y˜íé6*ЛvôF´ÐÛµòîæl³{ê7 ï¾Ö餵z)Ã(ô¾ÏŠv,}þ„+ã£N›“?€d¤cåçœ}ÿðÌŽy†Ïyn,xÖ :gv«5šW_Ó"$ÍPª‚(?¤¶›Ù§sÙ'uj(mŠ€p·ûX )‹Xdi ‰8!VZ–?¤Äa½V•šÂéR[O} +G/]9(8>a—"ÉzZÄlrž tVS ÕÙþóe%çTù(Ï©ÎÒ§ØëÃ}ýeŒRlŸ-êJ·8r˜jöq…ͨÐ85fW=ëGsçf¦¦¥@A&NϰÉ+—§®«­ƒ¬Á“g4hˆ¶ößM~ÝR˜#SfqO”QçÍ#ÂáÅź…#/*´žF^Ñ$\ÁÖñn³LŠÕëÆ®PqÕûïÚ}C[Ë(dnö$ÏÐiÛYoƒ]“®Àçsš<RŠo\žyµV‘¡VÊ(š¦´ú’ÿ`_?hóÉÒ¹Ó¸ôÔ,m²¯ô›³Ó3 G•¦·m¦jîvä€Fâó—Õ_¯¾'~ˆ?}§Àý/òöËûcš¡ÊÍÎŽBô†¯|¬cùÞƒÇÕ–ZèK‰¸uYJÉÑyص.Õ-?³î^ÏÕé4Y©ÀÁnvy8hàªkþØO©æÎµ×O_uZòÐçc7µ·ßvÛŸvt:]6ƒ“©,g§™Ö‘›_xþUBhu*¯nï¾G{þõG®ßÒÓÚ˜½€¹—ǬñE e‹Á gŒÞ[GnìhG·Þöçƒ ›Ñá*¯ÇòZFnyþ…WÙï³ìê$S·oá±o¼ðêù“][Ú[9¹_µúTÂãDóÚ™&.‘4’µúQ¨Ž…ÐÍn^|¼ér®êã“dê,“éõõômO€ÊyÊß{¦±ÞÉ ½‹O—éaƒQ¦ó5@¼Ÿ8´©É”u=òHs èôž™¯Œˆè ™Štñ8›¬³ÃçE•ÕÖC#áâæM›ï˜ÚƒRE6«BéE?º¥iS¡¯¦f[Q0à± ”FºoO  x}•‚;z$ž âè=ØŸY8óH·À†c(ŽvôÍÆ”‘¦LË4©\´Õê)®†P‰x<¿2èÒ J⨠`vF£Ý CU€ûYÀý7Þ'0iãû.Ô}8â4 ”&“¥gš”¹!:·´6„2¥”Š–‡˜°U¡r苲„"Ñî}ø½J»ID@Ôvpçè“é3'Éúé"ä©Ôš%òå<ˆ‰ÏÈ06±~uÄ¢–e쨭k¾n4qòäw¢>Ÿ³$t­ZSä¯ÜÓщº:çK ½Ô¹¥‘~½Q&W¥YL N¸r:°øƒßžº)UV³c¥=²É“o± »ž{r`Àˆ£èTH‹¼ý!©M*JÀ ¯ƒx݉¬ë¢ÛÙ±~”zǧò=55›ç÷ˆë´ƒF]ØÒ¶Ð¿µ£óäÔÓH$n}è1÷'ß¾£²ÚYŒòÜ“Nƒ¤)6Rß‘ƒã‰RO ©à¨ÈOö(På8†Kû@R±myöET2aÅgÑœ³H–Hèa”7ç‚÷TÈÔîÜöµ©FýÍl(è+¯q/,½ï+ôXeiÝ>‘FáÒLE¹11¹ò[»wžueçhÔˆ­Þ¦Ö¤e •²°ü0û0£SÒÖµçj‹›a_ßëÖ`Š¿Ìî&@¤\ŒTAÕ©²‘lz‚ýÊawKQÇ_¿ÀÍka$ÅÏSÜ\-0© &ýB<þ¶C9¹ÖMÔyȵ¬—9i󯿪ÀÙ—í¢ì«À›cE6¡A¿([ɲ­·lœvÖP£TÖÿhÒº•[³®dÙ¿fz~ál`Ã+QÔЦŸžÂÅ…L7maœáºPÕÕÛG¬tzš,M§ÑA?bÜ‘Z0ʺZñxnaQ Ä.“§H-ÜåØQi´7Ö×ãr––gsýÜ‘a¾ßîˆ÷&úz€{@²È záÇ'­õ b> |2¿Â…îÿsw®l‚ÌÌÊqÔþg•EE+O­ç›ÔïevcŽ£(°´à}'3͆ڎ¬L¶ç™' ìk;½ù !ø4r#ÕBˆÅG$kiº 6qòµ‚=yŠä\;‰ÌÅlÖ´tYºF§É³X\Lq ¸˜Úzëƒp–ž.×èyïãdµ‘pM5š-,¨0Ëeó¤X²=>È£}‰¾>G^A ¨Œ‹¬ÒDÃæì9¨¤´'Þ³•£r9Q>pÒ~™Úï¢wIp]0ÀE¢/B-ÓÄoÔÈĽzøý7v'šš&§_ô—TóܖѶ‡£¦¦;ØAd.yãÀ¸¶n[üÒèJ‘6¦‹Ä›;®îkkq2jsúê[â¯uœÇüä;xî8}-1À… ™#ý©¡·ùwîÞ}/ýbn¾Îq@]¸)Øí0"…ÌÅ47$>•H[¡^äÞÎ×Ò3+?}if¶cs[ëµ[ÿDfrC/ :fW¾Ú‰FAÁAEwl{ƒd8ú´ÕÿbD™ìíÜI[e.½)²³ ݇aûA#xGªRJ%6‘Ë©"ù·v*’w£*Òå$‡R.<÷ï°ï³ï<ómôæ·þòøä ô™É¯ëð!t|Z<Ž^ü>ûö/½„¾÷]TŽj^þjó±/³ßd¿þµès§P Úqöxòç¿õ\åØ` À,Ë“£Â…Y¥Ròï:Pªâ¢Ù|wß94ððvïÏ®êýímð÷Ѷ9ÓI™Õ7ÜsïÙ·ŸùÉP6B_¼éþþû¸W ¼ò°r#ö€Š;>yú„yÚþ¾Á&ŸA{ñ¯'|dÏ—o/,O“õ­|Ó·ÅeX9É×…E—TŒ¾|:=ƒ|ÍÁu"Òª¬¶Øòç6˜0º“ÞhÑãM…Ý4­þòÐqî¤PxO¯½×®Ÿ¹®)'§štò„~ÃDD<Ã._·§¥åÀâ‘M Õ Xd )3t˜³æ§÷g÷½t[oüë§^j®(›Žd©å2ˆl÷=›^~äà ÷ÜÛÜ‚²2èømU)Πs‚¬4g/ó/_{à;‰¾ ™[“© rÒgÐÏD;¨9þW.ÜÙ'÷aD‘¥ïs5·åã-°7jõm²rQNk¡z"+XM'z_|ãßzÅq’Tƒ$Ï€$9Ï”…]zÔáÜÈþµZj§^Aÿa4ܹeì“à$º<+ÏrÇ!ì µZC³†!ë,…\6RL(­ *S“),nÞëò=++ìÃk™9ª&‹‡{ÃÀ c'ۂ²yÁý~ ®»ŽÝýÎ.EÙ¹3]ú·úk¶^òØ)"$kðŒÔÆÖ}|SòÆ´ñ¯VA&ÊDäR×-p5Š"„qÑÌÁ06÷z¸2B”ÂØŒåˆˆÕ%ò Ì™â %7sjàâîùpqÏ×A˜·î[Dÿ—¨€çþ*‰Àü3D;´]RAúõ€÷&èó®t˜kàp»¸¶Rüâê;¸¼¢Yâ܇ëYaÍÀ• í/ÁÕ ´œœ50NÞ_*¬ýÜáÊ®FÑ5óI€3a‹¢‹¸™XE}𹇑;ÈÛÉ_SYT u7õ¶È+Љî½+®ÿLb”ì’Ü(ù“”’’þ)åú”7R5©C©÷¦~;õ÷iUiw¦ý4]—>›þ“ uFUÆTÆ/d²rÙ)ÙërŸ¼NÞ'¿Aþ+…Oq\ñº2_UÎ+¿ªÒ«æTשN«ÞÃRª%œÖòRüÄ_ ù-‚Æwão Ï´à“„œ8.À1Kœ`aA),Ø)À"Õ °”ø!àÂG8•¸ŽŒ ° 8óÞm!ñQF„Bü¤“„Tü=¦ˆ¨øÿ°ˆPHRX °N€%„Jâ`)1 zÂÃ)„^r—§‚Î>&À2Ô&ù+`F" ÖÊHiÀ°˜;ÉIÙ‚a î°÷Oa8Ç1ÌýºnwÊ ¼Ö0|_~]¾Í͆ý.à]ÄðÜiøŽáñ¬ã‹kRã×J†\üî9û¤?±óiÌÍEl Ð}kÛÐÚZ—£kê¸ÿß¹´Ž=¶&çY¬K¼V ¯iÊåw¿®ÇÓUºÜNø½Ìãõ’:Èáç÷ƒž}xçÓØÂ.¿SžÓƒq5.XÅ¥¶Áquæ-à'9j÷®i.‡›93þ¡ŒÎÐ~Ÿ/LwÅé¶é©éùÅ™8];=;3=;8Ÿ˜žòÒÕô–ÄèØü½%>ŸÝy»“ñ9º=¾Þ2=98µ%>º018›|¾ä’aZ/éÏÎN:äõÑî¶ÄðìôÜôÈ|î%ó7NóöãQÄc]mÝ—¢OÌуôüì`,>98;NOüÝÝЉ)zÆz¦óñÝ5?8˜§b…Ó³ô4ŒÌÒÃÓ S󳉸œ÷ï!Yëëæ¾êf÷%¦F鎑‘Äpœ.àNMÄáÑÙÄÜô”‡îM ÏúÖÁÙX|jž.ŠüýÓ ôäà"½0z€þ‘iœ£gⳓ‰y޶¡ELi}Ok5ŒÎâÆÌìtlaxžÛž±”rëÏÂ=15<±ƒGç§éXbnf€­ÁS ˜0 ³`y/M'ŸžšX¤Ý‰\:>9Ä=µŽk*9û²$áé1nϳñ9`Õ0Ç” Ëc ¸J1î¬2Ÿä88›€UcÓû¦&¦7. Dò¤‚Ö¤1½0?³0OÇâ{9æÂœ±øÄÌ%;‚˜6}À ¶.°~$íÞ úý.öüɱ¤/ñ>šºú*õ õm¸ž¤ž¢þW6ò¯lä_ÙÈ¿²‘e#ÿÿ²‘‹|ù:̵—ûåEó8»Øèåyí¿<Î ˜³¸±-²ˆŠD-¢FQ9|G/Za ðþ=,íð½s‘·ë1tÝKX¶Õ0kVðƒÿÃeáÿ¯]‚ø endstream endobj 102 0 obj 8552 endobj 100 0 obj << /Type /Font /Subtype /CIDFontType2 /BaseFont /TimesNewRomanPSMT /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> /FontDescriptor 98 0 R /CIDToGIDMap /Identity /W [0 [771 385 439 439 496 248 661 496 385 496 496 275 248 661 496 330 275 716 275 496 496 496 496 496 496 330 496 605 496 771 330 605 881 439 248 330 716 496 716 496 496 496 716 330 330 551 330 330 496 496 605 330 330 275 439 551 439 551 716 496 716 716 716 716 559 275 716 ] ] >> endobj 101 0 obj << /Length 826 >> stream /CIDInit /ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def /CMapName /Adobe-Identity-UCS def /CMapType 2 def 1 begincodespacerange <0000> endcodespacerange 2 beginbfrange <0000> <0000> <0000> <0001> <0042> [<004A> <0065> <0061> <006E> <0009> <0043> <0068> <0073> <006F> <0075> <006C> <002C> <0052> <0062> <0072> <0074> <0056> <0069> <0064> <0067> <0032> <0030> <0031> <0038> <002D> <0033> <0054> <0070> <006D> <0066> <004C> <004D> <0063> <002E> <0049> <0077> <0078> <0041> <0076> <0079> <006B> <004E> <0028> <0029> <0053> <2018> <2019> <0071> <0035> <0045> <005B> <005D> <003A> <201C> <0046> <201D> <0050> <0055> <005F> <004F> <0044> <0048> <0047> <003D> <002F> <0059> ] endbfrange endcmap CMapName currentdict /CMap defineresource pop end end endstream endobj 7 0 obj << /Type /Font /Subtype /Type0 /BaseFont /TimesNewRomanPSMT /Encoding /Identity-H /DescendantFonts [100 0 R] /ToUnicode 101 0 R>> endobj 103 0 obj << /Type /FontDescriptor /FontName /QZDAAA+Menlo-Regular /Flags 4 /FontBBox [-558.105468 -487.792968 717.773437 928.222656 ] /ItalicAngle 0 /Ascent 928.222656 /Descent -235.839843 /CapHeight 729.003906 /StemV 43.9453125 /FontFile2 104 0 R >> endobj 104 0 obj << /Length1 4300 /Length 107 0 R /Filter /FlateDecode >> stream xœ TSWòÎ{/ ~ªDi¥Ô„QÁ‰!ˆ‚ÈŸðS@T  Iˆ|E´ñ[A´ZE׺Ôu­¿î²m×¢žµk=žÚÕL[ŽÇcë¬ÛZÝãiµõC;7 ®¶îÙ}ïL˜™;¿;3wîƒ!Ä‹¼NXB²sÃÔ›~Úäœ6C¥¥©¢bç²:Äo2ò€Ùd,/»‘¶QÛiFÆè>éóHO4[ë–þ¡Kzé»H¯·T—#êTBF/E:Ùj\j'AD‡ôß‘–ÙŒVS—×þ*¤¯ÂÞ&,ç€ÍD@ˆ@#ØI¼âþË^$Ì8B˜Q¬Ç0ÜM8ôyø˜!dZ"s*’ÊI‘ 9…¾¼/ìYaÀ@àêÐUB8ƒ zC`ˆ™ßΙûp·"B|Ärq\,7sd°–õü–ß.óàÇád”làÆ }‰/™ˆ‘ˆ5b…V(*•Ábo]¤N-õ_©ŸN­‹ÔNS+EB¶ §',=³ü|m}}ݹò¬ Þ;1aíꔤ¤”ÕkY“ððv{nHèžÝàâÝ» d*?ú¢Å6k_ŸÍjµÑ7 õs©\3K& _4+A7%º{‹„J¡; ÆÜ–ŠO[;ýmÿnEssó­ïñ§™½jµõõYmnË»wtòüõíÛatî €9 áÞ`¾¢•÷‘KäÜÄÇ_3_Ä•¤kâ‰W´ -,à䯲9ì©£|ñ~¾ø#ˆÁàH÷P ç%l#¡X1 MΕ …Vã‡ñŠƒu‘„¦F*ö E~R?‰DˆIã¼âæåCLl˲eíQ:ÈÏ{—Ü6%’’?=•– ¡SÚ4›õiWÎZædw@b|+p_§§u„„nâïuÏŒÿb\üa’€ùêÀ ;°ÂRˆ!¡ ©‚ ¦Qˆb9æKŠeÃúau4ƒÌƒÌ¨ÈÜs—ÞÏŒ‰-;uº~n]ãt|³%%Ò3;˜S¾º¨ý¼šºÂUÎ ‚¾êê/Þ**a œÿš·®%)ˆ«?ú9ÖÉßÕ¹kc¸mý)9w}4è_ìngð2ÿy¡ÄVe,-äoݺyóݾÍÝ£SõëÖΛ/bÚ „7ËL/Oÿ(ÔW €½â£ÞéÚòæöÚü¼ ­4ï}è[ˆ¾ÕÔ3šWÒ6AÿR)M1¦Z‰µPjý<¬T"¬ vÄ~>'{nΊ˜XS}¤_ŸšÜÐèÈ-,ªª()ÎkJL€{^I¿OÓØ,ç rs¸éª°×'MÉI 3>+{ù»E%0Î{âÉÈ—üÕ Wª™1ô©¯w-œï-¦ÑÆ“ãÏcEð„iÄÃíûô:Ý9mɪ¤¤cÇÔ¹ùö÷róàsÔ©ïLN)*<Ì4=Þ{ 4B½ÄN­Ýâ „ãñ<À-Ò†Âæ×‰åZ9Ó aS^üþEÀ_‚«ðÖŠØY¿ƒÅUŸ°÷7SÝVì /Á"¡'[œÆ¢Ó¸;•3°—/S5ô^ï—|„öðŸt8»V„«aknÎyÆÐ±¨|7ó#TÑér1+òãuå¬ ªø_ø¹Ýèï ¬‹^p—h:²çXÎ^IÓoFÿåØ/VÎàš{ (Ê?†$Hþ˜¯¹ƒ§7=ò¸‹öÞ†Üûx7Œ¢rb”ˆÄŠÛ'aàŸüu¾tÃI¡ï`38øg2ßÂÏB=&š`n èÄœNÌÍ#€xûÒþZ„6[±:´W=¹—¢ŒF2œ®uFLlê{ØëÇŽaYW'ֱ̌M*‰Äb9ïü’3\n˜= ¼Åé D[þhKêöã™ÿ1‡iäüÁ´H{KR ôôDäåÖÊÏ£G9º§`aÑaç:ÎpÀ Ž°/¡;>ƒ³pÊŽrßbœaœyÌ&g óñ`£ ïo;ä…çºÅ´¨N]è¾Éèˆôþê$è´´ù†/5žT«a [Ö'§¤&oX™˜Ð ÿÌÌÉË1ÎÍN܆384#Ór¦oÚ3–ôô°fz¯efÑÒÛ‹*Þ¨ü7ƒ«ZaÌ / “HaîÜn¯%SÃp ¾ "íy;$táº3œÞ\ŠàMwx´b¬¦X1ÆŒ=Áÿ¼“¿\pÁ9’ùùQ¸@1x—õ~ô ÕÝ€ºŸy²òTl8Ç4Þqž`òïñ/í:'èsš™NçžÁvæö>gÕ3óù\ ö™/i"F$tu±ëŠ¢FpëaÉea‰É…Û¬sÂT)|öiÈ€”Ó`n8É?ˆÎR*w…©ÎpYƒÛX ½‹huê1Ž‘îŠ-(‚ät‹Ðqk㜬¬¬v>>|ÔÒ+W=ºõA˜³WŸ¶v>m?Øk._±/qî ìðçtøÿï ¡¯sŸ»…üî#ÜŒ‘Á( °rzºX9«`Ì}pˆÿË}øÌasÞ·8 'ÇþéQ¬á›i®¦£^'êá™ ¢: aÌPâàÓïóéŽC‚G!ôóα#¦çÇ3h“*èœ×Ò›S:ʃ”Яì¡s?:>úîœ4¹²¬c0ŒutdõÌŸç°m(Ÿ/l bWm\=+U»Ç¢Ž¿6.>>nmWgš^ŸÖ)l¸ÑãÛ›w®_»2Лžä"´ ôXp\4#RDºGuíЧ¤éwt­‰ˆ‹6Üî¸r½à‡ïúoÜè'ô›áô¶#cKÆÎ¼O\#â×À9pVÍŒçA‘•&¹^—¥§Ÿ@î1#4#¬G &„Ýížµ/N#ÜEhå.@:þÝèÆÉe„2„¸ L®™=²§=º í§ù”åÆí@!Æ"!sÉZ|·’wÉ÷eð>\‚_˜&ŒyéeDz v›ÉÖ²»Ù¹œ’KàsÛ¸¿q—¸;±@-Èsï¿ü"±¯<øÍ3–Âo|"x“7zpÿXîÁY¢Àï7ΑÈ~.À"|àÁ…È?áÁEèý¬ÇŸä–âM~BkÀ@ÍqÀzðˆK<øHH¥E¢™j>š¬g&TÛ›jª*Íu²ƒ2uxøtÙl»Ýb’¥ÙÊT²§×èb¤¬´I–gl°.ª¶UÊâægEPBC%â«êjëjLFk¨ÛÌl‹E–Ceje9¦ZSMƒ©\•i²YªsL•õc —yˆ²*¼<Â1 ª#¦†«§F„?#2,àbN}ÆHU­Ì(Ë«1–›¬ÆšÅ²êЧ¶“QUi¬«¯1Õ&T[­Õ6ٚē*RGjjˆ‰‰•è‘cÅæ2H± ¯–d⯠ñjäV!-#¥(Y‹ÜrÄë‰WlˆÕ3òd$9&'WêÑr™‹_á’«Cì·^e$±Äe6—åa{v´QŠþ«ÐŽ WªQÞˆ”훉(»È¥Ÿòªÿ鎣Ëå”ã µ[C#¯-?ÏB(rÓÐczuEC3TE*‘çÎG)æMöœ,ªp7uøÚI4 ÷Ñõª\štG&Ä«ÑO%®•yveD¬éçk–þ&:•KÓŠ2Ãy)q­Ù\qÖ¸rFíÛ¯F^½Ë~-rèzJëQ^ƒ'WîÈ­¸ÿJÁ endstream endobj 107 0 obj 3070 endobj 105 0 obj << /Type /Font /Subtype /CIDFontType2 /BaseFont /Menlo-Regular /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> /FontDescriptor 103 0 R /CIDToGIDMap /Identity /DW 597 >> endobj 106 0 obj << /Length 595 >> stream /CIDInit /ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def /CMapName /Adobe-Identity-UCS def /CMapType 2 def 1 begincodespacerange <0000> endcodespacerange 2 beginbfrange <0000> <0000> <0000> <0001> <0021> [<0064> <006F> <0009> <002D> <003E> <007B> <0052> <0065> <0073> <0075> <006C> <0074> <002C> <0053> <0061> <007D> <0076> <006B> <007C> <0072> <006E> <0045> <0067> <004D> <004B> <0079> <0050> <0068> <0041> <0056> <0066> <0028> <0029> ] endbfrange endcmap CMapName currentdict /CMap defineresource pop end end endstream endobj 10 0 obj << /Type /Font /Subtype /Type0 /BaseFont /Menlo-Regular /Encoding /Identity-H /DescendantFonts [105 0 R] /ToUnicode 106 0 R>> endobj 2 0 obj << /Type /Pages /Kids [ 5 0 R 26 0 R 45 0 R ] /Count 3 /ProcSet [/PDF /Text /ImageB /ImageC] >> endobj xref 0 108 0000000000 65535 f 0000000009 00000 n 0000047245 00000 n 0000000181 00000 n 0000000276 00000 n 0000001240 00000 n 0000028797 00000 n 0000042648 00000 n 0000019365 00000 n 0000032205 00000 n 0000047103 00000 n 0000000313 00000 n 0000000358 00000 n 0000000403 00000 n 0000000448 00000 n 0000000493 00000 n 0000000538 00000 n 0000000583 00000 n 0000000628 00000 n 0000000673 00000 n 0000000835 00000 n 0000001044 00000 n 0000001610 00000 n 0000005286 00000 n 0000001361 00000 n 0000001569 00000 n 0000005909 00000 n 0000005307 00000 n 0000005352 00000 n 0000005397 00000 n 0000005442 00000 n 0000005480 00000 n 0000005518 00000 n 0000005563 00000 n 0000005608 00000 n 0000005653 00000 n 0000005698 00000 n 0000005736 00000 n 0000005774 00000 n 0000005819 00000 n 0000005864 00000 n 0000006239 00000 n 0000009083 00000 n 0000006031 00000 n 0000006219 00000 n 0000015699 00000 n 0000009104 00000 n 0000009142 00000 n 0000009180 00000 n 0000009225 00000 n 0000009270 00000 n 0000015532 00000 n 0000009847 00000 n 0000015365 00000 n 0000009963 00000 n 0000015218 00000 n 0000010093 00000 n 0000010361 00000 n 0000010624 00000 n 0000010855 00000 n 0000011066 00000 n 0000011371 00000 n 0000011674 00000 n 0000012019 00000 n 0000012248 00000 n 0000012479 00000 n 0000012638 00000 n 0000012847 00000 n 0000013068 00000 n 0000013307 00000 n 0000013549 00000 n 0000013789 00000 n 0000014029 00000 n 0000014207 00000 n 0000014373 00000 n 0000014585 00000 n 0000014799 00000 n 0000015015 00000 n 0000015595 00000 n 0000016029 00000 n 0000017380 00000 n 0000015821 00000 n 0000016009 00000 n 0000017401 00000 n 0000017661 00000 n 0000018728 00000 n 0000018935 00000 n 0000018708 00000 n 0000019501 00000 n 0000019767 00000 n 0000027539 00000 n 0000027989 00000 n 0000027518 00000 n 0000028945 00000 n 0000029229 00000 n 0000031539 00000 n 0000031775 00000 n 0000031518 00000 n 0000032355 00000 n 0000032616 00000 n 0000041283 00000 n 0000041769 00000 n 0000041261 00000 n 0000042793 00000 n 0000043058 00000 n 0000046243 00000 n 0000046455 00000 n 0000046221 00000 n trailer << /Size 108 /Info 1 0 R /Root 78 0 R >> startxref 47357 %%EOF luerl-1.2.3/doc/pdf/luerl_sandbox.pdf0000664000175000017500000011774414677012037020117 0ustar debalancedebalance%PDF-1.4 1 0 obj << /Title (þÿluerl_sandbox\(3\)) /Creator (þÿwkhtmltopdf 0.12.6) /Producer (þÿQt 4.8.7) /CreationDate (D:20230921143529+02'00') >> endobj 3 0 obj << /Type /ExtGState /SA true /SM 0.02 /ca 1.0 /CA 1.0 /AIS false /SMask /None>> endobj 4 0 obj [/Pattern /DeviceRGB] endobj 11 0 obj [0 /XYZ 141 723.500000 0] endobj 12 0 obj [0 /XYZ 141 633.500000 0] endobj 13 0 obj [0 /XYZ 141 574.250000 0] endobj 14 0 obj [0 /XYZ 141 304.250000 0] endobj 15 0 obj [0 /XYZ 141 415.250000 0] endobj 16 0 obj [0 /XYZ 141 277.250000 0] endobj 17 0 obj [0 /XYZ 141 256.250000 0] endobj 18 0 obj [0 /XYZ 141 234.500000 0] endobj 19 0 obj [0 /XYZ 141 172.250000 0] endobj 20 0 obj [0 /XYZ 141 151.250000 0] endobj 21 0 obj [0 /XYZ 141 129.500000 0] endobj 22 0 obj << /Type /Annot /Subtype /Link /Rect [365.250000 443 395.250000 452 ] /Border [0 0 0] /A << /Type /Action /S /URI /URI (https://lua.org) >> >> endobj 23 0 obj << /Type /Annot /Subtype /Link /Rect [167.250000 434 181.500000 443 ] /Border [0 0 0] /A << /Type /Action /S /URI /URI (https://www.lua.org/manual/5.3/manual.html#3.3.2) >> >> endobj 24 0 obj << /Type /Annot /Subtype /Link /Rect [252 434 309.750000 443 ] /Border [0 0 0] /A << /Type /Action /S /URI /URI (https://www.lua.org/manual/5.3/manual.html) >> >> endobj 5 0 obj << /Type /Page /Parent 2 0 R /Contents 25 0 R /Resources 27 0 R /Annots 28 0 R /MediaBox [0 0 595 842] >> endobj 27 0 obj << /ColorSpace << /PCSp 4 0 R /CSp /DeviceRGB /CSpg /DeviceGray >> /ExtGState << /GSa 3 0 R >> /Pattern << >> /Font << /F6 6 0 R /F7 7 0 R /F8 8 0 R /F9 9 0 R /F10 10 0 R >> /XObject << >> >> endobj 28 0 obj [ 22 0 R 23 0 R 24 0 R ] endobj 25 0 obj << /Length 26 0 R /Filter /FlateDecode >> stream xœí]MÜ6½÷¯ÐyË"õ ,ÌŒÇ ìacØCCàl²â`ò÷WjI=’JbU“»­ñxZj‰,««‹ïÿñòcôËŸÑû§—ÿEŸûŸO/§$.ó¤û/jÿ¼P'Q™ëèó—Ó×èëéÓéSó÷ð³½ùË)ÏÓ¸½U©æ×߯¿VU§ZéZ5Ÿ'ó_Û›ÿ{ú÷ߢߛmJâºÖ*/ªBÃÿùù÷Óû®/Í7“¸J]ÕYÓÊsûg¿7-oÍ[•RIôÇN?·í·ûê[»T¢ê")« þ{Ü.›û_žþÕ4í¯HGÿlþÿ5úþ‡æ?M„Á{éãëéýÇ"ÒEôús¤º±ì~¼~9é\EïJ½þý½žï¢×_Oe¬Uuìö¦îŠ>_QYœå©ÒùèJÚ]Qqwat%ƒWð{òî;éÛ'E÷IÛ½:-Ço.ɽle ¯<À+äùOä“çOª¸È =íÉ3¹÷ãù“ç×FÍöÓ„2RÙ’&¤‰Ž»ùÝ|˜”Ó‘ª›)ZÍÆ°Óˆr®å|ü‹X'óñïF9[Z7Úi\õÆf>Úi¬Ó¬Uƒd>êu¬ûÇÍG}éi¸ónà‡<Îo} z„Óf®«´œªn9רr®Üe`ŒlYUDï´l™JºùWÅe7Æ»¡:-×*&”†Ðc4¢ççå´Ç ŠÚ÷ﺩixüܨNjyÜÍÔñ­øÅd2‘‰H yo>¿c0#(ÓßZ@€¿Sön«ìl¡AÀª‚ýÄbkçÂÂ7t§†" ïÃæ?>%`p+zè=žÕÄyžm¸Iø=Šè ¾ÕÞŠÆÑ¡’ìmR=3K(bÒ~‚,aG¦îcéiÔßåðùðͽÁ, YTù0¦6«,Ø6,¯ÞÚ.­'(†Çk„"}3ùú4/†?AëC@ž¥e.@‡•Ò“×k+ê–û–s%Ææ|É·§+¾xá¥[ƒÆ‘ªLÆ¢68½ùÁà°kþçã`E‰%‘¸Éú;Wè¸$Ø ·š?YØËðb·"Æ]'€ ãPÜA‰Pì›ÅãQbè~)ª‡á¸JÝ8Ø_2Øäñx)¢ìì±ÖP ÖƒBt°¡)¡ƒ-Ÿaàa0Üz,slº°Yu;³É’ i Q1Vo†eth^AgÔWê¡­ J c ”?}ñ{ú…ä’W¯`Û*Ô6ü’ú¯„+«&C)˜û¢E» ŽpU|f/Ã(A¢†+Ø>¹0Œȃ›DpFËöà‹ŽèF£âVe ŽŒôx/PÎ5a¦õP+P«×ú¯,ŒžÎ­¡b«õY(ÓÙ‹Ããø}¸Çsãj˜DÕe„Ð7Zù1AoÉr_b¡s2$Í$ÒÁNPâˬh½¤Š0è…(â!YÙ⸋$'MŽI4öKçpœ7ñð¨¸À‰·&\•–£3P5öyöŽS·v»ŽPAç ΈNUH €ßÉJ‡õìõRöð¦Ã°"Tí"<ϱ[Ü-²òNL)í2ÂÌ~P‡gßQ"qñ ]†…cׯF0ÛtK„Ä€2žuLÂÒÅM’¬œÀU†mðBÇrë$¹›Õ˜^Ș&Í eø§|ÇQnM´4·iKf<ÇR; £ÇÀ †™H°xIÄXWIÂû ø³›.3À=Á ð& XK„ƒÌ7¢A$pÍk1œå-BÞ­€Ø²Y%Þ踜sdqV†i«Ãbžð ×Ò!#‹ÜB_æ ? I’/5GI ŒlÃäIʈ{¹Í||¤ßla8KgŽ&Ã$¬“p¡SÖ«ž“Ôù˜tgÛZEJ/îg-³‰q]Û¼¨‹H«jÒ˜V÷’íu8סá¼ýáÐFó+|&Uui+Ül@›ÛÝöZ.Škm ”ì­Šj<Æý?ƒ½_`{c8fa?Ãï½#R«|,.ƒãÄ©*IPÊsä`·HÓ 6'¬oFØ C!ýÅç–Tî"^,Ú#éÙû2Xú˜“Œ#Ö’iŵ},í2ϲd.û½ªÄ-êÇãí}§§¦±¾ ì¢t²±‘\‘ºÂ9Ö—mó$¸%Y»Ù‡QÑIIÙ «’Ø8ÉnĽ¸U~8ág©ž\³ͯõu2 û›pφÚíB÷Õ,ønÐO?A€·ÑFFß®p]ö«sTè[Tt`ÑqÂqÚÊíÓˆp[•Ö% ÛªI„ÉÆ8¹Ò«ÊÀg€õÜHT“´DHóË(1d)n* ½ k•Þw‚e¶©Ùç˜Öì6+R‡­wE»¹î(àÜX–×c?f O3†iN ãH 0ŸYâST|m?s5Œq{:@2ùà·ÓK€£Ó6r4:’²ï»ØW0/Ég„Y«ÕõeÏ¢=bczÍê2 P)]…ä¸ÜÁƒ;Ò¶1×õ›Qy:þ L;Ò6r,ÙÝ$ÃpR f‘á;N1»ç#úã|îã°ÙüÖ°ç¾në¿^9÷o‰Þåy9CÛ$ûâ c;€Øeø†±mäHíÂà_‘^d›ž1D¥§¦Fé!0N4ˆ^éÃ9õå­·ïäðJÑ£ jú¢² U×ñ{:=,ãN —Œ·"1Ø ö~§Ç@¼÷ô•Ú•Å›Ãà%™jvª˜jõBÝrIÅÌ„Áæšõ¬t9–’h#¢žiøöá¯4A`EtÏ7‰rû-ín’UNK[9Ør²1J/në ”š­RšŽÅu/VéŠ2•¢£úüä œg:Ôº•§fXB ôCS ߨf—8ã7}¤ŒšÈâþ-©çØÓþ1Ï5×会g@‚jy>™kg7:‘u‘YNäÝgÍq$Ïm{Îb¨À¥S¤ ÿØ›˜@§•RÙ¸Ç÷ï%%§U) ûTæxW\0ºì×)¢’áŒB×pìtFXJ2ÑnÀ¨¾mÏ`ÿàQ°;ïÚ2§ÕXl÷b™ï+2-)õîøœ?v8*P+¡ËrAß­" ñ­Ôpï\ÂNùT¥vS^-tr”*`ìpóSŽ‘AÑwЏ8ÁO¿Áq {É>v‰È%—  ÊîV­ÊñBšð:S|<­Cúo òŒ$/{Ê÷®Ð´Ù˜‡ïKEÏÖ»Þ‡í¦Ï9…·ß2ßëð»ýª€^Qx2Ä£_6î¨ïDøÖÅ›?7> c+NQ8Çå…âÆ0±¶,.õjºÑQ)MÌtj¿DÅUL¬ýæ)ªU’N{Ì"¢z9º9ºdVi„qݹZ›§mCÖÀ 3dEIë`¥¯{ÊR”݆֠»C¼%)ç¤ðá;$™­™¬†ÞØc k¨Ã˜?&°,a½ÇÃ^Ü¢½(ó`ìÅ~Ãô5ç˜áÇ<e›~µÚš;ÊÈ&ÇÛÄ·:ïÎEÊÂPäV°Â¼Š€A¶éÁüx!'¹Ç,7?… ©ý€ü­â(ûËm³úv$YˆÏ8J“q,™$ãè—^a±1ŽÔc°(êã·l˜ïગÓ7@ð¬õrX¯·ºñö%-E´A­™•¾dRíkáÌ&Œ%z²ÕÁ­{2'‡spNÂÅÓKb]L<7¹ís³IYâ5l¹³…iVgà\ºŒwÜk¹.«õn ÊN9ίQÈYymMpä5ìúË ŽnÝ=§ÛŸn“ǹšmCÓ—(9±0QkÈ^c…Ix¬nŒze¯ìu¿GtAÄŽÕ¥aÀ°MÉú§Õ¹e@*‹ë>ÌpÕ8‰ôŽÌA¬ˆ¤õpfã ƒ`rÍײõ1>üÆ-ù‚†ñnÊÞîðv‡·;¼o—[Œñáí¾Eo×½x‰¯‹Ù¿ds3 da"þ-ëÃ#›ÔàðȇG><²,?§’jØÙ‚ëñ2’Ά(¶:én,wFÅ#û´Ÿ¤ÈN¸ih«$”ýÞr' øÏ§õsdGè®4››Ëf/Kê^y‚W>À+Ï! 2«Ú vcy¹(ẎÔÅõ:"aß]§*Kµ¥&p¬¼€›*"œƒ[Ø9Ê‘@§à(7ß[ÇSCDß:8gN9g7Kó×¹šÌ´áÌag#€gx%h–½®Ê©TB¦Ù ¦kk{½®x©ùf°ýŒ¦1ö£ÌKÜ:v`xˆ“MÌŒÓÝìwšÆ^¸íß°¯ö+B8à,´B±‘³5oþD_Üœ)°ÛŸ¢O§ÿ£=(‡ endstream endobj 26 0 obj 3325 endobj 30 0 obj [1 /XYZ 141 668 0] endobj 31 0 obj [1 /XYZ 141 646.250000 0] endobj 32 0 obj [1 /XYZ 141 624.500000 0] endobj 33 0 obj [1 /XYZ 141 602.750000 0] endobj 34 0 obj [1 /XYZ 141 581 0] endobj 35 0 obj << /__WKANCHOR_2 11 0 R /__WKANCHOR_o 30 0 R /__WKANCHOR_4 12 0 R /__WKANCHOR_q 31 0 R /__WKANCHOR_6 13 0 R /__WKANCHOR_a 14 0 R /__WKANCHOR_s 32 0 R /__WKANCHOR_8 15 0 R /__WKANCHOR_c 16 0 R /__WKANCHOR_u 33 0 R /__WKANCHOR_e 17 0 R /__WKANCHOR_w 34 0 R /__WKANCHOR_g 18 0 R /__WKANCHOR_i 19 0 R /__WKANCHOR_k 20 0 R /__WKANCHOR_m 21 0 R >> endobj 37 0 obj <> endobj 38 0 obj <> endobj 40 0 obj <> endobj 42 0 obj < State.) /Parent 41 0 R /Dest /__WKANCHOR_c /Count 0 /Next 43 0 R >> endobj 43 0 obj < State.) /Parent 41 0 R /Dest /__WKANCHOR_e /Count 0 /Next 44 0 R /Prev 42 0 R >> endobj 44 0 obj < State.) /Parent 41 0 R /Dest /__WKANCHOR_g /Count 0 /Next 45 0 R /Prev 43 0 R >> endobj 45 0 obj < {Result, State} | {error, Reason}.) /Parent 41 0 R /Dest /__WKANCHOR_i /Count 0 /Next 46 0 R /Prev 44 0 R >> endobj 46 0 obj < {Result, State} | {error, Reason}.) /Parent 41 0 R /Dest /__WKANCHOR_k /Count 0 /Next 47 0 R /Prev 45 0 R >> endobj 47 0 obj < {Result, State} | {error, Reason}.) /Parent 41 0 R /Dest /__WKANCHOR_m /Count 0 /Next 48 0 R /Prev 46 0 R >> endobj 48 0 obj < {Result, State} | {error, Reason}.) /Parent 41 0 R /Dest /__WKANCHOR_o /Count 0 /Next 49 0 R /Prev 47 0 R >> endobj 49 0 obj < {Result, State} | {error, Reason}.) /Parent 41 0 R /Dest /__WKANCHOR_q /Count 0 /Next 50 0 R /Prev 48 0 R >> endobj 50 0 obj < {Result, State} | {error, Reason}.) /Parent 41 0 R /Dest /__WKANCHOR_s /Count 0 /Next 51 0 R /Prev 49 0 R >> endobj 51 0 obj < {Result, State} | {error, Reason}.) /Parent 41 0 R /Dest /__WKANCHOR_u /Count 0 /Next 52 0 R /Prev 50 0 R >> endobj 52 0 obj < {Result, State} | {error, Reason}.) /Parent 41 0 R /Dest /__WKANCHOR_w /Count 0 /Prev 51 0 R >> endobj 41 0 obj <> endobj 39 0 obj <> endobj 36 0 obj <> endobj 53 0 obj << /Type /Catalog /Pages 2 0 R /Outlines 36 0 R /PageMode /UseOutlines /Dests 35 0 R >> endobj 29 0 obj << /Type /Page /Parent 2 0 R /Contents 54 0 R /Resources 56 0 R /Annots 57 0 R /MediaBox [0 0 595 842] >> endobj 56 0 obj << /ColorSpace << /PCSp 4 0 R /CSp /DeviceRGB /CSpg /DeviceGray >> /ExtGState << /GSa 3 0 R >> /Pattern << >> /Font << /F7 7 0 R /F10 10 0 R /F6 6 0 R >> /XObject << >> >> endobj 57 0 obj [ ] endobj 54 0 obj << /Length 55 0 R /Filter /FlateDecode >> stream xœí]QoÛ6~ׯàó€*ä‘’H`(8É€= b`ņdíP4Ų>ìïO¶¤XýÑ-É´ÃmbQ¤wßÝ}”ÄÓÕ/²/?ØÕêñöTÿ\=&<-2^ýa›¿Ú gEFìé%ye¯ÉCòPþÿšT'>®~+ûûµü÷•}ú£<ø\Ÿ´9á%É2™nÆ¢üø­ýQkJdDyœ÷?nNþ;ùý'ö}óm©æœ´Q¥ Ûoî|þÐêZŠy@´×¤™>O!‘å:'øû§ïÉU¥¶ñr!8ËËOJû÷¯äóF3OgRMç:Õ¤´!ÍH•½u®eV­´Le¡4™öñoíã9O9‰‚kSoƒŽwÆ™ÅÐ5PCÕõÔ¨v¢TTÏ­ +¸09/´‚¿·ƒîóÁW¾zéÍ:¹º/˜Plý™‰*'V?Ö/‰ÎË‚ˆ­ŸÙÏ¥yÌG¶þš¨4ÏrʪZµðªE¦ºÎ¦»µmÉSâRl:½µû\o[ŠÝ©r{àn]Z*ú3¥7î\=(KB!£2])‰ I;ØØB¨…Ö„ûZ­€-+Ù2Ø·ä°ÊæMO©7í3±vL+|„Šç¸|†‹ñ:d Þ4 èÃs8Ze±,U²?”Ú1Úmoѯ8†¿é_9ýXr¸¼‚E£¾$øj 1ÖºšbéDþÐ\Àô'jÅ8ϯ?¼5ázÔP9©TÅŒÑs–Ev ÑS=0zv> =ø &£Õv>DZóÁyIÕ—þîàìs0V:<ÏF<]{ÄÈ™SŒGHt$i%°B¯G&±ZØ@}¾¢žT,c}ð±UpÒÆIÔJj«ÞÊ iÃNwBe]‹]æ?Pw!Á»Ú÷a\>,ÔÃ¥D?Ua‘H6Vp³ÇáI#(º•+ƒáÃÓ$™ƒ¥¥> KõxM‚F’†GgH×#"ýé¨Ö´aÛü6Æ2ÎâwuÜ?q¤ÎÄ&—‡ Ø$ÃB‹žWiØr Á}úÔN4*ì×n¼Ï`\+W7ÄõïBP,¼AÔÕ×$¼%lŒH%ŽÇ.´‚û„]‚¥("aL”_h+úÜK‚³.-ãÈñÇðU«ê–ÅG²áÐ#¿ym:ö0¾ƒÆ-´ GÎ$c6Ý5ˆ&¹0çU¸ Ý…rœqú¥±ÅÚðð#¤}.T@Üt!Ë^úV¥ÉyG“±ìe,{y,Ë‹e/ÃŽžªèùüBoƒpTûÂ+ö T‰¢gFb`ô|÷e/µà–ëfüí ±ðæ¨ÛÅ—]x3€J`á\8>Û²—TÈŽs\Z¿~§;¼XšøËíª¥•XŽÒAc9Ê£,{Ö7E/²e Q©¢coï½|Wu0·:ˆ¯×d˼ËgÙW=-hÛ0¦†CÞ#Ï’ÿ½q endstream endobj 55 0 obj 1725 endobj 58 0 obj << /Type /FontDescriptor /FontName /QGCAAA+Menlo-Bold /Flags 4 /FontBBox [-445.800781 -517.578125 731.445312 928.222656 ] /ItalicAngle 0 /Ascent 928.222656 /Descent -235.839843 /CapHeight 729.980468 /StemV 43.9453125 /FontFile2 59 0 R >> endobj 59 0 obj << /Length1 1564 /Length 62 0 R /Filter /FlateDecode >> stream xœ…SMle~¿™ÙšâÖB£Hóm [$ívw m’†EKhÛ¦&^ØÙÝÙ-;?™™í1¦Ñ Ï$’@41FŒ'o$œ´"zâ`£¨hbÄPvy¾ÙÙRÒ&Îä›}Þç}ßçýù²Äˆh­L”ŸÍ^è¿ùÌ8…j}¹òYëÛOÿĹaèZ¹tR'b_À3@tM4°ïÃ>`˜þR·C?I;`wÕí’FÔ€Ý+ª˜Ú’CQ‚ýlni¦ÞÏÖoÁ>A$ÿL²²&]£QäHäC¨ö·å;T‘zµKÉQE’”ßi u›þz•C8t¶òZ™8ñÖãho³—]RMökؽ‰{DJ!rGTÑÈh^TŒÈ'˜V%z>žˆLĆBëž¼oý·æEµûáßnôeÂVšo+k­œØKdO⨲öhôúê*š"¿õ‹2y@aÄ&âQ5:¨ %ãÒøX"Û··/žJ¨ÑxoßÞñìø˜lÜd·ætÃoÞ½|…}|…¥Þzsnj"ÿFáêôÌÙü¥‘ÁÖÍö?|<{ú@’ýð=óØÒêw/¼˜n~•?|èÝ•ý÷Þû,¦Š®Ä¹ûÍê¹Ý'þ·õ}£;†Mwä¨fsÇT֥ͬÜ&‡p<Ø{po… J¦$öªlyvÓ×üâF Ã.†X"…Þ ±Œ[X ±B;é£G0Èç!Ž‚ÿ2Ä*º¸ÖÆøÄè§3zŽþ€SbÈì¡C£ ñNö:Ûâ]tL*…¸‹.H—OÙβ[«>¿Ê³éô+ü¤ãÔu>i•R|³O8Çxq™Ïj æ¼mUyN3ž AÄ‘«ùžïêš9Ü–9Y¯óiãñiÝÓݽœšÒ­º³ëåpŽóÌx*]Îè™ãÊfFÒÙ‘Lú©¿ã ˜‘§¹5k|ÖÕʺ©¹ç¹]Ù4™ZUó®î²MÓ¶ø†M9ª‘ öÉ%42é4×r†–©Σ)|-`l 6§""=°â/Ö  È'§<=`fài@¹ð• ÎÚZ•Ó Ìq¬@¹£ç@£ˆú5èpxlÄk°¬g4_Eì|?‡øÔÿViO¢uS†Gèºtœ åí†ÁN¢b †ƒnĆjT×ÞG{ãÛl1…i|¼£Q¼‹Á› 2ÅD:°:UøJáT{ûÌâ–îRA¦‰˜Î^Î>+èÓ v&ô`\#Ð÷Àÿ¢;y‚[wÕîÜÄOçÎ=ù endstream endobj 62 0 obj 956 endobj 60 0 obj << /Type /Font /Subtype /CIDFontType2 /BaseFont /Menlo-Bold /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> /FontDescriptor 58 0 R /CIDToGIDMap /Identity /DW 597 >> endobj 61 0 obj << /Length 378 >> stream /CIDInit /ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def /CMapName /Adobe-Identity-UCS def /CMapType 2 def 1 begincodespacerange <0000> endcodespacerange 2 beginbfrange <0000> <0000> <0000> <0001> <0002> [<005F> <0047> ] endbfrange endcmap CMapName currentdict /CMap defineresource pop end end endstream endobj 8 0 obj << /Type /Font /Subtype /Type0 /BaseFont /Menlo-Bold /Encoding /Identity-H /DescendantFonts [60 0 R] /ToUnicode 61 0 R>> endobj 63 0 obj << /Type /FontDescriptor /FontName /QLCAAA+TimesNewRomanPS-BoldMT /Flags 4 /FontBBox [-558.105468 -441.406250 2000 891.113281 ] /ItalicAngle 0 /Ascent 891.113281 /Descent -216.308593 /CapHeight 662.109375 /StemV 95.2148437 /FontFile2 64 0 R >> endobj 64 0 obj << /Length1 13404 /Length 67 0 R /Filter /FlateDecode >> stream xœíyix[×uà½+Á±\vnA¬$Á$HŠ‹Hq“EIA A‘ ‚’(y‹­8ª¼Åª,/I>ËòîLât’:q'nl%ÍØ3nã¦vÚ4­'ýò5ní©=uêŒÄÇ9÷â¤d¹t¾üè‹Þ;÷ÞsÏ=û9÷ a„ÝŠ ŽÔzµ{&»à79»°–ðÜr`àEÈxã\<6“˜ëùB¦9˜ ÎÁDÑÛÜ1Ÿ‡±mn1sì•Á³0þŒ_YHMÇž~çÂB%„^b1vlÑ$ŒÿÆìRl1žtÿQ%B¥j„t=H ˜g¾‹DH*zXäCÛ³oÁy”`бˆa¤‰HÄ„¿@Uÿç%t¬¨äÁt°þ6.‹s]Ø'1ãÿцðÆÆì~JÔONCBÄà„D%"˜D„ÌJ³Ò\"D—YÁK—ÛDèb…/ÁѨ!Æ;‹a Të´:9 CJ‡Óá àoê´œ¤¹\…±Võ_:2m*Ølت¼+5Šì„JëÆ¯„u‚§PÕ6*b‰Ø)"Ž€ÒOh™•bXÐú´„:¼¦Vµp·wF:‡‡šZ4•¦ß„óó4ª[iE= O­Û &‰í¦!›c¯§½í1¼2o4äÙ×?/)•˱Ú0„ÿÎ íÞø•à àûÈ€[æÜq:àÅ ¼¡ &%D8‡Õ"k4‚ƒëySao]½e`ÿµ¿žÇ·Þüì=ÉÙw±¢Ø®µØ0þðÏF°Õ¼Wû¥¶vüèç¾÷›»Nã•Õ ç›Ãl±oâa+è Ô½g{àd Q¡W§Õl*FŽÓQ%ðZP-=¿z »«=d5ãr³;àtJò Ê •ci^ÛÀIšt,É/V× žzã>[¬­D#V³H¬µ¶Leþ¶¾Aa*(bl6aYÉqF4¨3‚qðÆ»\—PŽJ<_`Ö˜UBÇ¥¿ç^½8Þ³ñ+æ à¸8VYsQSµ5aØiöÄ«€¨Íç–ý”cGÀªôfçBÌY¹¥¥­£­ª¤T]~ökÝΊ®ž±ÎT¹Ì¬5+,5CݵlYYùìC®Hß®{ú»MÊâ|™Að2÷òÝ¿©Ôj2TNÇ;»Çv÷õUTâ*Æuxèd$RVRí±Zzæë‡§ïÛk—K%V°òoß-hBvÊ#aÇÈj“è™h°ÂR–à ¥£ÎIœB—N)ÎÊìó2»¾zj?p`?bYa9[Ñ^eÄ¥vls4¶VÕà††Dbéó»ûõ…X$ÌÏ+2””ùü¡Ž!—Kv¼Ñi6¸êN?ˆ¾¡ù½£÷^Ÿ,5i fJŠõšò§×luØý=‘6›ãPC¤êîþvy±DŠú^³;lçpC÷ž`¨Öb»t!$ |Þœ'e ²-<³!EìuEÌÒ¨ÂßìojR+Hx9ýzE^žFgØ»K­ pÎF£ÓÈZÛM¸©óõ5\àÎ.’ ³‰†i|~¥¬L©8Áå'KJÅ0ÇjE6À²&ŒB¾°¡@.Öá|Q.ÚI„ecL—eÑP9¬b‰8çX!oHðc±D¯­çV»Cõ]ßš¥˜˜‹üá¼½>ò…¾y‡Î¡Õ nmåu»!ç¼¶¤2+”óÀÙñr‰Go{ñcGZš±ÁÔ†óºy!®Z¿ã¬bÏÿÉØ¸]O^«7þIh^KiL*sz¤ŽM<Ã)±æ˜ä% o¦>nµàçŽÜuh|Ìãin‰ÏÞ6Ðnø’E’¯ÖyñI±Ìaoò:¬F}Ðõ¯¯¯]gçN=|ãÍm½>>1¤.)*dìës“·Z¬¥%{ÇÞþÉžFà¬òÔ·ÁÂJU{)[¹îªÛ®0’À‚*Ê'æÖæçêƒxæÄOÞ¸!½ºòºÏæÉìÖZW™£H…Uj›QðýÖ¶•ÌéW>ßöû¯ž;Û…íËéÿuø`·2†ÑÜr=¶<ÓÞZª!™»²ÂÏ!s·“°•™BHB¹@Òú`’h&$ Ê2k$öÄL·ß;téw¸·~ô[ g+Í¡УJ †ˆ,'ïãÔ•ø·™ÏBY'£iqmº¦Ú\Ž›Zöݳ÷ܰ|úîû«j&V[šú·ñµÝ f¶Æ\ª˜šßôãÉó´Õ\ZnlnnÄg ŸÅcã+}ÑnãðèÍoœ½¿¡¢Õ q¡tp(Ü8qju85€äû²’«²œ*YÇ^TŒDl˜õv8=Õ5}ï?ý$ÆO>Í%ÜÑö‰»žÃaì|â±xWÀ»çw—¸¹—>üˆè²tãmÑ;`R¦$¼Å¥•F‹Ï—K;|qÌW°¥n¿´·¤L¡´\>ôw±\ùrM5.­a-Í¢þËßfº×j°Ý^ (vVºô€0yù‘ŠJ°ªËµ xÑ| hG½Œx"dŒÏ¤Öèr©år¡øŠlø‰ |š|µ¿£mp_K³y°o×Ðd¸A§%é²´ÁT,ƒ(/©©®q)µ®Ä©ÓJ%²|­ÞTÉzü§l3‡ž±š«ªÇöUVàjwGô÷¹l"V§ð™­¥¢œmåd ƒƒ4M*…Q7‚ÏÜ–«Š5l/'›.g¯J±˜dæ=мjpL=‰ïÇV+Xo%øRƼ·v5Ú r(š²|³µÞÅü…+l3Êó dVsƒÝn×Zõ Á³&ƒF£"‹>qùdÒ`T©á4ÇÆÿeÎ ×!GB†ôi¬çDC}¥³ÀjUŒÏ;©Ñ]W»„ðXeQCx¡é‚[ÿ“±½ui}ïË-Í\ŒºÁU.Â8Õ1ÉIÝ0VÑ’#K¶Nix;‘L§ºÆ}ÁÑæv¹j[Ûk\®š¿¼òî°›oo­uqáuÓÖM‚±LånoD… r“ììýüº¨Ðw©ÿª(ø›p6 ¬†ÉzzþZüœíšáp~®¤¬0ÏaÙó(ð0¿ñs¡|¶ûZ}1¯q®Õ„ÂÇß3r½ñöþ˜¿.æW–-§OÎ66iJÚÝ_}odøäÿ»½¾qÌSn*)-¶Û«o¹ñLª3b0ú·¿°gOuÍÑ#ÏGZÜÑ“AQT÷½¦g’³Áú.·¥Öm=2›üüW×N€¯Û@½*Mƒ~ºœÆ-Í{<.WeEûD{ëÐà¡ é´¢°ÜŒ•òbͯoü_\k–oY“tm!ˆBÕUc<Þéõx¼Q—\¼:£^OÝæHpqk% xëéºíã:Doo‹ö‚k‰gSoµlë(ˆÝ4¹>,[8ƒ¹;FH´×Yslí[“‡=­¸Ö=ûÊ- É£é7=þ÷O=;q 1óõÿvñžóûå­4Sõ©ÞÕ»úàw¾}ö\ÿ@}èôê1pïøã^xù¹¯ONâf›^KŒvÖõ¹hÛ¬&ºOQMr½u{[ôºÖf­ “Jà¨3“æÚXiwVËUaÎÁ—è 5×¹:oGçyîéÖ&1øÑ•ò’b…©´“Ëë­šý žÏeÿNàðŽ‡¹f4×_IrZ¶»H4çðåŸv(Z]+~¬Éå¾-ñ'æWZ®€ù…&µª•+ÝdñòÉ7ÛÊJJLÅÅRh¢ ¦[f¸?ÿ ‚²  HÛŠåá§³ŒogüÈÉõ ¡Í„J„ÜÉGâyÀ¼umÑeÛm/[H±?W 3èº×ÿ%—ð©:ß®ñÄø(´ ®Ú±½óÞÐØtÐêop´%Úqï2  S°hc‚ŸÑ„q¢‡ucÜÖžÎÜ~oæhS ¶ž8Þ0ú¯ïO4b|pj‚lrhÓ‚|ù4s·n’M¼[Ê¥`³üñ ”ÉÕh.—çårÊ¡îÿÖ¡ƒîÚžÞë'O·Ü6!•¨M¾'÷nOì²cu1«Iæ2Kdø±Çtï±ãCî:CpãÒ[£*už<ý0´—¢/¯¹ÊÉ×™ê QåÏC*%æ¹±g-œsFÐgV•À¢(»@%(5J¨M¹[ Üûòîåro¯´š‹ ‹,ÖÌ鞊Շ0îêYÿå=u-¶HÇ}—š‚ƒQ2®võ0?rµøâC3DZ½XQZ²$X^,+Q*°WT œê(fË¡çÜn(+Ãëïìæ¼AS)¶Y¢#×ô••‘Sr]‚wáF¾!Â[—pU•*Û@óÞŒ™mt>·ÒðÇp?Ž–›Ýø}¯Jí=¿ØˆõÆfÜP[RÖÁ}¯ëšñàÐ@[Ê`©D¡7UÌŸ~Åf+?V(õŽeî 6=¶é´ŒÝ.*c¿±ÞÇ]nõ¸;v¸™°NY~iÕ9âÍiÂ'¨ Ü›7ÚÜ…g›„9G(7“½•©,*´Z\¡ëAl½õ–á‘{§~mV®uD"·1 îÔé‰íWëuvîË'¯?dÖ3®?ÏàÞžÏuwñ]xx"·2¼]`b,áoª×l ù_‘5cøgzýMë-jÞϽê-È·ZúÖG¯*˜E¡^àÿHVëÆewEÕ}ÐT}õfk·‹åEºª þBwÏaƒ±X¯î*±ªÈlLpø1Ÿ]'•æHâÅ)fi!_Ÿ°9`fÖÖ_`ºqêGˆvº/…w"1ÜZ°0®v^ú®`àò7…wrÃ\óxïÌ}P¹žÂ~¨\«[]Q™°ÿã•è'Üif´©‚s”[„˜ï®~‚ϸ"Z½¬‹¤F}‹;-¾XU(7”Ìü¿c…v…Ò4áº0é „†OùÈm\—ÄþÑÏ`¥ü¼ Û¯ã\Wv­ÖkUŠ l¬³¢Ãy}Z56ìZo$fPÈðÔéæë´Q?wß-õ!sñ¥w¶÷fBmãžs8E¤éàNã7³Ò`¥™Ïi!ÞO­ü&·äŠè´2,ÌÓ»]¢þßµ8 Q0㢂É"‹J+÷~ûHޤwÆ€ŸVèÜ7ˆÜçËÄJÐ/‹ J«ÃÕ5Þºž±–f×mö[pë Ó£Ö‡®í§]e,Ik-_ûë¡eìŒ~îé[fç\.«ùÐí8àÏÜÑÔ„oXþÆÁÞ°³üÍ WV¸ØÆpÂÜn|üΡA¹)X/øò’×jŒ÷ôUT‰pIy…]«cÜí'Ç;»Yð,£¾¦ÚãrXméh{[]ÝÐàü©ÄLKcø;÷‡êq}è‘ÿñ\z+X¿¿¢ ;leY¾Œèü n’y¼¨‰ÿBA$áËßZRiušlI¿¦ÑôÃ{à¿e™×ãn^_QÙ\¹±~—Ã\ÕÖÌYû¸k1«ÅÐxLN‚M´,v:ÃÝAÑa—Úhïêìꩳ‚L¾hWsÓ«»º}U-SW;Ð×=v]÷`}PÙ,7ŽtŒimë쨪TË!K’¾ü§àuÕ¨þ?Ë’[g[,ào5ÔX [T`µ\ïÝ–/ü6îéYˆÞˆ»ÚL!nŒëÛ×pg´³ÒÙÓ{ž™çN^3uZ¬N<k)çû´,cg晇ֿnÔwF?Ü· ƒ®÷sSÌ¢Eòu›÷ïÜçIªRš<²i2Ìqí§ø.UÃwû§= k\Y1à_½)ÔG?¢é]®YëÌÁýw¹Î뙚‚„£+ÃöŠÆpWˆ›r|‘öøto´»Ëka_4Ú†qdèX<ž¾îÎcûº†BõòfeCx¸sìXs$ÒYY¥’g3#’ŒE¾ÌãÝy¶%lÝf >l¯‚×ñ2SQÓd3åçˬ–†šõ&‘´¿þ‘~ýßD…5Õ9O‘ËéT« 0©k}5S…ÿJp3\ŽÌ†™Ë·]qI|÷RµðµËѸÖ[…QÊì€`bÖhP«HKøGýBÿ ‡äM’ÿt»ú߯»\¤[<ñæ$쑘¹(Ú›Jæ(¥íÿ¼âlbP•0Zw¡Aøõ ÑÆ{‚4$Dh?ÌGá7¿*êežE{àÍÂÛ ú!*?‹ú¿ÆvøµÝ þ¹ mѲÃþyX{ð‡xšðsÀØë„¶ðýâØó,ªÞ ôšøM|=8½G`®pûôìµÃ{Br±-Ò@݈þ ‹± §ðÏs;óº@#8!xLð‘Ð,Œ ßiDQÑÑ›¢7Å6ñAñ#’|IDr—䥵ғÒ7òZòÎåýB•Èæd_=#{^ö^~q~kþk•·ü¢°%«SäE‡HÍâGWÿ¼ƒ¿>OŸŠYFGfÀ€§xX€ÐyXˆ*Ðe¡2lãa1ªÁ– ¿ÂK<,E¦‰‡óÐÌ23lòÝÅÃÉE/ó0ƒ„¢×yX€‚¢7xXˆÔb‹\\ÆÃb¤»xX‚fÅ<,Ez°ÎCâ‹<\ˆ$" Œ…8«H:ÌÃBä–NRXó2é=<,DUÒ),†y±ô" ‘Cú …%DoÒ÷xt%ý-…¥0_WÆÃBT“WEaò¿»óyã< úÏ{‰‡NÞ[< úÏû5MÙ0ƒþeÇyô/{‡Aÿ²ð0è?ÿ ƒþó/ò0è¿ ‡Â2"{Ñ/yd/ú7 çÃ|±¼Œ‡…È+÷P¸€ð&ŸâaàG>Oá"˜WÈÏð°yä(¬ t~ÌÄÎ?QXEt¨Ðò0èPQBa5áGáaàG1Da Ì«7ó°ùÙ³´ÿ‡ÏÀ…õE:Ë¢Ýð>J±R0J€ïê“wØÇnîlDãô¼ž7àTª¨è&Ñ4¬¦`=…@¿òSSþ$ºnäCǶQÉÒØ¢0„Fk›d£;ž˜¤+1øe¨žg‡¬¥Ña˜#|ÿþ6"T—(Åì¾1%aD¬Â‡ŠçO^‚ÙZJ¥´ç¨ì,è.…Va•ð•¤Øîß›“ãnBó(åuƃ k‚ÚŒ¬º69]]ÆaWöÔ4Õ¡Z3ã?ÃsßOõF4H¸fÁ^ `//ÚG%a©^ Uê§YýdõŸ 3Td¼Lu°Hµ–ÓÛÝ›Ói´JîäÙ½ém+ËÔçfà”iJ1k‹£ô¬ix^ûÜì˜àNƒ¼«TŠŠ›‚ç ]_†•¬Y«eÏJò¦yZYéIœ²“*®Ž ¢Õ à­Ò„Û#›ž›¥C0ã?µÑ3¬×ã ²£sqv µ”ʬ-ÇÙŽTz9•Že’©%7Û¾°À'gç2+ìp|%ž>Ÿq&ã+ìîøQv8µ[Фfr›¯ZcÉbãx<½ÔØ€ÛSÇV $§Ó©•T"Sy-äí¸nß1ŠahÄE½zcr…±™tl&¾KfS‰O”ˆM.±Xfâ3ìH&–J±¥™ÚTšMÁJšN­.eÒÉøŠû“ˆlÎ’Gg:v4¹4Ë&Éé8ë"D—âk°5\I-Õ°ãÉé ï¥gâK¶®ÁçÝ—ZeckìêJøþ)X‰­°Ëñôb2Cx›Z£œFÇúÛa5MËéÔÌêt†Hqt.9=·m/¼“KÓ «3°5“bg’+Ë pˆ»’€0 Xp¼›es‡§–ÖØŠd%_œ"»¶h-å°¯ÉEŸ!2§ã+ ªi¢”mÇSó´Â”ƒŠ$œ’‰/ ¦“pêLêèÒB*¶ýP`:–eŒ°iÔjfy5ÃÎÄåÎ\|aù*‰h]›¥qMòõNïJì ZÅ…0ÿ›÷ma&hvØ ?‹ÕEÏÉìˆÍã N ^ü@ð=xþÉN{®Àý¬«ú¬«ú¬«ú¬«ú¬«ú/ïª6+Lò÷ªGYì~xÏÁû`™Õ÷|G7ÕÔÊŽ;sx]PÓ 3ýhüæv®UWâçè¬ðµ.õ©OÞÚ1N¡öe±z`´g'>Õž+±‡`…h{<8ë£;[èZ{¶[mgy¯À– [„aa‡0(¬¶ ›…}†(|žOÛ»lav}*e±úˆæpÌì„¿…ÙG3Á2xÇÎZÙ†‹•è—+¬ì°g¯Ÿfãä§°Þæ—€½ÿ sÏXþÿ )Ö endstream endobj 67 0 obj 6953 endobj 65 0 obj << /Type /Font /Subtype /CIDFontType2 /BaseFont /TimesNewRomanPS-BoldMT /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> /FontDescriptor 63 0 R /CIDToGIDMap /Identity /W [0 [772 276 551 440 440 496 386 496 551 551 551 496 496 330 496 330 716 826 386 330 330 440 248 605 276 661 551 330 716 551 551 551 716 661 496 605 772 330 565 248 330 218 661 330 248 496 390 716 390 936 ] ] >> endobj 66 0 obj << /Length 707 >> stream /CIDInit /ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def /CMapName /Adobe-Identity-UCS def /CMapType 2 def 1 begincodespacerange <0000> endcodespacerange 2 beginbfrange <0000> <0000> <0000> <0001> <0031> [<006C> <0075> <0065> <0072> <005F> <0073> <0061> <006E> <0064> <0062> <006F> <0078> <0028> <0033> <0029> <004E> <006D> <0049> <0074> <0066> <0063> <0009> <0046> <0069> <004C> <0053> <003A> <0043> <0068> <006B> <0070> <0044> <0042> <0079> <0050> <004B> <002D> <003E> <002E> <005B> <007C> <0054> <005D> <002C> <0067> <007B> <0052> <007D> <004D> ] endbfrange endcmap CMapName currentdict /CMap defineresource pop end end endstream endobj 6 0 obj << /Type /Font /Subtype /Type0 /BaseFont /TimesNewRomanPS-BoldMT /Encoding /Identity-H /DescendantFonts [65 0 R] /ToUnicode 66 0 R>> endobj 68 0 obj << /Type /FontDescriptor /FontName /QQCAAA+TimesNewRomanPS-ItalicMT /Flags 4 /FontBBox [-497.558593 -438.964843 1352.53906 891.113281 ] /ItalicAngle -16.3281250 /Ascent 891.113281 /Descent -216.308593 /CapHeight 662.109375 /StemV 48.8281250 /FontFile2 69 0 R >> endobj 69 0 obj << /Length1 6832 /Length 72 0 R /Filter /FlateDecode >> stream xœíV[lWþÏÎÎx}Ëú–5ñ-Çq¼vÜx³õ5‰›4Ávš¨Î¥±ãPŠJÆ;c{âÝ™íì¬/Q…ªBQUU•Š"õ!ñ‚¨ DEB¨HHP!„DAˆHQA°ùÏ?g×»ŽÃÚÍ ÞÕÎ~ç?ßûÎ93 Bð(ç'õý½féy´¼Š¿+sɕكúOÿ€½0oê†Ñræ€@mCóh¨zcõ Ž¿…ãýó)o¹ò:»‚ãŸá¸*é$t0á×8þ•È’Ò—Ó Á1ÿÇÜÖSæ›×*nâø@ã; (Ãìë BH½¡öÃAÖIÿÊ[0¨cj  *jP-W‚BÅÀò(FõÃÔÙQŽˆ¯ÝS_[=ÅúËÚÙ»'€ýø÷ÿPžS'D6B€µ¨-*¡  ½¶½¶/¬%÷¸rëÞ þ ¿§é‰SÎÞæêÁþÚGZ•WVþÒñcû:µ·µ }í‰Ó'¬óO±ŽªûÆã³ƒ=Ç»:F® ]eA¥¾á­þ¾\õÉ_¿~ìbãmüˆ¾p…"ÈÓòFô)k_‡ËþPmöW½à£hì90 —•æµ»8Þûî±x Wr;eÃgR¹Cñ¹êG"f@¼,±ixCâ îÏ Ä*´±¸ÄÄÙ9‰ËàìK‡ ˜¸¾x^âêÀ %¯mPý¦Ä Âê/%€¦~(±‡Õ?K„ˆÖ&± am@b >£J\sÚ3‡ÐþžÄå0ªýVâjv¶¬#ã2a®]¡«!Z&¬’ýÛ û;„5¡Oè£&¡»„Ë„½¼Ib´—G ‡È~Qba–p¹Ð¿üºÄ¨ùÇ#¿¢NbÔ¿¢Mbô­xMbÔ¿âG£þ¿‘õ¯ IŒúW~ 1ê_¥IŒúW½J¸BôŽJŒ=†W¢½!<#q‹„«Ð^þŽÄAˆ‡ýv¡=¾#qºÃ#\#â×4IŒñkº ד}Zba77ˆÞk^—û­¹Ix7ñß—Xðý~#Â^«IŒöÚÂ{DœÚÏJŒqjÏn&þ5‰ÿe­ÄÿÄ‚ÿá½d¿+±°ÿ‹ð~§.*1Æ©óuë!ûŒÄž&Ü+âÔÝ”ãÔ‘†!Ò¿î‰ÿO„©¯ú:‰Ñ^Ï®"~ý9‰…ý „i]ê¯KŒëRÞÆûÞÉã0„h æñþÀá,8`ãσ<ÙÂ2Š#±¸êh·ˆÙ“Ä/‡‹h›C242ñßDö"^ dNá|ЬÎáÿ±´éé úéÇ‚Ä}Ù–ðåEÞGašòfd1»èC7Æg2ø›E¿ÛŠþ Ø1è‡å‚H~œõ(`z7t9U2³E3:þ<ÒÝ@Ž˜sam¢þí¯™ˆjSDßïŽ,‰UâX¥G\Sf¶Ñzˆ"pŠ=Oýs¬ß,Ίº,bǶ]Éý¼©<#æÕ:‡ãóØë,é&f{ó•Ú¨¦‰^~V—Q¢ešøž¬~‚t Šª9< GpÍúàiê„“®"N–ö­¯¯ÿ,EôH1N“)R-§Û ùæ4GU'ðdø¾nÁLšöžYÑ_‹%Ê•Àëæyý±à&°ß,ua×Á«Aóiœñ;ðWÍÏeÉ Ëï^œ[~_穹BçÄÂsÁi·ÍäsmV—}_ì­«´Ýȯ³K{ÉßU‰üNÙ¼ûõ}\\×H¢¿òåö ˆï÷j e‰:wè„mÞ©¯´^¤ª)OÅÆ³!Tõ—%OQíb~çúq3‰Œÿ¹Foó¾x|ˆOÍ›ü¬c;ÞJÚ䣎›v\ݳ;ÆO&“ü¢57ïeøE3cº‹¦›²Rf†Ÿ3—øE'¥Ûg<=i%rîG7Ìrúè´éf0"ŒÅã¼û¬•pŒ3ëØœ^ÈŽõ/ 9D¹0Ù+SNmt¶2\çž«fJw¸3ûÀθesç.Ù–g|ÒÓ=Œ¤ÛÆ!Çåθ<ádmϵÌLìAAò¶)qsõ%Ëžãçgg­„É{EP;i® «keû Ÿ¶†ŸÐ]ô=þè‘þ¾§,Oé+<›1±¬ÖÁ=ÃÓ¦›²> /FontDescriptor 68 0 R /CIDToGIDMap /Identity /W [0 [771 275 385 ] ] >> endobj 71 0 obj << /Length 378 >> stream /CIDInit /ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def /CMapName /Adobe-Identity-UCS def /CMapType 2 def 1 begincodespacerange <0000> endcodespacerange 2 beginbfrange <0000> <0000> <0000> <0001> <0002> [<0069> <0073> ] endbfrange endcmap CMapName currentdict /CMap defineresource pop end end endstream endobj 9 0 obj << /Type /Font /Subtype /Type0 /BaseFont /TimesNewRomanPS-ItalicMT /Encoding /Identity-H /DescendantFonts [70 0 R] /ToUnicode 71 0 R>> endobj 73 0 obj << /Type /FontDescriptor /FontName /QVCAAA+TimesNewRomanPSMT /Flags 4 /FontBBox [-568.359375 -422.363281 2000 891.113281 ] /ItalicAngle 0 /Ascent 891.113281 /Descent -216.308593 /CapHeight 662.109375 /StemV 48.8281250 /FontFile2 74 0 R >> endobj 74 0 obj << /Length1 12444 /Length 77 0 R /Filter /FlateDecode >> stream xœíyy|[Õ•ð»ïiñ¢Õ²vYzZžäE–e­‘÷}íÄÎâ$$–-ÙVbKŽ-'qB¦,™ÊÒ_˜†Ð„¯¥¬ÃWBÃÐåƒÎ|P¦-3t†BYJ)eZÛÏsÞÕó’¶3}ÿ`ýžtî½çž{îÙÏ3‚È"Aôô•ùTÍ›ã0s+<ƒ£ã³#øEÝþˆ Lº±x4ÿ íU‚(À\h &d öŒ«`ì›Hï{åMÉOa<ãÿ7žŽ>Oüà1‚0`<>Ý7IDˆ0~Æt2:ÿú©ä»0~ ”¿$(*ˆn#„D–ð´ÐOˆÉüR#d’¤ˆ „$%x›(þÝ Ä¾z ’ Ñ¿¶‘&êzq^x+Û‚üb+z®Ž@‹‹‹°û¤°‹;$2„Ð$„IBLV¥UÉÀ2 ˆyšza¾NHÌ´˜! ;`ŽÁÎRîfµ"‘]ä¹”"­ÆïW[ƒ~_8T\N—=hõi5ðɋĈϯ Ãz–í6±pŒ=Å™L®@ÌÚàÂsþ Nµ©°Ë>þÙØH[ Z×÷(Ò 67§æ«U2iÎÅXõ¬;R9Dî'|Ø=‡-n†YcISã×Ñ%ˆ±ÐýÓ‡¶^ðŽ•¸%äIõ÷Ýp]o 8oZüwêê¡"!Ç8¹l.g8\…´6n¬Î×b.ƒÀ%I¼vh'B•£c×½6;†j«GGúBÕÚÛ}C´¶6ÑF]@÷»pàСºztæ–oºö`UE…îé=ðÃÛï@½=—>»u çß¡žž D œ ƒdÔ ;œíÂÒââbüJ%ðR§ÔU½÷k‰Ä÷>Ú»¾ƒ8K¡ÔɪԷ&ÙÒÛÝÝ; ‘xíÛÿÚç'˜*©ïÝç°Ë¤ ûäBáÂ/}zŠÇ¾ap»1ŸÓ_'pÒG=Nè A¨8µqáDÁ1vÂXP3V'Ç• Xø9hj(µhb#w™Ù‹Ðþ}Ož^8†¾%T¼¾P]#YùÊtÚW¾/ÿæÉÝ×_÷óA(6z¶b³#lµ :0IDH§@¨3BàϵsªàŒø+Òpêgã⃺¦ö‡¤78ì%nužºÔ‹ò¥Vk [Òl×å (K¡ÒÓΤ¦.¼ú ²ÚK\F£Ý†TEÛÙöµNc^ìÖ*ìŠuhøÚ,“"¹c’ã)ñ÷d•à"a…Ò¯¶+yõ‡ý¿ZŒ~Ôùà¡­‘åt l¥ªÎÀ®ÅÖµwO®Ô ëd+ó› :q–\©/pÊQ~ ùÛ‹ˆqm¨:ÈÎn²8Q櫜²^´÷`Ea ®Ñp“[õŸá. —"ªÙêÀo3±‘ž9 æÜÚ§õk0ó8ìÙíØ@îœáa¶3Ÿ¥¸Ä1‘3F.:">2úùÈh§¸ ÑJ°r9Q°¿´Å:}±8KL‰€g•ì #:ÓÜâ–+‘Rá5î~¥æš5á÷ÿéÅ£¹ŠxG0_‹ ŒHÓYîk ôvúÊ›=O—ét¨2öü7øƒ÷ü uv¶Ü4EuQ¢!GHQm“‡·nCùN“Y¥T(EBR˜- ¯Y¿{øŽMåaŽiÈ6´´Íë!oBU³ßØÔ‰ì`KÃüõ7ãuÔ úÚ6¿V-žÝ çsÂ1œ(kàïÅ%;HÂïãs)¶b‡©s;æßFƒ·ßÖÓ;ï^Ç0ú±Ñ{Ϥ&·ã‘?U£¡qw‰ÝfDBvŽA ÿç'^ß·¸˜|:6¼s××ÇFþû»p–Ø +å<¢}ñ=ê)8]EA\vâàDUFY"Ђ"#ìphÙª`¥µ¶¤· Þ{íi„›»¢/^Ÿ|©9²;XYaöx‘¢Šæ@»Þ@~ã7ßz¤¯=ð{á£3´w¢w/~Á¾÷øß"ŸwêªøÍ½Ó^kußw¾ rèN6'1T<`¼eXEËðóÖ‚ÕŸ X\ÊÇa’Ï]c›~sSóëë&ï`?¼¹Ü§ÓØôEu•–)ޝíD6ƒÅÝÑÙ Ù²Çᨫ¼oTÐqSW;ÚÙ;ð·÷û¶lÛÿøõßB`‹&­‰…Z” u¼§3l.„œbÎ)ó4Ö÷ŽÔ×>\WƒåQŒ\ÿ Ñì’I ú6¶¶V«‘IÅY2…`˜ÂsõMàC|À¢êN36€: Ys:I”qÔWǤå$ÎD'qкœAð±Aj#‹KÆ~\º·º¦¹;ZIeÆ‚VT_ZRW¼&Ôi*ØB\xýA> ½xØj--im9Œî©3è![1 ÷.,BFÃZR¼¶ÀHrFºø;¶EÇžæjTd Zyso ìlK?—kb‹ï¯C¨à8¶ó©ûyÆŒù¬kWú5+^³¯]lkämVWEõÖÖb7¢-;îø1Ú¾c¦ܪÖBî5öö 5»K¼¾Ûîp—vw ­õ+ÙÙêûÃ;ƒÄ8Ýk ‹<­Ã_ÛµÖœƒô¨õk-­E…‘æ2O{kedÓäÚ.¤‘£,±ÛÿGÔÍ8ʶ­d>-CjíÒ¼sÉùHæ˜Uc?ZT,ZN­_s„ªwTט Gc¿-)]_Ë8I¤Ñ3NÒÁ³=yB4G¡¨«vÇ}¦twI¯ÕŽ»dMçѤ€êëv5ø««6:n ømö’Š2ôž ím¨®wetÔdÎÉE(KZµæ²[O¢kªôn¯7Òîñrl’z¬lT…½ë÷œLî‹UÜ…Àf3ºpñX0Á‰ Œ-؈.)”öm}gRä1(ä³ûú¯}§ßሰ½nƒªîÆ;›´šRöu‡‘ÙúÂùŽÂ¢jê$ƒ¤r¾\i6¨å`L ¥³ïþ;öéýZ YEªÓl¿ti›B§R#‡C 6í[œßU`äb:Ln&µœ…çÖ>R¸0Gj—¨e|¸nÂSÆÌœv;ï8 jVü:UÅ…¾ùE‘SÆ0d^¾ÍÑø’åÐ%åå Ïzû:i®„Gý^j7ØåþBráC'“bƒÝNG~»qŒ6(u ƒ|–Ôø¨UŸ§cØ7¶{JÔ*ÄY~ øjXR! VÕ8þU¹ ³³”Ñ8Ó¡:œ»&ŽÜ?¾þºïÛ´Ig(©4ç Ä6Gu¼jݺžãÑžPm{rpè†#o¿yìjiïritNuemFíÞ9x5•î‡Ó{@×û…·>ùW ö ?cÒ~ÍJí»ÌÕj¿=½PMßÂ[E…VZ&ùÎwÜ%۶쨀Ú׬Õ§™fÊ,V©ì#ªká‘Ã67WØmCä–¶ª›·WU FOØ¢7*åk‚ù*Á|½¡“ äÁS 1.th©+Z5µ;MFsá ¿‚SÖôÜ»K=92^âV(Ræô7 ßW[ô£½bö6è¿f¨]¸ÿbZc¡gç볨Á!´š*.üJÐÈoÁþíØŠ°'çkUªåJ×zy1¬DL…*µúõ74‰% e•Uvû\ûŒVen95üÚ½¬ˆ”†ÍÒ¹H§ æ–ù)aH§Qfgq'×À‡;sÕ½jÙ<ó/3NÜ{@$T ’;sU´/Ø÷}#Ó[¶pÑ»Ñ|sGaÐá9Â.öÅ~G¤À8÷Ùµ–b¸jÐ2- i~0¼Õdºê? 5pš_*®V*f-îx2Á몉jmª¾®¡{Mؤ’åè´õlº FJ®´ÚË|P{nN±•­¨¶«¤\4j<2”'<±04ë°•¸·ÖŸeÿ~³EÏ—ŠnÔtªÌ£‰ê =¬i‡F åäºüìÓFªz©†L÷G¶ƒzü§”¨ƒ1~õªâÇ…Ö•iVŠ_Ρ„˹‡6NÓ$28[Ú[zo›D7í>Û**—ä˜M,­»T¹9Hœ­È3ëÈ–® õÅjÖ¡­õ›Ê= ™zcŸÏ;þ7ÿôñéÃH-/eßß¡3Èå3´9mœÚ¬×I@×±NÚ*KÜÝ#Ïüãîn]¶8‚yáq\³ó§]¥Ñ’àW)‚X»¢ßrzEê»R[~ÔËsþ µÕšÑÖ–®öHئ¨f4Ô°Uª ›&W`,Ü „ºH4gjeË» LPÿ[Ý=á@_)¨1èd|W•é>ŠÉ•û·ïs2ŒsCåvÏ&‹VÆ)/ÓÏO•Õ!½±-·„í\R+´»Š>XñÕ!“;̪·œ!@acÚˆ¶ßå¦ùN q½¨èSðr‚°¢+<#£Ö ¡Œ×jW^GTËÂgà*^¶s¤’1®õè0ú½ƒ—mr@•SÀ9Ò ÞMvÍÂç‚™ù=Ë®Cí(2©UÌÜ/  §æ¯,Ÿ»8»}ñ”"^„Ž•`®èWáY¬ˆ„VË‹ËPÌs·òC5¸næËYhå2prßÂs+Y‡l.ïg ç#/sy’aÊ­³ó'qöÁo3ß>‘© —³ºJµ*¢ñA.°4ìã¤èpP¡T^z) si+Ñmæü¬×.ª*?‚¬› ÙW‹~Í~ΰ?/0TB¨Êä&ºdá÷èÛǪ´R—@£´å«>Es!Z%—“ #›ÿl_xŠ"ÛÁ‚ žR„ðqá.÷¶ÁÊ×~|5üH³<‚bƒ‚¿³ ÿ±ÍŽÌ¦avC¿Á_ƒÞ²£7#ež¾…÷ט “ï~„þá^'­Ñ‰F®óÞ)Ø6w÷Í®bŽ­ÆV2ˆ¤¤cá— —${ÝMü«zTø4À*Ý-½öIŽFÂ(;KɨTPu9™P=ä“–vöœÛÖÖ².O–TšåvŠTnÛ4ÀÉ\Â6SŸÌ#Wf’oª™æVŒø¦ Š>>ɇùü"AçÔ¥­õ__QpÑGY‚Šª|]¶ž½%´i ·ŠqB;êµF\¹f‡©gŸ’[ r­ŸË9j“«™õ¡?åeçd‰ åäJ¬²ÚùäMЩ¸‹ z¨hiËÀäwÍe6©BÂG#2C —¼H.¯ûp¼É(ƒo_´WÆ—zÞo—Šqéw¢/¸¦îãv¯C_Ã62ri!û47ZM7ëi±«så8+¨‹•H!<1?ùz£J"Q)¤MS]Å?³?;`õJs¹›¯  QöµSA®f”9:ë:ªá‡ ªEÜ-þzñá£àQPUQ(—y’ýê‘È&©j“³§ ½éÝÑÀ1$- 6h*Ít…¹BØ5/¦débæn4Í?¿.4iÕùÙ Á~¶ƒ<ÔsoÎ2mŠBÅUüKol¹yðîØmÝÝ÷Üó‡=½N—Uïdj«ÙÓ5rûK—^GA„“ÅM{ö>ñ䥟¿eý†®µ@Ù”7f(«‚™–‚„ŸáÇ÷Dž»FNôt£»îùâ@ohÁjp¸ªk„±âΑ;.½ô:û#–]œ`šöÎ<ù½—^üxßúî.Nï×-¾-‚¶/÷`¸ S‹–ßµðý _fš±ËÛ1—s¥ÝÁ]uŽÉóx7lÚš“sWð|k³“A{fŸ« ЃÃzƒTª/…ªqü`G›± â:¾½lz÷ä·wíëôyò\á.¶äXo׃jë{kü]GBkÚ;ÖݛܲV‹\áA?½£­£ÌÛа¥<àw›‡+#­-ý·ïJ DG¥œk„‰§©8úîgâßg.•ÓþU¯·9ÞÑß0FIŽ"'ϨtÑ‹{Ms ˆ*„»Jj…ZM`¶Ù\ê79#‘þ™¡: ýÐþ4C;Ex!­~KÍ¥„Gœz„r¤ÒÜ<£¢ÈL#DU6†m®¤âeÕA&d‘ËÅùò¡p¤ï`=÷Æ¥‰íP#8¸wèËE §ÑJÌ‚êZöÄÌ«/PµK"1è;XŸ*l†Bl[cSû£‰ãÇñzÁTêr_íîž^Ô×›®(óPæFt)t>H™c6BŽw!´ö'¿9y;R(-&ÇB:ßá.1›¡Ù¾øÌà g›¡Å÷¨ÙŒÿ!±U,ÈHxé+¯dÂ+¶ƒ¨Ùnvleßû7%ué}ûÃk´‡^­*ë\;3°¹§÷xò9$v=údáý7?µkë¶ÚzçT\è7jÕHœe%m:|`W¢ÒEÊ9.Š!’=\D8‰YWw}.+/ÁŒøÂ~j©¶ÂoFV5vô*ž. @ô”KU…EØ7²ÄjUäÝ©`À[ÝP83÷¡·Ìm‘æ@©êè÷ Ôr—Zo,/ŠAø»'ÍØ ×cë·¨Ô9¤T”Ubc´ Ú£v_o.dØŸí,*TcŽ¿Åî$ÁŽÄ\TB«´’ƒlzšýdcwŠQÏïãð:ÙIeðT€„§Úé_„»þ“íÅ«}ñm¡°J—ú ûª´òŸÿÊ{öZÁO-–šéôƒÇ&’Õµ•ûöÜ}4Ûo¹éægÙóOGÛ¶<ôÀów~½8Ϙ¯—€{ú_ݶ56Ÿ:õ¯ÏÜx¬­->›ÿd_?š{vþÇçÎ J«|£8úâ±H8†³-ã_I¡UÿB¿ùuX!ΛÍÛXrž9('K™¯wÖ ^~hîØ”©@¦àÚ7…Ô ÛOþòd±E!·Üÿ@ái­ÚöáyÕçÜ?D¯ü[ü5Û õã À-O±•m&6e†¢O0¥ÕAQ…›€ šÄâu ÑIž%rÉ0‘G‚ðeBp%¬7À“ —ÀÓÏz~€½ŸPFbö·ÂX4Ö ¦ÆÍw þpÁ¼~k2tÿ(  ±‘ áœÛÇgåâó"ÉŸ¥¾¼øG Ð; ¿OÁóÏÏ Ð+‚ñßÁÓ÷àxMjbŠxœøê«kÑwáó{r y‚|—:B]ˆQÁm‚_ÞÖ /ˆ$"½hDtFô©¸L<.~8K”5–µÝ‘=–}:ûýgNÎ…\enoîµ¹ç$FI»d¿ä§Ò|é„ôzéIé[2 –hHpof2ÿÒ_ù¿ ‚_߉¿)ŒiÆ#& qSÀù)f”ÅÃB€<,"l¨‰‡ÅÄ«h„‡³/àálâF2ÆÃRò4ùÁ2oAáQF„\ø “„XøC¦ˆˆðÿò°€‹²xX°–‡E„Rääa11 ºÌÀY„Nô Î&EOò°­ý(#gI²Z0,ä*ä¬õáù! ‹ñ|ÃY>„aî¿é;³Nð0È0ë?yd˜­áaa¶ƒ‡A†Ù§xd˜ýƒ ³ÿ‘‡A†ÙŸñ0È0çEæ|Êà ÃÜ}Îáø”åa8—ãMfưÏ{0,Ãp†o²Ì}¹ÿçÉú1œqF0¬Æt¦0¬ÁóG0¬Ç{3÷5bœû0\€qðÃOcØñ/a¸Ù;–bømÎÊðÿ1†3gý‰ƒ%x^.Â0¾‹<8KЄðÂ'P?11<°ROŒÃ‡&ÖÃÜ(ìOÓx‡ß8`ïï`öÃúž¥‰nøÝ‹±R0Jþ(1”¢°çÊó+þÊnúŠýÄF|ö4Ï' ì;–TÔÄ0¬¦`=EŒÀ)E…þŸ£æþwߪ½™+ûz‰>8­ÿ¯rŸÀ+QxÒX¾1À™À7ÙsÿsÝpT“˜bfß%`Äiƒ¾Ò7Οœ„Ù2LÆ´ÇðiS ¤šÄ|%0¶çÌÉ—ñú—¡&Œ¹ó: ã¸ëÖ·ZºÌi4‡]™S§°Ä8ªn˜ÙˆñÓ<÷]Xnœ9®iÐR´ä#ðMh,WŽÎ ¶ÏŒ|2òÁÓXÜxË`KmInCxï’L›Aª]à™½S«V&±}Åà”aL1£‹½ø¬aø¾ú¹™1‡; ÷Á·ˆaÜ|Çðú$¶ñÙe­eÎJð†yZ™ÛsþIéæ),ÍYì °}[ÛÐòYWã+ù%Úÿ})­P-ëy ÛRƪ†—-åê·_±ãËùª\%î&™»¤ñyK6ÈÑÏÜ53{ñÍSØÃ®~ÓŒ¤£—I5Î{Å•¾ÁI5 x3x'ÇížeËÍÐá0Çã/êè,íózCtÿXœ^›J¦Ò³“qº155™šŠ¦©¤‡®§×'FÇÒÓôúøt|jO<æéOLħéîø^z}j"š\N-í¯¸b™æ×+6Ƨ¦&ôxË鵉á©Ôtj$]tþj4^…E¼ÖÛ·¶ÿJò‰i:J§§¢±øDtjù³·¡I: k’‰tŽüKkK±<–‰ÑÔiêQÏS߇çêY걯ª‘¯ª‘¯ª‘¯ª‘¯ª‘ÿÕÈe±|æF‰«®ýê2<Î/VGùŒõ_æ8àÌ® Ì‚rA§ UP ß‘ËNHÝ?G¥¾÷`)füz =Ž¢¬ÛzÀšâcFô/P¸*ü_Z·Î/ endstream endobj 77 0 obj 7193 endobj 75 0 obj << /Type /Font /Subtype /CIDFontType2 /BaseFont /TimesNewRomanPSMT /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> /FontDescriptor 73 0 R /CIDToGIDMap /Identity /W [0 [771 661 496 496 439 330 275 248 716 275 496 496 496 496 496 496 275 496 496 385 439 496 330 551 439 330 605 496 605 496 496 771 881 248 330 716 716 248 496 496 716 330 330 551 330 330 496 496 605 330 330 661 496 ] ] >> endobj 76 0 obj << /Length 728 >> stream /CIDInit /ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def /CMapName /Adobe-Identity-UCS def /CMapType 2 def 1 begincodespacerange <0000> endcodespacerange 2 beginbfrange <0000> <0000> <0000> <0001> <0034> [<0052> <006F> <0062> <0065> <0072> <0074> <0009> <0056> <0069> <0064> <006E> <0067> <0032> <0030> <0033> <006C> <0075> <005F> <0073> <0061> <0078> <002D> <0046> <0063> <0066> <004C> <0076> <0054> <0068> <0070> <006D> <004D> <002E> <0049> <0077> <0041> <002C> <0079> <006B> <004E> <0028> <0029> <0053> <2018> <2019> <0071> <0035> <0045> <005B> <005D> <0043> <0031> ] endbfrange endcmap CMapName currentdict /CMap defineresource pop end end endstream endobj 7 0 obj << /Type /Font /Subtype /Type0 /BaseFont /TimesNewRomanPSMT /Encoding /Identity-H /DescendantFonts [75 0 R] /ToUnicode 76 0 R>> endobj 78 0 obj << /Type /FontDescriptor /FontName /QADAAA+Menlo-Regular /Flags 4 /FontBBox [-558.105468 -487.792968 717.773437 928.222656 ] /ItalicAngle 0 /Ascent 928.222656 /Descent -235.839843 /CapHeight 729.003906 /StemV 43.9453125 /FontFile2 79 0 R >> endobj 79 0 obj << /Length1 4704 /Length 82 0 R /Filter /FlateDecode >> stream xœ TSWòÎ{/[«D´ÅOBªü !¨€HÂ/€È§!‰æ' P¤T)~W­ë·h©§µ~¶g9mWÁžn]m—Úާk­Ûºýèv]·UÛ*yìÜ—‡ÒÏžÝ&Ì7w~wfî„!ÄŸ¬&,!…%± [¾Ý€”ÍÆF[[Ãö®?íAükB&&Y̦úºë¹!ä¡™HK² ab6¿×U¸ži±{ž<ä <‹ëÕT†ÍYgÒœš;Iqc7=é"áD‹ëR\+&»¹Ïÿ ×Bد ˇ­DBˆD-A­0Ý÷Ÿ½@˜)„0J'°þÃp_°ÑÈwBCIdqCf=I'ŠQ¯4ˆ‚½~v¸b$pyô2!œQ2Lµ!0ÄÂïä,’Ñ[?BeJÙ,¥LiáȈ› ùœßé7éûo𤳠XÜywR>¥\)SÉ”±œ›>ÇGJ†Ü–DRykG?ãT\;™DÑ^•ÔO" Vk“´­L¥A‚J®IÔ&©ÕšðˆpU˜ŸÔO“„ËàáÜL}¡¨ -Õ¶«¼ŒL)¯\u´¡áé§n~Çd蟭©1Vškª–lª3¥Í’0jÐÎu5h“a¹õÄì|oçAsLÔœ¨5M[›–š8Í.NÈ5 …§F¯påÒ 2™à™h<Èg$ !Z4"A;Ã"Â#ä*™šÝ :ýÚu™ø¬[«×yÿY˜ßxÖãp·œ5çÄ 0±Ã»Ý1D–áitaìä÷«K8 ùXs]óSÓr^Á<Äkt)ó´l[Œ\n³½ëý3^lY¸d31ﮣ¬ÕÒÉdy¥)i¢`j(RàØG`ç?…\Õˆº§‡Mc2¾º—hÅ/ä„üÿÏ ÎxÈ—´þøln JœL4(“Uêë´¥?‰ºVC[]„ô~Y†hÔl…Nß¹!+;'kã*½nZZ¿,(.-6ꩃ¨üÛÛžæfÏÛ¶¼¼ØfîmÆÓ64ds`¶ØùK#ÏtÁ¤‡¦‹•‡@QQ¿GMt,–ì>ð¿ýû"£–l£¾_Eß˱Z'ˆZèÖWY§·Š1{Ÿ;‡ÝšwñNFŸðºà.J±§ÌÀ¬:PͪåJT* · bÕÌo*nUöUÞ俬½Ã_¶ôYo[Ÿ·ð<Ì®åoClߪ½-ä÷C-¿ߺ‡¯‡^ {`ã¤IøV´­4•ó—n&Qx§ùª]h$* í¾­ ÚèQa"ûÑ„çŸþCi¤¦u®\Ù¬…²ÒÒ³6ω‚̬wNåæ@ÔœÍê­†ÜOÎØö€>£ ¸ór{"£¶ð7ûSÒ}8=ãèy\Ú€-sâIÎAŸÅ¤”ùrD¨$DÅ’Ÿ·Ì‹ašDÃúdí!x$4«hêôCS§çB§½ü²2!~A¾:ž½ž£ ƒF+ÙÛÊt~=njÚçÞULç 4W@9£1E1Âf¢ ùhÃZÎHDTŸ€«æ00ÌðƒÃ0À;ß…ÙÁ½_yà¿€Éaæ—ÃzÊ„ßÍÍ sŠË‚;s7ùä‘#4SË!kcωwº˜åœòîe pó0³ú0•PNº¹6®•H‘KrЀÀij§ŽñÕùêãJùð¾á²%T½úÑ\™j&L8˜ü{ë„ä}ïÌí;qÕÈ 6àÎ%êZ>ßÏ|V:ÃàFÖ/N@ò'g`å¿ã‹ú…›í 7ûwp³aÓö a¾ÚÑbí@Ðý^Fψ­ˆÍ+¨×Õr®~Q> ×­[“™™½fNÏžgt?|Ý]…·Y0Èz÷Bd4?ñ–‘Ã>,ÜÔB@½¡\5í¨5Hìæã 8=”¸â™ÌÌÁÁ„’2×+%¥pˆ¶ˆÝYÙU•G™¶»ÕÆ'¬pù¤}ÆÍ¬R2‹–¾Âg¾’–þø;„êÐr³ ‹ñw·mß¾ $Eù…†ÃÒW–.…šªWj òÎ¥—qo/APo¯<8òTúô©àZ14äZ1}êzÊQ_ŽÐhíŽÍ0c µÊî7 Ʋ9ŸÍÝô»û«ŽööökWñ«½ì›Z|qéݵ›¿Âºs7Àî0¦íÞ…šzðüÏc? !a¨‰¶pì ´ZTt¤þ¡¿¾©@Ku3ß$'•œûèÕ‚Ô´ºSç ïv×3…ÅÞó—¶agÍ+èaNi“òhë‹‹ñn” ;쨪a*¼×¦¯ïÄ^H=<É—q¥è¡³Æ·n™8žAâOÆ·V¼R òÌg›ÝàöœmÈ_ÿ?ºu{ÿ,} §8:rß~þüõ½½8¦Ý?¹Ñº¢Þbeb¶ËÔô»«:vºoßÓÇø;ý¯½Ú£U+“á=Én¼ÛÇ4x÷¢µ̦*¼•}çà3Là;“À1¡ñÞ¨ÓïÝ£Óëu{öêu¶wŒð+Û¡£}d¤£¹ 9[º»·`8¾¹»{ø•o¾ùÇ“°Ö¿‰Úx»¨Z좴oÒqZ‹'¢‘‰ÍUÈïT: ”›¢æää¼u&3sNÔ¦¬ôïËJ“µÝ+Wv¦¦•–}Ÿ®†¨ÈžóG3Ò~4-¥&nÁenÞÇüHW†z ÛÎ|’kÀaTˆÂ•w·×LN¹E0ýüÁûò"Ú´¿ˆîñ³óÓÆ–ÜG¾x{TÜûĂЅð& „v„Ó"þÿa÷>PÞŠ4ÊóAèGXŽ'®)”‹€: oœL ºþ òº.¢=rü=ÕFŽ“aœŠS 6Á_™ÙL!ccv0טQ6™]Éþž½Ä^ÃóA—Á=ͽÄ]’L‘,’l”¼$¹( ¼T‘$zߊÑûé3™œ¸Go½ÇØ7[EœÁnþ”ˆ³(­KÄ9œЏâ5—"ý ÷ÃÊ=ãÃñk¹&â@È·( ¸ ¸s °">q¹ˆ?9!â’yŒSÄ'’ ÌaÓÕÖdm´x‡ qqs ].›Y‘먋QŒG_&)jÛ¥¦û2§£Q‘a²ü˜9Ô”#Ãêq{šÌ&{”OÌB›MQLyÜŠb³ÛÜÔb®)0;lÎbsc³ÍÔ$à q1_¯‰«7ÇÏG ñÑq Ññq?bcˆÑ?bu+LŠÒ&S½ÙnjZ®p6Œs'ßÚhò47™Ý:§Ýît(î­I±q#431áxa@Š`çcêØæ&øí@܉T+®¤9ÝH­G¼™¸ð1± MA ‘b(%ø¦%× ôσØÏµ*HbMˆ+‚ä1y.”Q‹ú­(GoœÈo•ãG2õÈ»LØ_†ü1ÿS‹Ï“ ‡Rêñ •ÛD–#͉’IBRsQcjˆ¬¡²’F¤ùâQ‹qSüBcÐ~\d‰ÅO«ð‰vR̈;QO#¾«½2!æÁõ/ï¬ý™u1ÂN;òŒÅ¥FxçìlbFå»w"­YïF }ß‚Ücû(­EŒ•Ïr;úñaÀi endstream endobj 82 0 obj 3321 endobj 80 0 obj << /Type /Font /Subtype /CIDFontType2 /BaseFont /Menlo-Regular /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> /FontDescriptor 78 0 R /CIDToGIDMap /Identity /DW 597 >> endobj 81 0 obj << /Length 602 >> stream /CIDInit /ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def /CMapName /Adobe-Identity-UCS def /CMapType 2 def 1 begincodespacerange <0000> endcodespacerange 2 beginbfrange <0000> <0000> <0000> <0001> <0022> [<0054> <0061> <0062> <006C> <0065> <0050> <0074> <0068> <0073> <0053> <0072> <0069> <006E> <0067> <0046> <0023> <007B> <006D> <0078> <005F> <0009> <003D> <003E> <004D> <002C> <0064> <0075> <0063> <006F> <0052> <0070> <0077> <004F> <007D> ] endbfrange endcmap CMapName currentdict /CMap defineresource pop end end endstream endobj 10 0 obj << /Type /Font /Subtype /Type0 /BaseFont /Menlo-Regular /Encoding /Identity-H /DescendantFonts [80 0 R] /ToUnicode 81 0 R>> endobj 2 0 obj << /Type /Pages /Kids [ 5 0 R 29 0 R ] /Count 2 /ProcSet [/PDF /Text /ImageB /ImageC] >> endobj xref 0 83 0000000000 65535 f 0000000009 00000 n 0000039087 00000 n 0000000197 00000 n 0000000292 00000 n 0000001363 00000 n 0000021910 00000 n 0000034244 00000 n 0000013261 00000 n 0000025318 00000 n 0000038947 00000 n 0000000329 00000 n 0000000374 00000 n 0000000419 00000 n 0000000464 00000 n 0000000509 00000 n 0000000554 00000 n 0000000599 00000 n 0000000644 00000 n 0000000689 00000 n 0000000734 00000 n 0000000779 00000 n 0000000824 00000 n 0000000986 00000 n 0000001181 00000 n 0000001733 00000 n 0000005134 00000 n 0000001484 00000 n 0000001692 00000 n 0000009145 00000 n 0000005155 00000 n 0000005193 00000 n 0000005238 00000 n 0000005283 00000 n 0000005328 00000 n 0000005366 00000 n 0000008978 00000 n 0000005724 00000 n 0000005856 00000 n 0000008811 00000 n 0000005977 00000 n 0000008664 00000 n 0000006107 00000 n 0000006239 00000 n 0000006428 00000 n 0000006609 00000 n 0000006840 00000 n 0000007085 00000 n 0000007344 00000 n 0000007575 00000 n 0000007820 00000 n 0000008107 00000 n 0000008384 00000 n 0000009041 00000 n 0000009475 00000 n 0000011276 00000 n 0000009267 00000 n 0000009455 00000 n 0000011297 00000 n 0000011557 00000 n 0000012624 00000 n 0000012831 00000 n 0000012604 00000 n 0000013397 00000 n 0000013663 00000 n 0000020729 00000 n 0000021151 00000 n 0000020708 00000 n 0000022058 00000 n 0000022342 00000 n 0000024652 00000 n 0000024888 00000 n 0000024631 00000 n 0000025468 00000 n 0000025729 00000 n 0000033035 00000 n 0000033464 00000 n 0000033014 00000 n 0000034387 00000 n 0000034650 00000 n 0000038083 00000 n 0000038293 00000 n 0000038062 00000 n trailer << /Size 83 /Info 1 0 R /Root 53 0 R >> startxref 39192 %%EOF luerl-1.2.3/doc/pdf/luerl_new.pdf0000664000175000017500000014471114677012037017244 0ustar debalancedebalance%PDF-1.4 1 0 obj << /Title (þÿluerl_new\(3\)) /Creator (þÿwkhtmltopdf 0.12.6) /Producer (þÿQt 4.8.7) /CreationDate (D:20240911123453+02'00') >> endobj 3 0 obj << /Type /ExtGState /SA true /SM 0.02 /ca 1.0 /CA 1.0 /AIS false /SMask /None>> endobj 4 0 obj [/Pattern /DeviceRGB] endobj 10 0 obj [0 /XYZ 141 723.500000 0] endobj 11 0 obj [0 /XYZ 141 633.500000 0] endobj 12 0 obj [0 /XYZ 141 249.500000 0] endobj 13 0 obj [0 /XYZ 141 574.250000 0] endobj 14 0 obj [0 /XYZ 141 222.500000 0] endobj 15 0 obj [0 /XYZ 141 415.250000 0] endobj 16 0 obj [0 /XYZ 141 179.750000 0] endobj 17 0 obj [0 /XYZ 141 137 0] endobj 18 0 obj << /Type /Annot /Subtype /Link /Rect [365.250000 443 395.250000 452 ] /Border [0 0 0] /A << /Type /Action /S /URI /URI (https://lua.org) >> >> endobj 19 0 obj << /Type /Annot /Subtype /Link /Rect [167.250000 434 181.500000 443 ] /Border [0 0 0] /A << /Type /Action /S /URI /URI (https://www.lua.org/manual/5.3/manual.html#3.3.2) >> >> endobj 20 0 obj << /Type /Annot /Subtype /Link /Rect [252 434 309.750000 443 ] /Border [0 0 0] /A << /Type /Action /S /URI /URI (https://www.lua.org/manual/5.3/manual.html) >> >> endobj 5 0 obj << /Type /Page /Parent 2 0 R /Contents 21 0 R /Resources 23 0 R /Annots 24 0 R /MediaBox [0 0 595 842] >> endobj 23 0 obj << /ColorSpace << /PCSp 4 0 R /CSp /DeviceRGB /CSpg /DeviceGray >> /ExtGState << /GSa 3 0 R >> /Pattern << >> /Font << /F6 6 0 R /F7 7 0 R /F8 8 0 R /F9 9 0 R >> /XObject << >> >> endobj 24 0 obj [ 18 0 R 19 0 R 20 0 R ] endobj 21 0 obj << /Length 22 0 R /Filter /FlateDecode >> stream xœí]Kܸ¾÷¯Ð9€e‘Ôð< ‡†Èa‘CàÍn°X/âì!?êÕ£Vé£XÕd‹÷ëñ4[Y,V}U¬*¾ÿËçf¿ü‘½üüŸì‹ýùøùPäMU ÿeÇ?ï¦tEÖT:ûòõð-ûvøtøÔÿ=þ<~ù롪L~üªRý¯¿MmÛ67ZéNõŸó__þ÷áïÊ~ï;ÇTä]§UU·µ†ÿþãËï‡÷Ã\ú'‹¼- Ýve?ÊÓøg¿÷#?þ¨û·*¥Šì¿ÿ:ü|¿ß£¯ãR…êê¢iKøïé¸|¾ÿùñoýÐþ—éì¯ýÿ¿f?þ£çOÄà½ôáåðþcé:{ù9SÃZ?^¾tSeü”ýù¸Ÿ>Ó‘78}òüÒ³Åv+×dª\\¹ªÍ‡ýØX4—”­òÒ »u¾‚u®‹9µ lV°™/É'¢áb™º~/·‹‹Ñø¼¯…£Ç-ݼûóì [+À^[átðDŸàDÉHžçà5øxj))_ªŽ~£6U^ŸQvŒÚv÷Ú¢aoxf6 G's†QeÊ{ÈôR弇̸‡T5ŸD=ÿ`ÎÒªÐAj®÷N¾‘„ B*¤­³wZ«ËͶ$z‰€¶’VùœM­ˆH”mN3®šuñB$‘`ÿãîÕü{"®áû”]Œãü»£ðð|˜§Ï<Á÷µ%ƒåšz†½á©3¤$–ñy Å1A<½”1)¡Œeè‰åz+/A¤Éý}Ú¢ÀID³z ŠçwE¢Ç •¸÷ýáÏf¼ÌÁ] t"qXKˆƒÅ0ar¨t[Ë_YîòÞˆ]C›Õ¸7ó@[Ç© C/¬lÌS.\;ÎHYTê`~à'‰ÁäS-Ô!Pz–ŒÓ †È“”ã÷ {òudäÓÂtLg1ÌÉ`À=„»0pP-I©dcÒek›)½˜êÜ”Âu­ÒC¢*´íÅ4v°­ÞÈio`‡Iº ÍqnWhs율˜8!ÉöL$œ„Nì‹ ¶%‡Ë%~­›D%K®êöbÐ[M°ÓÃÌqölI‚\°\ª¦är°Î#§TdÏÁVž¦«Ø‚D}û»­0ÒOp­Ãú7ƒx¥$)˜qµ/c½¬„‘ªd[]á’tl„‘öeá_l$2R•¨Åg(¼o•HŠK|¬'’$Í yóŒÃQÚHÒöä (vç:dóHl77 Ã;):GUIdœè`f³Øª81ÉÎRŽeHPÆ„CHß º½-¨Ã‚D¸¯Ÿ‚oý4ó7JdŒ­ ×i¿ºGÍÈõ»![í²’ª’¥áX á `U$Œq*¥×™ÁŸœ)Ï#¶ÉÀ‘è,I"QÓ|_^è›D-°Ž÷Ã`.ŽãâøÄÂÅJ¶â³"îÙ\oÉáÔXYuS=æ`LÆ2‘èO-ùÌ"Ÿ¢ä;γRã¯Ò(.>øíð9ÁÕ9rº: 9nä³CW0º—ˆ ÷Ýg'¸¨ÇœENÄ*Ʀá5kf@¢4Rº›)p¹AuÍ9rc¥»W9¢*3ý M9r䔲›áˆaG ’È"“ä=mU`ÄèùÞ‡n3ëh‹ìŒïA2›vJ¶·"™ß˜gZRê=ì5‚lwT¢RB7Í¿3ö1Y/[•Bß}ýj$€ÑÊømy‰·0ˆËQT¨À?*m5}:Sxñ®ùv—ßmUôªÂ“ ^ýrë‰Æ=¿u)QœüyóË0nS”Îuy;Pc¥G„ÃÚħ¥8æŸÏaýY"=ƒG°š¹dž‘©ãÈ«´5xÿåÉbïJƒ‡Í›O×Mu]ɡ͞DwE­Wνñ}dãÜ ƒ…sŽöˆ\À®h˜_2Q²q"ø ’ãÂ(åòxP3(£Æ¹ßÍÖ-ÂQ|‰*áàªÎQŠû®*çæ¾ôÊ¿owïZÜcHN4æT‰TbÀ‘õ3°nþ(ä +RãèSQ)¸dX”+3yhŸQ§+™kÕî¢mŸ¢mn¥öŒr†Y,ÙH8½m }S4h{“`Ë“ˆ ð¼`ʰí¤ëêñ™n8×ðz¦±í½`ÊÐ$@Ëî EœpQ"XÄé^©íªk`›”á÷̇«-á7Ȱ¥ÿXçû» ?³æÖÀ!)®|,*8jh°Œ¦ÃòÛ>§°G\(°3ãXM˜K„oÂF4øÇô;œZßqco¡qÞvEí»A3q'¦ø;ÎïeÊî­—èêsQÀï+ØÃºfÎÃx.)õ­”íg$Œ3TOqOÖdñˆÛAŒµÐ%ç&$+‚}]F(ÜœdJΊÚ8÷i…ˆºä”@Ö Z8,è‹sœœƒ4=)Ù‚ÙžÛÒ‡xª7vî‰*–941cX8 *ñfT‹„·.›>!µ‚ÀTr zÏo ‘ß´ ^íõ,{¬ØÞvÚ.:g ß’HRƒ[ÌqYtWìvE OÒ£2»¸7‰èYèÄ$]LzXÒs0§iMÖ Kðè?Ä}‡RH¯“¹ðƒãÙ¸G¶¹t¥¦<Ü•„aÏâvXÍIcØHÒXàˆÏQ–$@ˆ ¼(89ÔBò¥–‰ã¦ÿ“}ëõiqÒ@Ý~Ê>þ‹d6¹ endstream endobj 22 0 obj 3346 endobj 27 0 obj [1 /XYZ 141 586.250000 0] endobj 28 0 obj [1 /XYZ 141 543.500000 0] endobj 29 0 obj [1 /XYZ 141 482 0] endobj 30 0 obj [1 /XYZ 141 419.750000 0] endobj 31 0 obj [1 /XYZ 141 274.250000 0] endobj 32 0 obj [1 /XYZ 141 358.250000 0] endobj 33 0 obj [1 /XYZ 141 212.750000 0] endobj 34 0 obj [1 /XYZ 141 296 0] endobj 35 0 obj [1 /XYZ 141 752 0] endobj 36 0 obj [1 /XYZ 141 160.250000 0] endobj 37 0 obj [1 /XYZ 141 700.250000 0] endobj 38 0 obj [1 /XYZ 141 98.7500000 0] endobj 39 0 obj [1 /XYZ 141 629 0] endobj 25 0 obj << /Type /Page /Parent 2 0 R /Contents 40 0 R /Resources 42 0 R /Annots 43 0 R /MediaBox [0 0 595 842] >> endobj 42 0 obj << /ColorSpace << /PCSp 4 0 R /CSp /DeviceRGB /CSpg /DeviceGray >> /ExtGState << /GSa 3 0 R >> /Pattern << >> /Font << /F6 6 0 R /F7 7 0 R /F26 26 0 R >> /XObject << >> >> endobj 43 0 obj [ ] endobj 40 0 obj << /Length 41 0 R /Filter /FlateDecode >> stream xœí]KÛ6¾ûWè\ ŽHê 6û(ÐC ôPôP¤/MÑmýû•-jwEê£È1eQÚÉ"ÉÚ´Éáp8o†Ô»o>þ”ýöoöîöãßÙ'ýÿíÇC~¬Ë¼ÿ“~¾|ýF›gu)³OŸOÙÓáÃáC÷ïÓ¡ÿàÇÛïºßþËdöm÷÷쇻7Ö:}àó¡,ÕñÔÝË?_¿l𿍤­èÞÏÍ—§ÿ~øþ‹ì¯ÓhÇ&ÏeÓ!ç‘G¯¿|õÕŽÌÒžÃôócÛJQVM%áïÿ~úëð®g[8Bˆ<«ºWç_þùåðë‰5¡ý¼+rÑVyÝð÷×äú|pé‰<èûÇû‡*Eöøk&ziêÿ{ü|hªî…2{ü9ûê$_gÔ±ÑÒvúTß"Ï-õ±n„,G-êÜRe®ÎM/-lÁã”ý8/oT„ës‹8±¤UÝÏ-âæÜR«²2zƒ$‰Â$éÖxCåˆF‘£ñ„‚,ÀÌÁ3nÐ8²'¶9–Euîp) Þ#ž[ìÊïúŠZî•€l4±¯¦ž „-X{±!±â®zTÎÊb VɃ‚ü!\îì©Ã­'ú]Z e¤dÔujÃ'h‹þ(–f¨'ÄVpêwzm¿}z“µfq)L¹3×IÜ!.QxކÃ`IÅËŠè¦ÄM¶p±ñ:õ"zÿØù/©:ªÙ¤Âí‰m;¯ñöh ½‚mi´Ø,´€t.íxƒÉû–´v.i­Mß3¼7dQ´Ö™ê­D{ÃAüŽÌ¡Þ»1WнÀêNB}?ãŽOQp ™Ba—ek”É Ü+^lH½ö—§fl-îÞÚqQE«¡©ï´ÆÀR"×MZŒ*Ëä˜Nmvb­9 ­:}ÆÕ~Æ”»„· ^s“õX<ð¢(­inª¥JAg;ͰÌÛyk¸÷øÞ+ù{pâvbÍk§x‚#—ЀÆà0Å¡2”ÂPŠm ¥XŽ[\(%is+ËØe1œÝ#5¤ bµ€[–U¸ŽíºAÀIóÚ€E((&É­Œ²P, OÃ\'¬éC6 \¸ €G²2ˆ|Œl`¥àFª¤Ëdø<oãaHx ¦CÀ뮎á5†š820s®I0`Aâ5žÆ` +g#2óÒl¢V\ 3SÆ¥w¿If$9*’œ´;SWã@e'XvºÕ~ØÓsµâZE[o˜Kê Óè¿Ó¥µ¿°2÷×qqÌ×µÇâkQ²°ŒYªk]Š%·¦E©Œ·ÖB›µ1ó PÐÖ0—Ý?¸sÈt@­EÆpo÷æÀsÎFÒ¦½J¢qYˆºÖØ å4H3•1óãŽî!(‰»W·ÞkK[MˆP‹H’ ‹ÃÚk™\Kð ‘ @SN7(9Ù½áìþ2Ùv{:8ƒiãè•’» Tþ+hƒ0Ô$¦ YJI}Ry&æ¬5 Œ½?˜k¬ÓÉjp}qàÔpP•ýz ¸ô³5ªJ}¥±–'ŒC(s¬ÌÙW9Å!Úôn¬:¡8±ƒí[ ØR– ¶Ô°¥--l¹!Ì'i¸Næc¾6€DC·ÕΕ’ÅÊÂi8h£$•(3 Ž?#%6f£ôTœRÅxSÜÎlî©–;Ør[°ê{@-šÉ‰ªÕ”žêEÀÝ›-FQÃÑw¢ÑpQäãUÀ ,UIÌÉYQç¾f,eôOB†Ø[DRZ>'ñ–‘“FÇÀØÀU´¨Á€¡Z7„øŒü£JŒ*¥ ­0ª”¨ûr6²Euhbß.ªôÂF•œóÙªôj-UbT‰Q¥b¼)UºUòQ/»@•ňƒbœ@¢YOï(†ã`§Âйä8Éîâ3˜Ú›žˆ_)ÛÑœ—Ücñ àüæ”8@䈣ÔÜ0H8M‹Ï’| ‚0ÇñqŠR{ÃgÂ)Ëšºes6uÒ|µ»›ô=›¦z+{d[·êð}™PfK)—χœÙÀðƒ'lawmâih-÷ÊYµ¤pÖØÛbÜ Gʳ§‹øüõz(bdù°x78éÄ耡D]’"W#ý¾Ãr#eÌ0ÊÉÖëué\ƒ¼ôÙ×€S¿XD´Ô‰ sï©zì:â+Vƒ<`ŠGµ(¹¬Ã %$x'ׯ c¤š‘jFªÏo0RÍH5#Õ.MµMð·l†âüµ!òmhmFª©Š*91R}IüËH5#ÕN©Þ+R&æÖMt˜mþ·ÁRt)‰¡Q‹Ã­Èœ¡fŠöKjNÚß)®dãjöïªç»”jöš×\‚gx"eˆôÒù0DÊé^Šy·¡’¢ì„ƒŽ.ýtˆe£ÂeÀ‰m?ÇŸ_åÅjF¥¼`TÚì-Q'©hó‘IÝ_ýt)2¨MPžá6'Qqè]ÈB!ž¬]¸½MP;HBqeƒ²2PþŠŠS±ìs¡’‹!jÊR9þ^&ªžÆ˜œ—/„Ùˆؽº‡F}–ø™ê@c:Žâ¼\ɧ •SÎNT°@Ð8iâx†K*—ò¬¬ÛdgÉä”rSªi7ÕGi z‡M´ ¿s[lyHaȨº[ƒ7tsjDz²¿›ë Yø®nrGD6€Šœë$b€«Ý¦£.s„:Ö——½’g5@q' ×F2È °‹ b‡Frmä›E¹ñÚH†tP Ïwö ¾ÒnC˜æw°å¶°åµè…IÔL¨¦srý `w‹Sh£kÜŸ§ÂÔRÓVǹO~­‹·Ò3ô›Õš½KX…«¬4©JS¨zŠ“Û“Q”£‰œâ ³ .¢Laòpëb¼ˆKÞÉ—ªÈ\Ž€s©N¡‘Ɔ! %´ã›ô<ÜÀ(7é…<Ýç:iÒ‚¤œÒ%  R𱎫§tñ½â¤c0­hÁÐŽœ+ΟâZõ¦po×=ˆ1uìWÏG ­Ï|>O’R’ƒ“ÉœL^1™|öºŸì©3üùÙX¿àCöáð?»wІ endstream endobj 41 0 obj 2855 endobj 45 0 obj [2 /XYZ 141 710 0] endobj 46 0 obj [2 /XYZ 141 416 0] endobj 47 0 obj [2 /XYZ 141 373.250000 0] endobj 48 0 obj [2 /XYZ 141 320.750000 0] endobj 49 0 obj [2 /XYZ 141 647.750000 0] endobj 50 0 obj [2 /XYZ 141 596 0] endobj 51 0 obj [2 /XYZ 141 543.500000 0] endobj 52 0 obj [2 /XYZ 141 500.750000 0] endobj 53 0 obj [2 /XYZ 141 278 0] endobj 54 0 obj [2 /XYZ 141 458 0] endobj 55 0 obj << /__WKANCHOR_q 28 0 R /__WKANCHOR_s 29 0 R /__WKANCHOR_10 31 0 R /__WKANCHOR_u 30 0 R /__WKANCHOR_12 33 0 R /__WKANCHOR_w 32 0 R /__WKANCHOR_14 36 0 R /__WKANCHOR_y 34 0 R /__WKANCHOR_16 38 0 R /__WKANCHOR_18 45 0 R /__WKANCHOR_1q 53 0 R /__WKANCHOR_1a 49 0 R /__WKANCHOR_1c 50 0 R /__WKANCHOR_1e 51 0 R /__WKANCHOR_a 12 0 R /__WKANCHOR_1g 52 0 R /__WKANCHOR_c 14 0 R /__WKANCHOR_1i 54 0 R /__WKANCHOR_e 16 0 R /__WKANCHOR_1k 46 0 R /__WKANCHOR_g 17 0 R /__WKANCHOR_1m 47 0 R /__WKANCHOR_2 10 0 R /__WKANCHOR_i 35 0 R /__WKANCHOR_1o 48 0 R /__WKANCHOR_4 11 0 R /__WKANCHOR_k 37 0 R /__WKANCHOR_6 13 0 R /__WKANCHOR_m 39 0 R /__WKANCHOR_8 15 0 R /__WKANCHOR_o 27 0 R >> endobj 57 0 obj <> endobj 58 0 obj <> endobj 60 0 obj <> endobj 62 0 obj < State.) /Parent 61 0 R /Dest /__WKANCHOR_c /Count 0 /Next 63 0 R >> endobj 63 0 obj < State.) /Parent 61 0 R /Dest /__WKANCHOR_e /Count 0 /Next 64 0 R /Prev 62 0 R >> endobj 64 0 obj < {ok, Function, State} | CompileError;) /Parent 61 0 R /Dest /__WKANCHOR_g /Count 0 /Next 65 0 R /Prev 63 0 R >> endobj 65 0 obj < {ok, Function, State} | CompileError.) /Parent 61 0 R /Dest /__WKANCHOR_i /Count 0 /Next 66 0 R /Prev 64 0 R >> endobj 66 0 obj < {ok,Function,FullName,State} | {error, Reason}.) /Parent 61 0 R /Dest /__WKANCHOR_k /Count 0 /Next 67 0 R /Prev 65 0 R >> endobj 67 0 obj < State.) /Parent 61 0 R /Dest /__WKANCHOR_m /Count 0 /Next 68 0 R /Prev 66 0 R >> endobj 68 0 obj < State.) /Parent 61 0 R /Dest /__WKANCHOR_o /Count 0 /Next 69 0 R /Prev 67 0 R >> endobj 69 0 obj < {ok, Result, NewState} | {lua_error, Error, State} | CompileError.) /Parent 61 0 R /Dest /__WKANCHOR_q /Count 0 /Next 70 0 R /Prev 68 0 R >> endobj 70 0 obj < {ok, Result, NewState} | {lua_error, Error, State} | CompileError.) /Parent 61 0 R /Dest /__WKANCHOR_s /Count 0 /Next 71 0 R /Prev 69 0 R >> endobj 71 0 obj < {ok, Result, NewState} | {lua_error, Error, State} | CompileError.) /Parent 61 0 R /Dest /__WKANCHOR_u /Count 0 /Next 72 0 R /Prev 70 0 R >> endobj 72 0 obj < {ok, Result, NewState} | {lua_error, Error, State} | CompileError.) /Parent 61 0 R /Dest /__WKANCHOR_w /Count 0 /Next 73 0 R /Prev 71 0 R >> endobj 73 0 obj < {ok, Result, State}) /Parent 61 0 R /Dest /__WKANCHOR_y /Count 0 /Next 74 0 R /Prev 72 0 R >> endobj 74 0 obj < {ok, Result, State} | {lua_error, Error, State}.) /Parent 61 0 R /Dest /__WKANCHOR_10 /Count 0 /Next 75 0 R /Prev 73 0 R >> endobj 75 0 obj < {ok, Result, State} | {lua_error, Error, State}.) /Parent 61 0 R /Dest /__WKANCHOR_12 /Count 0 /Next 76 0 R /Prev 74 0 R >> endobj 76 0 obj < {ok, Result, State} | {lua_error, Error, State}.) /Parent 61 0 R /Dest /__WKANCHOR_14 /Count 0 /Next 77 0 R /Prev 75 0 R >> endobj 77 0 obj < {ok, Result, State} | {lua_error, Error, State}.) /Parent 61 0 R /Dest /__WKANCHOR_16 /Count 0 /Next 78 0 R /Prev 76 0 R >> endobj 78 0 obj < {ok, Result, State} | {lua_error, Error, State}.) /Parent 61 0 R /Dest /__WKANCHOR_18 /Count 0 /Next 79 0 R /Prev 77 0 R >> endobj 79 0 obj < {ok, Result, State} | {lua_error, Error, State}.) /Parent 61 0 R /Dest /__WKANCHOR_1a /Count 0 /Next 80 0 R /Prev 78 0 R >> endobj 80 0 obj < {ok, Result, State} | {lua_error, Error, State}.) /Parent 61 0 R /Dest /__WKANCHOR_1c /Count 0 /Next 81 0 R /Prev 79 0 R >> endobj 81 0 obj < State.) /Parent 61 0 R /Dest /__WKANCHOR_1e /Count 0 /Next 82 0 R /Prev 80 0 R >> endobj 82 0 obj < State.) /Parent 61 0 R /Dest /__WKANCHOR_1g /Count 0 /Next 83 0 R /Prev 81 0 R >> endobj 83 0 obj < [{FuncName,{file,FileName},{line,Line}}].) /Parent 61 0 R /Dest /__WKANCHOR_1i /Count 0 /Next 84 0 R /Prev 82 0 R >> endobj 84 0 obj < {LuerlTerm,State}.) /Parent 61 0 R /Dest /__WKANCHOR_1k /Count 0 /Next 85 0 R /Prev 83 0 R >> endobj 85 0 obj < {[LuerlTerm],State}.) /Parent 61 0 R /Dest /__WKANCHOR_1m /Count 0 /Next 86 0 R /Prev 84 0 R >> endobj 86 0 obj < Term.) /Parent 61 0 R /Dest /__WKANCHOR_1o /Count 0 /Next 87 0 R /Prev 85 0 R >> endobj 87 0 obj < [Term].) /Parent 61 0 R /Dest /__WKANCHOR_1q /Count 0 /Prev 86 0 R >> endobj 61 0 obj <> endobj 59 0 obj <> endobj 56 0 obj <> endobj 88 0 obj << /Type /Catalog /Pages 2 0 R /Outlines 56 0 R /PageMode /UseOutlines /Dests 55 0 R >> endobj 44 0 obj << /Type /Page /Parent 2 0 R /Contents 89 0 R /Resources 91 0 R /Annots 92 0 R /MediaBox [0 0 595 842] >> endobj 91 0 obj << /ColorSpace << /PCSp 4 0 R /CSp /DeviceRGB /CSpg /DeviceGray >> /ExtGState << /GSa 3 0 R >> /Pattern << >> /Font << /F6 6 0 R /F7 7 0 R /F26 26 0 R >> /XObject << >> >> endobj 92 0 obj [ ] endobj 89 0 obj << /Length 90 0 R /Filter /FlateDecode >> stream xœí][o¤6~çWð\i‰/ØØRU)™$•úP)J¤>T}¨²ÝV«îªé>ôï—`ð|ðÁ g£ÝÍ`ÎÝç|dž›ŸOÿü–ÞlžÿI_ëÿ7Ï Ë Åª?éöçÃáËÒB‰ôõKò–¾%OÉSùï[Rø¼ù¹üí¿T¤?•?§¿þVüXŸ´=áK¢”̶×á¼üø÷áGcL&–—ÇYÿãöä¿’_¾K¿nï–Æ„±yIÈîÎÏxQèLçB™-™'H{KöYf­àJ-àïß^¿&7•ØÆÓ!„`©.2ºHÿý#ù´•ÌØË´ÔrÆ­f…Éáï‡Ô9é-ø¦w/ÉÍ£Nyž¾|JyeLÕ/_£ÓBH‘¾|L¿/.~H_>'*S¥¬…ÚÙ^5ÂønDf¦6ÃvDìFЬ0|û•ƒ‘M5ÒPýrw@g‚IÞ½_~bDeVõFxÞ¿|u ÏJÛÙѽ¦fçÀÉê‹4"îv#¶t =±ÜB­<Ö÷Ñ•Š}ú§BÅ ‹LH<ìF^J‡›Ï ¯'”A¡fPCec›½ƒ>‚GÒ ç>ð;¢²Κõ½ôÈÕ8ƒ´}{°½\÷ðqì`á`ûƒìàû8Ä >˜z—Q,OHôÞ[]F`€/?\äcî‡/2Â<°R°Y˜:\ä²g±žcãï@Ú„Ž!,y'hÉä9ÓpÈ$‹ïãÌá:àÆE§8³[Å·¼…ÞÃáÕœy S?‚¯ûŠFÞ2„/ìû$%' ´O£çTì#XŽQ/$œWp"Юõäd2•ën‚3"ñÀr É’d%{.òç×ñI6DVTùá¹öpñØŸËŠÄ‹Ê? ˜X ÿ¾fÃêžÌ=u,¢3à÷SZ³PÐ p4€Z÷L(8ˆB…-ʆp ãþmüi·'M”ê|ªó¯¿Î—*ïf¯TçSœQªó¯«Î?F›Š!`‰rîÇ"–¶²š2Côë€ÚÃŽÜÑ8’ÑG4R+&ÒØ/ ëJ2Ä¥ !Oâq´ ¡Íã0˜gÀaÏTwƒƒ‡¦Día´ÏÎl±pöÙ{±¡P) …Ó„BÍÙ1I.Ï$ª|¾è{Ã(‹8¥Ãcß1pÄÆ /¤w^%­¼–ªw.‹#M;¢G4T¼ˆy¨DÝ3úÌÃÁ"AÁ­ؼk|¼çsl·pÚc CF#zd4!…zÈ}nûÆ9<­ódWõ$N¶ùÃxh"9^x”àx;¦þ4ø3´È!œ<檗¡u r¦¾Ö»Àé\Å+‡úáp¹, £XZ§ €!MÁÍvO_ou]~êES/z±6tF/Zf¬è5µB,…Z³·„£ÎI„ˆ×GЋÎU³æÜ³Œ+¾P£Bôkµ òǹH@=9¦Š;%¸à^[Ì×Z`0û¡&êâNW‰¢è8;µ.‚»¸Ât%¹FôSªîÜAèç £±ö|£ G?#Màr‘w¥r‡2‘#l@FÁ!Ò{®ò¡z'ðôÊÁSK»¨<=<¥X„Í6;0d6KØ,a³3¦<ŠÙx}dجʛõ‘„Í6KجŸõ…c³­³6{6{ Éõb³­›‚Íži4´2µ¡•©®^ºÒ0g•¤×®z@BYi‰j²…¬xnGŠš¤úb>’&õ¯Eámóc¶óÁ(ñƒ%š«.±Ç¤D`ÉJ,!°dnW÷€%yÇÙ , KTW’ëKdG«`àƒ%w1ˆ?©Æžo×·\÷BÏõ-WËó¡zQYJ¡'”‚P Z F  ë‚L ‚Ý%–@P€@Ab­Zkdï삜 ‚´’\1²  Èy¦AëBÚZr(F±âÆŠQŒ÷ÙÈæ©ö‡—6¸¦÷ øòX+Ãoì„V\áJ¯·âˆ LÖ±/Bgñ¨‚Þ®ð^a‡±Ï~5&aà@ø<´AáOKÁ{ o– P fÐ#”€ðíϪ‘#{³&¦Ë ŽH}<~˜©hhpD39¸Â©yiP–7?8“G÷!hOÀ,çÉgC*“)^ÖñÎp–‡ãfRÐ9µDÀëP.U=-Ë%èÕSh[BMIGñ^- Qóbç€ò¬^Èb2æÔ!Ú€Ù*5G§zªL†/åX˜ =† Û7Â4”µ]á2xél³¸‡sl8ÉÑKQçä¦Â¹|H‚‹WL’OÚ†p_Ä7BÂS”9!åhHÚçyÊîøL‘jOòÄ1‹DRy”íð5©ìޝuCè´>sFTºúòÊÃúcXžF¼ß9þÁa´ÅDSÓ°þ3ÊPɽŽU²1U²Ž,ÚAýY\BÃ6ߥ*%O‚ÊîiÊn¬äõäAfF¥zH©n›'.F\ª¯ø}ôK€æ¯5 ÈdÞ§Œ€]—®óW Vq„l#"ðcõàGÌ)—mwËü2;übi‹ýÔ;Áßy!ÁzÊ`ÂT|˜Š³ÿbj‰¿¬·ûMhϪ~L슜‹Ø‘}%C4…ªgcã¤MXDDÍ ;< ÐÄŸPKF»=ãL¨—ÔÏ\OŽOÕwß*£¯$Ûïл֊šï–Ò_ª£öTÌ–I…Èz ÌÎa‰Rþ¤oå´ÅvS ˜ÕžÒ§äªhcC endstream endobj 90 0 obj 2055 endobj 93 0 obj << /Type /FontDescriptor /FontName /QPDAAA+Menlo-Bold /Flags 4 /FontBBox [-445.800781 -517.578125 731.445312 928.222656 ] /ItalicAngle 0 /Ascent 928.222656 /Descent -235.839843 /CapHeight 729.980468 /StemV 43.9453125 /FontFile2 94 0 R >> endobj 94 0 obj << /Length1 1564 /Length 97 0 R /Filter /FlateDecode >> stream xœ…SMle~¿™ÙšâÖB£Hóm [$ívw m’†EKhÛ¦&^ØÙÝÙ-;?™™í1¦Ñ Ï$’@41FŒ'o$œ´"zâ`£¨hbÄPvy¾ÙÙRÒ&Îä›}Þç}ßçýù²Äˆh­L”ŸÍ^è¿ùÌ8…j}¹òYëÛOÿĹaèZ¹tR'b_À3@tM4°ïÃ>`˜þR·C?I;`wÕí’FÔ€Ý+ª˜Ú’CQ‚ýlni¦ÞÏÖoÁ>A$ÿL²²&]£QäHäC¨ö·å;T‘zµKÉQE’”ßi u›þz•C8t¶òZ™8ñÖãho³—]RMökؽ‰{DJ!rGTÑÈh^TŒÈ'˜V%z>žˆLĆBëž¼oý·æEµûáßnôeÂVšo+k­œØKdO⨲öhôúê*š"¿õ‹2y@aÄ&âQ5:¨ %ãÒøX"Û··/žJ¨ÑxoßÞñìø˜lÜd·ætÃoÞ½|…}|…¥Þzsnj"ÿFáêôÌÙü¥‘ÁÖÍö?|<{ú@’ýð=óØÒêw/¼˜n~•?|èÝ•ý÷Þû,¦Š®Ä¹ûÍê¹Ý'þ·õ}£;†Mwä¨fsÇT֥ͬÜ&‡p<Ø{po… J¦$öªlyvÓ×üâF Ã.†X"…Þ ±Œ[X ±B;é£G0Èç!Ž‚ÿ2Ä*º¸ÖÆøÄè§3zŽþ€SbÈì¡C£ ñNö:Ûâ]tL*…¸‹.H—OÙβ[«>¿Ê³éô+ü¤ãÔu>i•R|³O8Çxq™Ïj æ¼mUyN3ž AÄ‘«ùžïêš9Ü–9Y¯óiãñiÝÓݽœšÒ­º³ëåpŽóÌx*]Îè™ãÊfFÒÙ‘Lú©¿ã ˜‘§¹5k|ÖÕʺ©¹ç¹]Ù4™ZUó®î²MÓ¶ø†M9ª‘ öÉ%42é4×r†–©Σ)|-`l 6§""=°â/Ö  È'§<=`fài@¹ð• ÎÚZ•Ó Ìq¬@¹£ç@£ˆú5èpxlÄk°¬g4_Eì|?‡øÔÿViO¢uS†Gèºtœ åí†ÁN¢b †ƒnĆjT×ÞG{ãÛl1…i|¼£Q¼‹Á› 2ÅD:°:UøJáT{ûÌâ–îRA¦‰˜Î^Î>+èÓ v&ô`\#Ð÷Àÿ¢;y‚[wÕîÜÄOçÎ=ù endstream endobj 97 0 obj 956 endobj 95 0 obj << /Type /Font /Subtype /CIDFontType2 /BaseFont /Menlo-Bold /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> /FontDescriptor 93 0 R /CIDToGIDMap /Identity /DW 597 >> endobj 96 0 obj << /Length 378 >> stream /CIDInit /ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def /CMapName /Adobe-Identity-UCS def /CMapType 2 def 1 begincodespacerange <0000> endcodespacerange 2 beginbfrange <0000> <0000> <0000> <0001> <0002> [<005F> <0047> ] endbfrange endcmap CMapName currentdict /CMap defineresource pop end end endstream endobj 8 0 obj << /Type /Font /Subtype /Type0 /BaseFont /Menlo-Bold /Encoding /Identity-H /DescendantFonts [95 0 R] /ToUnicode 96 0 R>> endobj 98 0 obj << /Type /FontDescriptor /FontName /QUDAAA+TimesNewRomanPS-BoldMT /Flags 4 /FontBBox [-558.105468 -441.406250 2000 891.113281 ] /ItalicAngle 0 /Ascent 891.113281 /Descent -216.308593 /CapHeight 662.109375 /StemV 95.2148437 /FontFile2 99 0 R >> endobj 99 0 obj << /Length1 12496 /Length 102 0 R /Filter /FlateDecode >> stream xœ•y x[Õ™è=÷j³$Û’µK–}%Y’7ɲVKò*ï[ì8¶ƒ„D¶e[ŽmYNb¶h¶’†ÒvHJ_¡C;úJËÒeÒ…2-tt(}ó†vè˜Òutýþsï•ã„@û»ÒÎùÏÿÿçßÏ‚7A l«ñj·Žß3w³gf~uúÑ}±CÿA˜ÿ}6Ÿšnéú A”¼ sÁY˜(xƒ¹‰ Jå0.›]Èø³ªà³0öÀøó©ÉøË[_3­†qf!~`‰h öÀø(ŒéÅøBÂ{(™ð1‚P”5G~‹ái¡ û¦ÎÓd’¤„ …$%øW¢òÿ>Oh*yðÃý­4ÿë„{™ä[Ðÿl&Ðúú:ì~T؇¹‚DÅ!,Â$!&‹Ò¢´Ã*hêù ÍBb Ïk¢Š È2ØY¥Z§Õi,`(R:œg}M§mcÄ ¥*„´º˜°omߤÉL••!›vŠúç¸Ù(´c*Mëo j©G‰ÊMTDb‘SD¥Ó²(E° õi1uv†ú±ZÕÈÜÚk¬oÔhTšt’åiTÅeæò:RfËæ &qÙ ƒe„¼ž–æ‡ÐòœÑgÏÞ’(6"µaý•!HbËú›Ô.ê%Â@`±,9v:Ų¡ &Åøp›U,Òh¨]Ùõ¼ñ¶‰¨·¶ÎÚ¿cçê¿Ì¢›o|üîäÌÛHQd×Zt½÷ÍùmÈfÙ®ý\s úâ-ßyëÎchyå왆(]ä?mô‚º7øÒ`zuZ͆03ÌNÇ*×r€Õ2Öóù-!›•ZܧS,“—*44B¹^fÄõ: ËŠÔ5Ô£¯Þëq#«­© kÄfŠ´¶Æ‰Ì/ë “¼€,+”_O t¦‚|0Z›é¨˜óØó)‹Æ¢8Ö~Ü¿$î A$öæ$Æ’i5›Ü€3þß`­‡^ꊵô隷W+°~½"/O£3lïV«Œ3bT Ö‚«[ʬÕúzÃg™ ؘe"‡aY.)Q*2²d±Ys´vžTp†Ù”ë>U žŒ(Ūɂõ©QëT*çeã`È¿1!FÔ׉5ÿuN£ýÊSTDúˆ´D«w£ßך0 •:ˆ45FSó÷bò‰ìyî´§´ÐnGùEÊæ³hAß«QåÙ피@«ë‰Á.£³H)´ÛÅÓ¡¬Ë8ÄL“Ç…{ Öf,R*8ë‚tJE(HŸ­m·{ª«zý»Þ=÷Ø£ç„{ÝíÍãw}•ùóˇ™êô{×>@m¨éý¿= xï1á,z¬¢¹SYÅÎ ç·50á¿-VðgÎh>/‡ŒjÒÕU–RTß8vWÜÞuÝÒ±»v_ilxàsÌúW¶„-tµÅ¬˜Ø3Úô£=qò1›Å\Ô5DЉüs#Ãhdt¹·½Ó¾ñÕ÷…Ë›Ü@åK£‘ñ£+Ë ©N>Æ\ÅIªTp&YT¤Xd˜ñ¶:=UÕ½ï¨uÐå’^qZ ®Úc÷£€opnûð=×&Í& äáâ"½¦´Ú鵨vW¬GW(«<ÅÜ×RX$– ‡¾ÇbC޲“(ܹ5ª±š@¿PD+p¾>Ö}t¼[}TÌ‹.‰ú\àÓÁù¾Öæ±ÆË@o÷àžhX§ÅiÁ6Iej]quUµK©1ÅNV"–Ê´zSíñcœ’\qp›ÍRY52VQŽªÜ­í'™[¸„!(7N ã‡lV¥¢”nb¤Ó.B*…Q· ¿‰.UièF:YJ_–JQæý x– ì ³‘Â×7‡Í^ƧfÞŒä_²QWÄn(”"$•Ylu.ò{®h™±P&—Ú,a»Ý®É·é§©C3&ƒF£«~ú‘¤Á¨R7Çú‘'YÂŒ+¡Ocã©zÁ9°ã€ë(m¬ÖÐ3¯¿.©‹”ÍÑ’¡khRÈÐõ7Ž]d™Ç'³ßÒò 'µÏ{=Ö“èÛ5“ñë~ ²x "ÏÏWÚÐEëØ¾€ÓÁ›v“£ü|­Ói|ô{uéö쯛L™ôèQ„ö&¿~°>‚ìŽú€™F"\©5«Ôä1ª=»·Î!-äëuýä§'Úk>³g»&ä²XL&‹Ä¬P¨e…zƒÿÉý8‚û!{íƒÀž‹Ì‹ƒ¼ÿèX­„ÀTsik|2õ­Ôuhúà¯î±–…êíÎ[¯V51æ /y­¹¤¸ØTT$ÆÛ`ºiŠùö÷t6H¹rè›Paô1NðÍ"‚9™¤JÈ¿A¨=|$^’å-¯7:6²ñr1BZyR.5è:³Îet´Ö×=:=: í¤«fdû\«742´ùÃŽæéæÝÌÃÝ£\¤U§~Ë–ƒƒ]´¡æ–tæÖ{2ûë‘ÍðÈõááÿxg<‚н © ²Éu M+÷}_€ ÅÜ-gïÅLÍJIm´|ƒmrE,¥…y¹œ²ûÝû¾¾{—»¦«çÚ=ÇKÄj“ïÜØ¡–én;RÑšd.³Ä†zø§÷¸¾Ð]k Ö×^V©ó Ó§áú!üüª«¿-¨Z_°òyp§xi윅sÎúäT " ¹öb¥F µ­ë¹9êž¶,¼Ÿy#;°Ëf)ÈÏ/°Úv’Çþ}"^B¨£+û‡»ÛZ¡¦ZËb­÷"d6Úñ¸ÊÕ×OþÔÕ¼ó3L]ìE sñ"µ´PR¬„¼ŒÊ+‡¶íšèë/¢KáN2 —” ìŸ¶0ýޠɌʬí­Û®íï-)ao’Lõ6Ü$ƒø&ù±×FrSsÏçV6üÑ»ÌÏÚábŽÞñªÔÞ3 ¤76 pMqI+ó^¢¶cf›/Lµ´™D±Bo*:ÈúBYYø±B©w,1Ç‘éT´L§%íva ýÕl/s¡~Øãn‹8ì•Ò­N©Ì\y{3DšàÖîÜÛÖ›/³€ ç(”r#ÙÛÈŠ‚|›uç%º@¶›oÚvÏÄ¿Y”«­±Xëarš9ºˆïLöËõ:3ûù#×î¶èÉû³O“¨§ëþ“X‡ ‰hdjÁ·³‹Ñ&F\VbûÐGþ‡.ÉÔú_S=þúlc«Z…v0ç½r™ÍÚ›¾¬`>ÔõRŽþ_²J7J*;Ë+ï…¦ôË7ºh»]TX «Ì OU2wï5‹Ôèò®© ,ÆifñÙuRlQiöv¡ ü'TB|@`¥BLZhî¾.„,«RðVHÖu¨íG? Ô(§·¿³íÀXÇ`¨®°A޵hˆÅÚ**U…8âd:î9¡'W)}Ê3bûû¿åîÓ‚¿ƒ³þËú¤k§6î oˆ-k¾+uË9DÒmº9V:ùv§ÏG²<£!ºõ¹LÚkoX›ÏåÌ船)‡ÙØSwZÀdµuë?d#˽Ý&sø:½±P‰ÐØ5_g¶æÂ‡Öª.¶3©ã-Í%E|æœËõ/¼<œ¼¶ÜÝÜw¥Ôµ!©Ï9®«pÊm6õ¶Ñ9'ûÀuù+ÁŠ‚pt¾þ,Èøs“±¥i1»ý…Æ&ξ¸,91¶ÆL¬–+ˆg ‚;hiP¡ AÛÚ·¨þ _ÜÁ´1 w =h`ŽA¯ü(ò…î”qI/Œü—÷¾ÑÇ´S¿…)Jô×â[–ƶÑh@ɃOœ¾7×ñoî±ÿs¡ÉǬÏ+¶òȹšCå^vmÜ8È/ è׿èu†"‰®ÞòJ!*†×êHwˑѶNÚ‹£¡ºÊãrØŒÍéö–æÚÚÁ¹£ÓS‘è3÷…êP]èÁ§bžµw‚öûË+‘£¬Í ,‘I îA;øGØÈÇ:0÷ë®l[žËÍ*‡mó•Þ¢~&ëµuÌJg¨®ãë3Ã(àÛ9> ø£yr½>ö©Þ9‡Î¡Õ nmÅ5[„}k?^TYJÊÒb´TóÅÃÏ:°Ò‰ÁÔŒŒsºâBè³·ßTtÿÀ™µ«Ñ1ì-¿`Ž‘³ « ÇäÅ›§ˆ÷â_ ã®˜V/•#¡Ä¨ïr1ÇD/VæЧþþ^<ß®P–Væz£”¾ ñg³ÐkÌ¢+¦ÓÊ¥H§7vº„}4:àZg2&„ò=V••c½ÝÏ<@ªØ»[Õe ÞB}LE#í¸ÇµbõÔ ]1«ÂuÎÓžsa@ÿû/?&ËB>c­à·èC÷ñM±l›ê-ðÍ!O½‚–Èòêú2cL&µYÃÕÙzá0Ͼ¯Ïþ§0¿ºjã)p9j•áØ·ÚêªÈJô2u#\Ü-†© ‡/ ø·×ª?¾ÐžÐzK¡i!•…FƒGº“Ÿ1Ô*|»ên@ν›D¹Œs¥´ÄʦÊËhgy«óÚ¤!:êÊFpRHÑı†k´asïMu!KÑÚŸ6‹!ÐF¶žD)l5ðûªpzKö÷11_“¹«òñ½F`#”E 3–°аq/ÓÐ]ãî@ÿ[…ÞêpY³K¦Z+"‹ç~ø :|$V6)Åv»ÔWû9Adí±Ëih»NQ¢TçÅþ ýœqUë˜àÄföw2eî7§\&r8á˜| ñÖ m´=6+zrß»GG<ž†ÆÄÌáþH4ü9«X¦ÖyÑ‘Ôa¯÷B бQ¸ïfW Effž>tcsL¯& ª‹ òI{öafÏÍÖh™™‹·¼ñ‹­‚\ÿ>T¼,ÛF¹›î’7‡¢œ„lJàéÜ%2àTr· 4Õì‚;£«©ÉårUý)ŒÝ}«#QD—TØuZD"pm‘B$£F×&Ü —Ü{FWÓp¡îÓÍ»ë UÖRÄ%WhÅe ¥ZåP5¦to“1“^+Áþƒ³r?¹»°þ=ü÷åpªvˆŽÀmL±…i'¶sCñ,Kió_XF&2LT ÒDu'1O€Xÿ ŒÛ…ß'äãÄVAÐðm€q1À;D½T1QsvxZ`ψ±t¢Öa¾ïŽv 5ã'a<ˆéÂÓÆFXÇ{‚?~Q˜pÃ3óvÁ=„“rÝøG/nà¹a­æÇa_ÐÚ¯Áƒç”øN¢ðz0oX«$_ÿˆ¦.æñM$B*G_C¿%=äù•GÝN=G½-ˆn€ÿ§kÂí„ðáÿm½*¶‹÷‹,)–Ü.y=¯<﮼ŸHÒ°ô¤ô%™Eæ–Ý&{Uö–\"¿OþçüüüÚü}ù¯È ú Nü•Õt˜Øû*ÎúÛFý‰ øõ9ö“b1K؆I0ôQ¦ˆyâ3<, ʉ³<,ü <,"ª‘‘‡ÅÄ˨ƒ‡%ƒ<œGÜNªy8ŸêÝ”‘€^â—yX@¸Å¿ca!ÌK%R•5 ‹`^$iäaá´±°ëM2Çà+Iš…%0/—œæaQ-9ÇÂy¼þ9˜Ó?súç`NÿÌ韃9ýs0§æôÏÁœþ9˜Ó?súǰŸ]ò3†³Kþ•…e0_”WÀÛG³°Ë–7Äà OÞ8 àÜŸw˜‡„'ï8 +X:/ò0¦ó* «°¥"Jå,¬ÆòH½< òH›YXójé" ¿”ã¥eñŸæaŒÿ]6°øïò0àË8^&lSY„‡Á¦2ÎvfÖ¦s<ŒmÊÙ®”Å_äaŒ€…˰Megyl*{‚…+±~d¿áaÐì,Œ+“T.åa #gm!Ù¤É&ýK6K²é\òMøòMøòMv‘çìò%‚&¼à"Ð01K$ໟH‹ðdˆUb‰i…Q`ü‡ù$‹á†•ð½yø‚¹ØŸ!–ÙQ¾€½>§sÖØYšØßûY¬ÌÅR  yÀ»œsä*ûèb”å·ÌËFC/í†sÕTt“Ä$¬¦`=ELýŠÄwÃ=íÀ&¾׋<‰m„k“ÄÃW•1É®Äáɰú›¼–&ö–翯{Lu‘¥ÈíQFXÛ4H˜aq<çE˜­a)Ð,íYöì4è$E¬À*–+Éb»¯ ÁðÔÆÊ°Ÿå=ã}šÕ-^ump^Ý$`wž4«LµfFYü /M«¬, ú>ðÉ1V2šÕ¦³Âúw^NŸÓ,Å {><^bÏ´Àj!§‡ voNGí %üþÛ›Þ´²ÄúÆp™d)rºÝÏòš„Ï+óåÆwλžbŠÅMÁ绾+Ü 8+p¼’<…IžwzOô‡Nžbµ¹Êúqü–f½gbƒ×•äZüíO®¥‹Ô§6ìœf}ƒó’É ¼òé/úå¥rE7韄;K†å—ónLŸ;ëÌìgOžb#æÊ'å4¿D« ÞË/÷u¬Õ à­°;±´û6<—£ƒ1çãcmô%ÚëñéáÙÝŸZLeV—tk*½”JÇ3ÉÔ¢›n™Ÿ§‡’3³™ez(±œHïKL¹‡“ ‰ezKb?=”Zˆ/ÆRóS¹Í‘ËÖh¼M¤—p{jéòþäd:µœšÎTlžwû°{a+»sp›‹%<|9Åä2§3éøTb!žÞK§¦?Rz:¹Hg`md1™ILÑÛ2ñ PŠ/NÕ¤Òt VÒôdje1“N&–݆ñG[:¾?¹8CLO''´ o^œO¬Ÿtr9µXM&'3@¦/žžJ,fèÚ°Ï;–Z¡â«ôÊrø‚œÓ)X‰/ÓK‰ôB2ƒe˜Xe%jékÕ4;XJ§¦V&3XÚý³ÉÉÙM{á;¹89¿2[3)z*¹¼4 à°+ “€ìÝ4cžZœ_¥Ë“tbaïºHk1‡}E‘Xô)|ætbT2‰5¸‰=«KžV”• < \2‰¬ît¸N¥ö/Χ⛙‚ÐqNTPö†ÖS+™¥• =•؇• 8³‰ù¥ËNÄÖž6Vq¾ZUº;C¬ |˜ëªû.bN³5|«ƒå“¹*6G…»Ïw©ïÀç?^mÏ%¸¹S%ÿ[:à°ûà{¾÷žY¹êþïèdóØòUwæð:@óÐü h¼sW×Ï¥ø9:˼~SŸ˜óÅ£,tµ}VŒæ÷ô'Ús)ö ¬`m¯@}á*ÈÕ-t¥=›­võó^‚-(4 ¢‚VAPP'h4zá«Qøˆ=Ÿ4^.böbm Z€¯¶ç"f/¡K`ñ«Ÿt.R l°r•=x}lÿ“üÙÀüÿ(Ûªj endstream endobj 102 0 obj 7472 endobj 100 0 obj << /Type /Font /Subtype /CIDFontType2 /BaseFont /TimesNewRomanPS-BoldMT /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> /FontDescriptor 98 0 R /CIDToGIDMap /Identity /W [0 [772 276 551 440 440 496 551 716 330 496 330 716 496 826 386 330 330 440 248 276 496 386 330 716 661 551 330 716 551 551 551 716 661 496 605 772 772 716 565 390 248 390 218 661 605 565 248 496 551 330 330 330 936 661 716 551 330 ] ] >> endobj 101 0 obj << /Length 756 >> stream /CIDInit /ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def /CMapName /Adobe-Identity-UCS def /CMapType 2 def 1 begincodespacerange <0000> endcodespacerange 2 beginbfrange <0000> <0000> <0000> <0001> <0038> [<006C> <0075> <0065> <0072> <005F> <006E> <0077> <0028> <0033> <0029> <004E> <0061> <006D> <0049> <0074> <0066> <0063> <0009> <0069> <006F> <0073> <002D> <0056> <004C> <0053> <003A> <0043> <0068> <006B> <0070> <0044> <0042> <0079> <0050> <004B> <004F> <0052> <003D> <007B> <002C> <007D> <007C> <0045> <0046> <003E> <002E> <0067> <0064> <005B> <005D> <003B> <004D> <0054> <0041> <0062> <006A> ] endbfrange endcmap CMapName currentdict /CMap defineresource pop end end endstream endobj 6 0 obj << /Type /Font /Subtype /Type0 /BaseFont /TimesNewRomanPS-BoldMT /Encoding /Identity-H /DescendantFonts [100 0 R] /ToUnicode 101 0 R>> endobj 103 0 obj << /Type /FontDescriptor /FontName /QZDAAA+TimesNewRomanPS-ItalicMT /Flags 4 /FontBBox [-497.558593 -438.964843 1352.53906 891.113281 ] /ItalicAngle -16.3281250 /Ascent 891.113281 /Descent -216.308593 /CapHeight 662.109375 /StemV 48.8281250 /FontFile2 104 0 R >> endobj 104 0 obj << /Length1 6832 /Length 107 0 R /Filter /FlateDecode >> stream xœíV[lWþÏÎÎx}Ëú–5ñ-Çq¼vÜx³õ5‰›4Ávš¨Î¥±ãPŠJÆ;c{âÝ™íì¬/Q…ªBQUU•Š"õ!ñ‚¨ DEB¨HHP!„DAˆHQA°ùÏ?g×»ŽÃÚÍ ÞÕÎ~ç?ßûÎ93 Bð(ç'õý½féy´¼Š¿+sɕكúOÿ€½0oê†Ñræ€@mCóh¨zcõ Ž¿…ãýó)o¹ò:»‚ãŸá¸*é$t0á×8þ•È’Ò—Ó Á1ÿÇÜÖSæ›×*nâø@ã; (Ãìë BH½¡öÃAÖIÿÊ[0¨cj  *jP-W‚BÅÀò(FõÃÔÙQŽˆ¯ÝS_[=ÅúËÚÙ»'€ýø÷ÿPžS'D6B€µ¨-*¡  ½¶½¶/¬%÷¸rëÞ þ ¿§é‰SÎÞæêÁþÚGZ•WVþÒñcû:µ·µ }í‰Ó'¬óO±ŽªûÆã³ƒ=Ç»:F® ]eA¥¾á­þ¾\õÉ_¿~ìbãmüˆ¾p…"ÈÓòFô)k_‡ËþPmöW½à£hì90 —•æµ»8Þûî±x Wr;eÃgR¹Cñ¹êG"f@¼,±ixCâ îÏ Ä*´±¸ÄÄÙ9‰ËàìK‡ ˜¸¾x^âêÀ %¯mPý¦Ä Âê/%€¦~(±‡Õ?K„ˆÖ&± am@b >£J\sÚ3‡ÐþžÄå0ªýVâjv¶¬#ã2a®]¡«!Z&¬’ýÛ û;„5¡Oè£&¡»„Ë„½¼Ib´—G ‡È~Qba–p¹Ð¿üºÄ¨ùÇ#¿¢NbÔ¿¢Mbô­xMbÔ¿âG£þ¿‘õ¯ IŒúW~ 1ê_¥IŒúW½J¸BôŽJŒ=†W¢½!<#q‹„«Ð^þŽÄAˆ‡ýv¡=¾#qºÃ#\#â×4IŒñkº ד}Zba77ˆÞk^—û­¹Ix7ñß—Xðý~#Â^«IŒöÚÂ{DœÚÏJŒqjÏn&þ5‰ÿe­ÄÿÄ‚ÿá½d¿+±°ÿ‹ð~§.*1Æ©óuë!ûŒÄž&Ü+âÔÝ”ãÔ‘†!Ò¿î‰ÿO„©¯ú:‰Ñ^Ï®"~ý9‰…ý „i]ê¯KŒëRÞÆûÞÉã0„h æñþÀá,8`ãσ<ÙÂ2Š#±¸êh·ˆÙ“Ä/‡‹h›C242ñßDö"^ dNá|ЬÎáÿ±´éé úéÇ‚Ä}Ù–ðåEÞGašòfd1»èC7Æg2ø›E¿ÛŠþ Ø1è‡å‚H~œõ(`z7t9U2³E3:þ<ÒÝ@Ž˜sam¢þí¯™ˆjSDßïŽ,‰UâX¥G\Sf¶Ñzˆ"pŠ=Oýs¬ß,Ίº,bǶ]Éý¼©<#æÕ:‡ãóØë,é&f{ó•Ú¨¦‰^~V—Q¢ešøž¬~‚t Šª9< GpÍúàiê„“®"N–ö­¯¯ÿ,EôH1N“)R-§Û ùæ4GU'ðdø¾nÁLšöžYÑ_‹%Ê•Àëæyý±à&°ß,ua×Á«Aóiœñ;ðWÍÏeÉ Ëï^œ[~_穹BçÄÂsÁi·ÍäsmV—}_ì­«´Ýȯ³K{ÉßU‰üNÙ¼ûõ}\\×H¢¿òåö ˆï÷j e‰:wè„mÞ©¯´^¤ª)OÅÆ³!Tõ—%OQíb~çúq3‰Œÿ¹Foó¾x|ˆOÍ›ü¬c;ÞJÚ䣎›v\ݳ;ÆO&“ü¢57ïeøE3cº‹¦›²Rf†Ÿ3—øE'¥Ûg<=i%rîG7Ìrúè´éf0"ŒÅã¼û¬•pŒ3ëØœ^ÈŽõ/ 9D¹0Ù+SNmt¶2\çž«fJw¸3ûÀθesç.Ù–g|ÒÓ=Œ¤ÛÆ!Çåθ<ádmϵÌLìAAò¶)qsõ%Ëžãçgg­„É{EP;i® «keû Ÿ¶†ŸÐ]ô=þè‘þ¾§,Oé+<›1±¬ÖÁ=ÃÓ¦›²> /FontDescriptor 103 0 R /CIDToGIDMap /Identity /W [0 [771 275 385 ] ] >> endobj 106 0 obj << /Length 378 >> stream /CIDInit /ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def /CMapName /Adobe-Identity-UCS def /CMapType 2 def 1 begincodespacerange <0000> endcodespacerange 2 beginbfrange <0000> <0000> <0000> <0001> <0002> [<0069> <0073> ] endbfrange endcmap CMapName currentdict /CMap defineresource pop end end endstream endobj 9 0 obj << /Type /Font /Subtype /Type0 /BaseFont /TimesNewRomanPS-ItalicMT /Encoding /Identity-H /DescendantFonts [105 0 R] /ToUnicode 106 0 R>> endobj 108 0 obj << /Type /FontDescriptor /FontName /QEEAAA+TimesNewRomanPSMT /Flags 4 /FontBBox [-568.359375 -422.363281 2000 891.113281 ] /ItalicAngle 0 /Ascent 891.113281 /Descent -216.308593 /CapHeight 662.109375 /StemV 48.8281250 /FontFile2 109 0 R >> endobj 109 0 obj << /Length1 12688 /Length 112 0 R /Filter /FlateDecode >> stream xœ•z |Õµ÷Üm^´YÖ.K£e$y“eÉ’"ïû¯‰·8I/’mÅ‹/Iœ!% ”šR–R¶B iIZZÖÒB€R^¡¿öëúµ¥~Z(”Ò¾î¶Çß¹3#[ ô½ï³=Ò¹ë9÷ÜsÏùŸ;&A2âADwoI@Ó´#57Â3<1½<¾fqÌýA8‹&ã#±øïZD.Ô…'¡B‘`OA¹ʮəÅC’.å\$$›NŽw0-Á…öëgFÍÍÄ>‚p‹ LÏŽÌÄ7ì Ê.‚Èš"(*„n&Ä„L|‡830ü7u1Næ 1IJ(±HLR¢·ˆ‚?÷Ù‚s®1[<Å´{jhºõÖÿxòú“­­ÑÈC¹õö¡•§VÿíüC{?ÕªG(×ì‰ä ÁÿßDÔƒDêpê |‚9uy°¸‚a@›.­‰Ó$êLÖÕÖwm‰X4ŠLƒ¾Ž­ÖÖ€*)¥Úî, ”…Û²2óÌ-ly•S#ÏæÔ©ó)PŽø¦µÑe—£°hWÝCìwvØŒ‚BU]¨ñÖŸQ‡ÑÔÍZöêôJ5r¹PnFže€ªº kVåÄš­¿M¾–PŽ×á‘K ¹ü9e;ÕAAÓ!~AÜIàêðbÈ›ížòª]-Eˆ¶í½åßО½K}Óv­^n·›{ºG›Š ý›o)*îê8î ªUÙÔöŸ •!Æ]´Å›ïk»ïªŽNk&2¢–Ï4·ä{£M%¾¶–Šèà\gÒ)‘Lj€SÙ¸þŸÔ“ ¯†`@b|â8KÀg0ÂM½#eAZ’øñÕû*¯˜˜¼æÇË“¨¦jb¼7\®¦§ëº‘ššD+uÝuò‘«¯®­CÜðõ«¯:ZY^k£»{Žüàì-¨§û…?ß8 º"Á­Q爬«”ééÅÎà@î̸¥!»Z€÷ˆ!jL&U+õ6‚ý°ø`UuSW$ªc’+Ìy-¨®¸°¶`K¸Ý’·“:·öÚ=F®P;÷_:f·¶4C·×šŒ 9bÖî<æÍGfS')íÌ3“XD8+%X¢K%I™ßÇMìRd›Œ­lM^§Ke µÞäU#µø¦•ºKœ4RÈ­yTíŒ#e³ìytñ<»&„]̘rýXß`öZ(ÏND#(C¦f4ðXn&\ ¢æ6ö|‘£µy[Ž"iÀôÊJ­Ø398„=¬bÐ$D–b¢bao)ñà5/w7Î;^Ø ¥Ü¦£@W/ïˆÅ“ì­l¨Ì¦P(U(é ­=ìwk-ÞŽ úðÉñÖf´­÷adnjJ®ViòÌçb#¨{ÛñŠQò0‰à—=pÌVÄ0[l‹Ôô5t!bltßÀâÕ»>ŰGNe“çHÔ×{Ý5=ݰƒ°„'Aç&¢0åAµÂañ¤;HµZ8!©€*NÜù™Dâ¾îÙÞ×/•©Ôú¼|Ò¶„£;{ººzÆÂeùä_Ÿ@‡ÿø/çŽåY*¨oQ8®kÞµ_Œ&}ïÂðs.Áû!òq8>(h7¶C8µàs.7!>{8ƒè˜?=7š\ÎÂ"m޶Ørá¼V³…MNìÆ%2•ÆH»3‘–ºð£W‘ÝYè1›a5ù{ضN·9'FëUNÕ64v7mûÄÎdÊ]ÿ#Y)zްc‹ jg!¸qPBj'gMáÚúúë&C>MÛÔgm]C È¢=®ˆë Dϱ?m^{dÈF#­&´4`2ú}1rÒ® •µ2ã˜WÎú¯Å€ 9ðúñŠ‘ñ`° ulP%~¤• {YÊ<*“Ó]Eì5ç!T‚†P­!K^“8[ÜÁ(è@låjÑÙ¹¶•„a2uzW`ßê;”zÁg±³=[-)+PrV ø¢ÔÉÐüwg1¿ÀjnÖ‚«Õj¹)²L†:¶¡A¯SÊ3d •1Ï£@¹â›R]ð§…u¬Ñ+öñüAE#çŠmŠlNë$ѰþŸ"1Hã&"›x%Âã’PºM¦{.Þ_aËàÉK5um·ÎíG誣Ïêá,ÔT(GêbΙ‹³Ø|«µ4èjܲLïœhÉ£ÑÕG¿ÿÂ÷£Ž‡RÁeåÍû?ö2úYC4bµt'^úá¾i˜³Šm¦~VÛD “ ;·¸zDqNÝéÔ øJ"Ä$á7uÖ4ææ}?ü~*J9)\!Ù<€7 õ£Éø½ÇG.Ȥ”‰(©¬ð`¡‘Ñšš‹ LªU~óþW«?µ%²ï®^:Ñž¥ K÷†rõ(ÏŒtí¥Æ²žö@iSY÷%ªˆ=ó­þ`èö_£.o{ÛЩÑT‹%ÉÔ™2ÅÕ:wl×n”ë¶X5j•Z"&ÅŠÈ–íûÇn, L}Ƙդ§~y •W.i°>=|÷ÎúÕkË ‹¿«ÕÕ´õZ±¬½PÇyñ$û({ˆÖ…Cž3B°$¥v~D¨ó{WßBÃgoîwmcãäÄ$gëƒÿ¬B£ÓE…N‡‰ÙÕ¿òǯíÝRÌ=Û7õÙÉñû¾Íþ!"“š Å<"þ-õ8p×ù 8 …ކß,@º•€ÂÆ-[QKóâÎá;¯º¡†ÆÄÔÈ¥kg_lŠîU”[}~W4¿¼©¬Íh"¿ôîWì­Ew¿È^øàÛÚÑožûûÛ‹ŸGÿüyTþî ~{Uï7=|z€$8*Es'M'-œæä€ùGh«eeX­»Yrož%+eÊÔ¹Fwè¥{WNÎ[ò*Ä0HPõ0ùËs6•ÒÖyÖyf·¥D`eBªµ›²@ oµŒ`ƒVª— § lv§ïõ•ŒÇ¾? ‡Ï_(½xijUW À!Ú†±Éø8`³1ðåÙ^ˆð-M³Óu`FL yþDO÷à‰á=íšïìêÙwºsbîæØ8:<¼¸shÇëÓ5U=‰Êr´ãÄýƒõO­«»…}ÿtiÀ sMªªJ=SïlG“­hk{`ªn—«¶nø‹¢­§:Úоž¡ÏßعûðÅk¿ŠàL[ô:$ÛhIà®éîöˆÕ ™5³Ä×P×3^Wó $³`›E9ìx=Ȳ‹rVÞ9Ùæ>.®¿-þÑ4\ Ñ¤®Ìá¾9)!dÈѱJ­~áÅ2ƒG_¾ÕjÍ•ýø9 ÒäF‘}‡—ýQþ;ì_öçy–¼ ê#V(-táÚÑ×OVêå"†éÔŽ\íÚŸÐJ˜Ö(•$Ã(&Wß'ÛÖ§È6“A’¿³þ;ñÃ|.MÙ¶S§SÈ©õj'*yè£Kå_n§ÍQUww ú™À¥G®Õãf¦ÇÏzK]º +]n-w¬J)ÅQº€aÊèù•Ó¢ÆÕg®²A …l Ô…F½67tÓ ¨e+x]àŽÒ"U0Í£z„ÜJ›²^j«{jæø] ‹×^ó퓃ƒSa…5G$u¸ªâ•Û¶uŸé‡ÐîdžG¯;þÖÏNžÌ×áÑÜÚŠrÚŠÚÆîyàèÕ¨±ø0pï†5ßH” 85˜ž%9Át9gÔm"˜M¢ÕµèA@vÕ½koæ{í´"û›ß,*ܽsÿäP9 «ÞhbÜVš)±ÙåŠ¨Žµ9Šp.ätŒ’;[+O ï3Òà‹ØŒfµrK(Wc0B¯Õ·r7!zv{U=uðÔº¹ÓÌû˜/¯èVûâÊoR“Ÿ.,R©Rg™Œ×}±¦°ïA){3 É%jŠC“ Òêlôòê×zmZHÌõºJœpÙlõg°Ö(g­Ü¦yº¼ÅbP#Ùt7ØÉs[€N6:¯-Öéíÿñª I3TêBTàÖä2Œì áÁ¡žJÆ ¡Ëoz²¬.SÇ>®´›”ú ˜°Fkñ4±ôOo~NF¦ €Ž8+Û®¨Y½¾¡NcQÉ™mº›|ÔZ⫲±Ôj‚øÁŽâö6MŸ–KR‰nZÌÁQ©~3 løê+jàJ¸D=±œ¢PY°¿¦J7ÑÒÜÑ8tH‘i6U³•šr‡.KdööCJ×A’)[ZØÒp÷"d/ꎔõsøª­¨†S(à+þ6⃘’ÑiQipÏ!7øû+ްmzN–yd{&YR‹ŒæÖ¬B¶=•FðUõBK YŠ"¬v§ÙŒA`2ËÚó…"ZÀdˆ¨˺–eOÝ[àÅ)ç¯2¤Nè^¥;KCB½ßƒ^²öœ¿ŸÑÝ¿×r¹%n•¸ƒ½ÔçŠæ™Wþ¼q´EÙHžŠìBÕ“üƒÝJ=»RLÔÂIc‚Ú4@àá“Í» ÝæÖ¾xrÛ!‰Lîæ¶æž3»çЩým ç—fgZ-í,mŒx4IÁÒr¬•eÈ·„{cÕÛЮºÁRCEç_?ðOú§Þq i•Åì{{ &¥’aH}¦I§Fw Ù ø5ìÃsŽŠÂ¢®ñ'ÿ×þ.CÖ xÉŸ@_¥~²7 ÙJ9LÉeíˆj^û3ï±âFÁx¶£cèô6:¾ò€<¬ÖgýƒNÝÚ_DK«6}ä¡|‹VìüBĹÐÕ3›MgVnÉή¿’Ä%ÀúsÒG„B²Ù}à}ì¶KT ÔãU<‚UAÙ—7ïMïÏ›?yhíiŸÛ ϲùýÜ-ª ¥Ó…~ä ØŽPÓÜí(w{ºzn’6© ˜ !ê·àIªÒâ !b ŽDªp=B/8E„ps!_¥vfêëÚ[‘*‡Aá€3ÐwÕÛ}.W”í)2ij¯ÿ\£^W̾æ23»ž}d«7¿ \ ’+uÆRµ}rr̤UÊÁãQçþ¯°OÖ›HpÄrƒnÏ /ìV4Z8A"­åÐúêTžP¥Š ÄÅS œÃÙ %È„‚hÚÈü<´ö_»ÈjcûûLÁjô¦ý,Zâë]{o[žÅ;û›Ð÷_ïqÓ:ƒ”a”ÿçD»Wn;í)ÀZ¯s#9éZû%öc:s^é}ÓÈÍ„R.X¼­öµ×uI³Uê2TÒ8-ìÓùì“z ¤Š¥Ø§æÚœ~VBÊ#Vy¦R"MˆUÖæÕ)qØ SgÈ*ʆ\­Ljp­rù.q>’_4Ú¸—ùF N%»ßk“K¹º©7´¥öý÷Gœ~—±šm`”r/û[¤ÈÖëºX_³S›¥änµj¤ß´:÷Zƒ&;[£’S4Mé åÿ›}ãˆÝ/ÏÂ÷„Y¹º24ÁþxÈ’—• 5êLƒ}U·Ë{Ëß õ±[É£°#μù+A•ßyoÞÌêuäÑÛb7wuÝ~û_t÷¸=v£›©©b“LÇøÙ_x …ZŸ-h~Ë /¾Æ¾Ì²ë3LãÁ¥Ç¾ýâkÏônïêÀš¿fý-È’§ˆ¶ûN.}ÒJ6rK!s ñyùէǽyáÏÝ2S癟¿pWÂfQÕïžiir3èÀòÓeôð˜Ñ$W‚)‹¯LÝÚj΋zy¤­âòþ¹¯OŽŒ9Ê,ñ[x²§ÛïC5u=ÕÁŽ£ãá-m[·Ý9»eˆì6¥Ê‡~rKëÖ}ýÎÒ²`‘ut¸"ÚÒÜwv*ÊÀG¨•øZ’x‚Š£ßÁú,Â}H ÈÓ®¨°ìè;ãŒ9;S•™cV{h›­hKSY •‹§ kʼe´R‰d8-îh´oi´æ~æþ?7(()ý] vŒŽ»eÊåY9fU¾•FˆÎ¯h—A SAÅKªBLئTJñô¥y B‘hßÁaîK#»UD@ sá; ôñ€…÷F²yó˜ƒÚ8 |ªÛDMeg›Œ[Ù€&bÕȳw74¶]?‘8sæù¨ßï.]§Ñ–jöw÷ ÞžÅòuae|È`’+À¿ª3­fˆìÓž|„/ÿðÝsg‘Jm³¸ÖJÐ#[‹ ­V´gïsO›8Ÿ; ÙÓ2æ‘Ô. éaÚ«"Þv"›¶ƒ¨å.vreÜùé¢úúm‹‡G¶èu.£VSÒÞ¹4´£»çÌìÓH$îxø1ï]§ŸÚµ»¦Î½xƒf½IevؤÁcG¦E2R‰¥(_ò-"Š5Æ¥ýÁ”aÛ òê‹©"ãî©qðIô5T°à-¨”k¼ùýìë2©VýÍ|¨Ì_Uï]Zyß_Rd“g"dtõùEZ¥Gk4—æÇÄäÚ»Nß"ëÍsh5ˆ­Û©Ñff#µª¤êjökŒ^EÛbÔþk­^†}c_¾WËIüUv9 v$Åþ^ ©ÚN³­è öWÈÁî“¢î|÷kg$Å÷Ó@Ÿ<íЩ:ýJ<õw¶[ƒ^­ë¿†œj ç°Â»!zãÍnó6`ãÕ%ŽÜtêî(íÕ¥è=PHßágØÕë÷··^>¶µ¥¹N©¶Ù·“rc·%w1¹ÿ{ð•Ûâž{¥­º2ÉÕ(ä Ûw϶¥WùðÒ=÷¶µ£Ü7:5NÛÔ*·»Ì=ÍŽÔXòV¿ó÷o>ð|b0[îÕæ¨Ê°¥3è¢ÝÔÿþgåø—EV^Ƶ°ýÏÛ¡DDQ!ì­ó²¦ËnÆS÷žË\,}POWw®Af|!þÇoïK´¶Î$_ l)¯-+ðZ':Û]®úú¾²nò»tÅ=8ãÙ±sù+“H&mɉ·u_;ØÙîf4 y@µ"HàîyÓ-@.g‚Ç;‚ÉyÐýëËwé#sr®†¿q(§´tí©MüCýQî49\¥Á}`gï»™$êr»rsØ÷\ˆØ×÷ø Á±åd­¿%þH†½ÈÇßYãëçÔ›Kî„hI»$§~‚Þ öj½ù¾ò«…ÅÚá‚\okYŸË„”rÓÖœøt"‘r@ü6»ž[ûù+sóÝÛ:;®ÛñW2ç¨jQ™k~í=ññhü=ªˆîÞù3’ÁšÅVÐrÛUblˆÀ¨UR‰]äq«IþM–šä݇šô¸Éß#٥瞞}Ÿýí3ßCo~÷ïÏœFŸyô»WE§’â)ôÒË쿳?|åôƒï£*Tÿê7ÚN~•ýûè7O£ÏŸCõh÷ùS©÷.ØopÆLÛPÍY–ÂéC­âßÿRsÉ®ùï¾ktøk—Ø¿¸fàÝÛáç£ ÚB§,¦©ùž{ʾýÌ¿æ!ôåû‘î¿ÿÃâ8ßœ[¸“ŸyÐð1£±ÿk3JA¸ÿ(ð“~¡¼" É¿öÿvqí žK¯ÀÕþB:+›|˜pphéà¤ÇV?ŸfXè.v,ÝΦ.ë z¼9ÁÍÔEa÷®¼ÿl¾@å²ûeYB±ÏaCv¡@]¼,gX˵o–ìxÇê© ª—‹¼ÑT\‚ÝF\O]Fný€pc™ö¨yŒ0K†1aŽ—¶2îpc(ŒëÉ]ã6:+Sž©×ê¡1ÞHÀÆñT~Ii°Ü)WȤVP£Ã &<ì÷¸+ŠKªòp=~‘Qpº¢[ƒýøMDº´Är×£WN‚rÄ©WŠÎÔ ²{ãR²³Û2³äYZ½¶Àjõ0[êB44¡Ø ºÌ¬,…ÖÀ£ 7nˆ„멉‚hIqµE!|.³æù!g‰&]ÅÁÒJŒ]¥2Dƒ 8¨¼¢?Þ¿[%µþ6Y xß'Ú'«Ymz_|Ó?Äãvîy?ø¥ã{••Áÿ$tåÏú;lä­7A?ÉF%Œ‘ÚÙ&b/J>âfJÿ©—D™2ùÔ D;<-"‚È"¡AÜO´aÚFá» ÿ“!* mÚ"b}…|úFˆñK„ ·AŸzxðw!,Ð_+Т´>b Ÿh ¡¿,ÐRbBüs–q•@g ’:–£NÉ ˜‰(à•-ý G‹q6/}“£%\ýï9ZÊÕÿƒ£e˜–ept† CžæuÈÓ¼yš×!O‹Òúð:äi^‡<Íë§yò4¯CžæuˆéÌ4ù³8ÙŒV¯À´,Ÿ£UX6Yˆ£5@çÈ8:7­¿–›§Ÿ£uiõFnlœ£¹›ÙGç¥õ±¥Ñ.®ÿu]ÀÑg9º˜£ïÆ´,M~Y¯ì´úìÔZ"hÀj~ø ÕGLqøî$’Ä,<‹Ä21ÇÕ4@ihü9õ ®‡Zêˆiø¥‰íP7㉮‡ï8ô>Ÿ1èÙí3\-MtÁ÷A®WêF`&Ü‚X‚™F`Ì•üËÿ‡ÑôãˉŽ÷‚ 'M„@?Q ”fOcК„ö$1\òÿe ìCiÜyÞ›œ{ÀGuBûÿ$_‚kg‘Ó` úÌp²NA–âÿ_ûxÖYnF~\?”PÂú¦A®E®o\à< µ%Ü 47÷$·b4‘½Írr%¸Þ¾O oƒjäd8Èñž€r7È>Îi·opž…½ˆÃ(~=óœð¬EP3Àõ_¤éàô€5‚¥ AëQ"V9ÄIFszÂó,qů—×ç87ã"·>\žãÖ4Ãi!¥‡QnlJGM ¥°Y~ì|ZËg1à2ÆÍÈëö Çk >?™/_Æ}Ç`½KÜ*b\ß$|Ƹö9Î*—7vç•fæâWOý±•'9m.sÖ›k¥9ëÝàõIrÍ~lîÿw-mÎÛØçyÎ6x+Û°ÁO^ý¦]^.WEšðJøµ,rüRÖçç׃šƒÜʓ܉ùä•òš¹L«qÁʯ´u¬ÕEè·ÄÄÒذ\~Üszü·{ôðûÃtßdœîLÎ&—çâtCr~.9?²˜HÎúèºéiz{bbrqÞ_ˆÏˆÇ|}‰™øÝ?HoOÎŒÌnO,M̧Ɨ_ÑL íåñù˜“ùü¥´·316Ÿ\HŽ/æ§×ûÊqÃa47¸§·³ïÊù ô½8?‹ÏŒÌOÑÉñ)>˜¥¡­6±ѽ‹#‹0ÓÈl¬$9O'¡ežK.Í.Î'â ¾ úðGãüÈÁÄìÝ=>ž‹ÓÅxðìt|øÌ'’³Eô@bl¦é™ÅgéÒh00”\¢gF–饅8ð9Ç“Ð2²@ÏÅçg‹X†ÑeN¢¦þŽ:hç sóÉØÒØ"–öàd²²Í±ð˜›^ŠÁÐÅ$K,ÌMXŒJ@‡1èì}4bžœ^¦½‰|:>3ŠGmÎ5›êý‰"qÝcxÍóñPÉÖ`{N—Â\œÞpYŒÏ`uÏ'€k,ypv:9’΄áEeoh=¹´8·´HÇâ°r¡Ïd|zîŠAðIr‡{„;6p¬‘Ìvî{œKOµ¥œtŒw¾ÔÔ7¨g¨ïÁó$õõµ´ypïÄFù×PJç¿l&Þ‘§·ÏË"«¨TÔ.jUÁgô²™fa|ô;Àp>äL¢‹è^@µØíÔAÏy!<ÿò(P endstream endobj 112 0 obj 8350 endobj 110 0 obj << /Type /Font /Subtype /CIDFontType2 /BaseFont /TimesNewRomanPSMT /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> /FontDescriptor 108 0 R /CIDToGIDMap /Identity /W [0 [771 385 439 439 496 248 661 496 385 496 496 275 248 661 496 330 275 716 275 496 496 496 496 496 496 330 496 496 716 716 439 330 605 496 771 605 496 881 248 330 496 716 496 496 330 330 551 330 330 496 496 605 330 330 716 559 551 551 716 716 716 716 275 439 439 275 ] ] >> endobj 111 0 obj << /Length 819 >> stream /CIDInit /ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def /CMapName /Adobe-Identity-UCS def /CMapType 2 def 1 begincodespacerange <0000> endcodespacerange 2 beginbfrange <0000> <0000> <0000> <0001> <0041> [<004A> <0065> <0061> <006E> <0009> <0043> <0068> <0073> <006F> <0075> <006C> <002C> <0052> <0062> <0072> <0074> <0056> <0069> <0064> <0067> <0032> <0030> <0031> <0038> <002D> <0033> <005F> <0077> <004E> <0063> <0066> <004C> <0079> <006D> <0054> <0070> <004D> <002E> <0049> <0078> <0041> <0076> <006B> <0028> <0029> <0053> <2018> <2019> <0071> <0035> <0045> <005B> <005D> <0047> <003D> <0050> <0046> <0055> <004F> <0044> <0048> <003A> <201C> <201D> <002F> ] endbfrange endcmap CMapName currentdict /CMap defineresource pop end end endstream endobj 7 0 obj << /Type /Font /Subtype /Type0 /BaseFont /TimesNewRomanPSMT /Encoding /Identity-H /DescendantFonts [110 0 R] /ToUnicode 111 0 R>> endobj 113 0 obj << /Type /FontDescriptor /FontName /QJEAAA+Menlo-Regular /Flags 4 /FontBBox [-558.105468 -487.792968 717.773437 928.222656 ] /ItalicAngle 0 /Ascent 928.222656 /Descent -235.839843 /CapHeight 729.003906 /StemV 43.9453125 /FontFile2 114 0 R >> endobj 114 0 obj << /Length1 3372 /Length 117 0 R /Filter /FlateDecode >> stream xœV PTçþϽwwQ ²° Mˆõ.ËC ìÂ.°¢BTÞoe ‘ÇÀ.°°è¾\AjŸñk(:ÖlÚ´ÍÐ;‘qÚ;H2;N&cÔiÚXÛqªXƒì¥ç¿»øhœiïÿîùÏÎ÷Ÿïüçž½!AäMÂRnÔêÜ?Ššý8L­¶î–àûšV”ï"«²ZÌÍÍA…u胺t+*‚3=ηá<Æj÷lµ„ÓõaœWÚœMæ°»Šœ?Ày¢Ý¼ÕE~@ „,àqÎ;ÌvËpÐÙ6œ¯!„½KXn  !½ä]Bà‡þ_öiaÂaI°AÃpßè¹ÏÉwB–!Yß’ÛLÖ~Î'U 8!³Ãm[s·áL/Ý C¬Â1Î*9ƒle„„ËUòX•\eåÈl;5ûá˜,äÑ¿ÜÒåÈUô,CÏEh§R¢•\e;}•ÌŸ›ùíl—Ä;"8F|—FÀ&´ïçzˆ㎋SGˤ‘rµ\¯L7¤ë#"#"¹þU™YÖÔÁؘÆT¿3{õJÛ­Q*m¶k¾/8ÓWk_ƒPy î}onŽ«‘¾B#–42B¯Wª¥ñq¹*MÅL‚6©úÆ·?CáK¸ïôf½öØÜv…>Dîšû3§Æ8BH*z«¥…ˆ0¤Ò ru*(XZ*†¥O D*K›oæræ© F€¬LÛñUÌØØêµÛÏ·´üxÛƒ3ërÞnh0ÕZêªßj2gÅÊC=2\-†ÄÅå%¾¾³M24šN_l4/Ù•µ:**u4^Ë–Wè ‹Ý8f* #ŒÄø0CBüsÉÒEFpQcšîêË͇ÑÑ”J£g¤ª’¹à+b.Ïσںó¾=œéœI—âÚB9÷ù\".&iˆ™Š€ÈR©ˆŒ0 íp”ã£Q—†Ü :šš„xL‚<Ô¿]dšž­ÉÎéÛ›—_·o{Nö(tvýµ´¢²Â¼¡<çhn6$–”Ú®z::<Ù‘åR„Šö3Ô#¡4ÊiÈCŸÒb¬û ðÚ?@Ÿëíéé¹ó->zØ[v‡×kw8ì^¯Ã~òø p[øúØ Àà1X KÓ|ÎÝæÂ¤ ¢ ñ‚\(›h?´·…?—tkZ@lÍ訶¸´ùZ;æh¢¹¬DÍÉÞ½3?77çîìvŠÉþîî€1!qè$D€üä HH‚o`òüqØ4;ã¸oWO+#w§÷lã£é©[väæŽéŒU®•pŽÆ`^~]íy¦ûñés)º-.±*0_&ÌW”ÈB©RJýaPÒãçž¿lþ-àL³·ƒLõ¿Ühjp´™k…ÇGŽ:tÏÛÛóQpAўݯ¿!cö×H¿i²,y5ã“DE$ñI‡E§†¿}¬½ªrcµ2Ù‡çüY {èå %?ÖÎË£•eññ'´š«\ÙìQÖFs@»XƱÐÿ¶ÍW‹:V…/ƒRD—«áà·Ö—•• %ðñL_lß1sç­o²¨p÷®¢Â³àrõ'×ß9Œ°ƒ$CbŸ›"­lPÑ%gZà´P¯ÕtN~=ùz^H Wú†{“upÄXq1„,2ß °Î^Ð äÿ'*|gü­€!q ùF’hĤí,\ÍÒãEšr}Õ‘³?úÖ0JW¤'¾üuifVÓ§0ü°@y…oêæaÄ/.=È|ª0¬8+X¡{8YãÛ'ñ:Ÿ¿S×ÀÔøþ¹vÍž>ì ”‰kMе¦£•àAë-’6T¥â™$A\|o‚zj±®ÍÓîq[ÌöD?ÌZ›¯ 6í|…¥Ýâî´4kJ-›³ÂÒÚa3»E™LVñ)MrsŠ%eêR’’uI)Éϙ̈ʤç@ÚÚy3_é67[ìf÷fÞÙò ’¶V³§ÃmiÏvÚíNÿdNÖ‘6â!í8ÜÄBÌÄNŠPcÇÅÒMl¨k'¥øt ìDmÎyÒˆ–í¨mF¹ƒ¸pÅ’‡XQÇ“rÔXDW:¹IÔ·ˆv”¾¿+OªPr£ÌãpˆÈóx.ÄhÄýÛ‡Ç'Ú›qæx3m7‰þUh¯ùŸ»ø™˜Å}¨¦W(®›lF‘_„ˆÚBܱ wH£¡j#­¨óç£óÆ¿ ‹dãÁÛEV-Þ]â­=)# ÊNܧך¬Ì(ypþbÏÆïE§=íh3Ÿ—qÍ!ÆésFñ](;Q×!â·£†®w¢õ¼ÕuråÜŽ<þ_D;ˆ endstream endobj 117 0 obj 2342 endobj 115 0 obj << /Type /Font /Subtype /CIDFontType2 /BaseFont /Menlo-Regular /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> /FontDescriptor 113 0 R /CIDToGIDMap /Identity /DW 597 >> endobj 116 0 obj << /Length 504 >> stream /CIDInit /ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def /CMapName /Adobe-Identity-UCS def /CMapType 2 def 1 begincodespacerange <0000> endcodespacerange 2 beginbfrange <0000> <0000> <0000> <0001> <0014> [<0045> <0072> <006C> <0061> <006E> <0067> <004D> <006F> <0064> <0075> <0065> <004B> <0079> <0050> <0074> <0068> <0052> <0073> <0041> <0056> ] endbfrange endcmap CMapName currentdict /CMap defineresource pop end end endstream endobj 26 0 obj << /Type /Font /Subtype /Type0 /BaseFont /Menlo-Regular /Encoding /Identity-H /DescendantFonts [115 0 R] /ToUnicode 116 0 R>> endobj 2 0 obj << /Type /Pages /Kids [ 5 0 R 25 0 R 44 0 R ] /Count 3 /ProcSet [/PDF /Text /ImageB /ImageC] >> endobj xref 0 118 0000000000 65535 f 0000000009 00000 n 0000049103 00000 n 0000000189 00000 n 0000000284 00000 n 0000001213 00000 n 0000031671 00000 n 0000045325 00000 n 0000022422 00000 n 0000035089 00000 n 0000000321 00000 n 0000000366 00000 n 0000000411 00000 n 0000000456 00000 n 0000000501 00000 n 0000000546 00000 n 0000000591 00000 n 0000000636 00000 n 0000000674 00000 n 0000000836 00000 n 0000001031 00000 n 0000001571 00000 n 0000004993 00000 n 0000001334 00000 n 0000001530 00000 n 0000005571 00000 n 0000048961 00000 n 0000005014 00000 n 0000005059 00000 n 0000005104 00000 n 0000005142 00000 n 0000005187 00000 n 0000005232 00000 n 0000005277 00000 n 0000005322 00000 n 0000005360 00000 n 0000005398 00000 n 0000005443 00000 n 0000005488 00000 n 0000005533 00000 n 0000005901 00000 n 0000008832 00000 n 0000005693 00000 n 0000005881 00000 n 0000017976 00000 n 0000008853 00000 n 0000008891 00000 n 0000008929 00000 n 0000008974 00000 n 0000009019 00000 n 0000009064 00000 n 0000009102 00000 n 0000009147 00000 n 0000009192 00000 n 0000009230 00000 n 0000009268 00000 n 0000017809 00000 n 0000009955 00000 n 0000010079 00000 n 0000017614 00000 n 0000010200 00000 n 0000017467 00000 n 0000010330 00000 n 0000010482 00000 n 0000010655 00000 n 0000010960 00000 n 0000011263 00000 n 0000011616 00000 n 0000011853 00000 n 0000012112 00000 n 0000012445 00000 n 0000012786 00000 n 0000013099 00000 n 0000013424 00000 n 0000013663 00000 n 0000013973 00000 n 0000014288 00000 n 0000014606 00000 n 0000014932 00000 n 0000015262 00000 n 0000015562 00000 n 0000015870 00000 n 0000016100 00000 n 0000016338 00000 n 0000016606 00000 n 0000016824 00000 n 0000017060 00000 n 0000017262 00000 n 0000017872 00000 n 0000018306 00000 n 0000020437 00000 n 0000018098 00000 n 0000018286 00000 n 0000020458 00000 n 0000020718 00000 n 0000021785 00000 n 0000021992 00000 n 0000021765 00000 n 0000022558 00000 n 0000022824 00000 n 0000030411 00000 n 0000030862 00000 n 0000030389 00000 n 0000031821 00000 n 0000032107 00000 n 0000034420 00000 n 0000034658 00000 n 0000034398 00000 n 0000035241 00000 n 0000035504 00000 n 0000043970 00000 n 0000044453 00000 n 0000043948 00000 n 0000045470 00000 n 0000045735 00000 n 0000048192 00000 n 0000048404 00000 n 0000048170 00000 n trailer << /Size 118 /Info 1 0 R /Root 88 0 R >> startxref 49215 %%EOF luerl-1.2.3/doc/src/0000775000175000017500000000000014677012037014563 5ustar debalancedebalanceluerl-1.2.3/doc/src/luerl_sandbox.3.md0000664000175000017500000000645614677012037020122 0ustar debalancedebalance% luerl_sandbox(3) % Robert Virding % 2023 # Name luerl_sandbox - Fuctions for sandboxing Luerl evaluation # Interface Functions The **Lua State** parameter is the state of a Lua VM instance. It must be created with the **luerl:init()** call and be carried from one call to the next. As it is possible in Lua to create self-referencing data structures, indeed the standard libraries have many instances of this, then using the functions which decode their return values will generate an error when they would cause an infinite loop during the decoding. An simple example is the top level table which contains a key **`_G`** which references the top-level table. Note that Lua **Chunks** (see definition below) can travel between different States. They are precompiled bits of code, independent of State. That you can 'carry around' this is no unique to Luerl but a low-level implementation detail of the standard Lua [language](https://lua.org), for more on chunks [read](https://www.lua.org/manual/5.3/manual.html#3.3.2) the official Lua 5.3 [reference manual](https://www.lua.org/manual/5.3/manual.html). ## Spec Definitions **Binary** means an Erlang binary string. **Chunks** means a portion of precompiled bytecode. **State** means a Lua State, this *is* a Lua VM instance. **Path** means a file system path and file name. **KeyPath** means an Erlang list of **atoms** representing nested names, e.g. [table,pack] for table.pack. **Keys** means Lua table keys, the keys of a key-value structure. ## Functions #### init() -> State. #### init([ State | TablePaths]) -> State. #### init(State, TablePaths) -> State. Create a new sandboxed state. If a state is given as an argument then that state will be used otherwise a new default be be generated. ``TablePaths`` is a list of paths to functions which will be blocked. If none is given then the default list will be used. #### run(String | Binary) -> {Result, State} | {error, Reason}. #### run(String | Binary, State) -> {Result, State} | {error, Reason}. #### run(String | Binary, Flags, State) -> {Result, State} | {error, Reason}. Spawn a new process which runs the string `String` in `State` where the default sandbox state will be used if none is given. `Flags` is a map or keyword list which can contain the following fields #{max_time => MaxTime, max_reductions => MaxReds, spawn_opts => SpawnOpts} `MaxReds` limits the number of reductions and `MaxTime` (default 100 msecs) the time to run the string, `SpawnOpts` are spawn options to the process running the evaluation. #### run(String | Binary) -> {Result, State} | {error, Reason}. #### run(String | Binary, State) -> {Result, State} | {error, Reason}. #### run(String | Binary, State, [ MexReds | Flags ]) -> {Result, State} | {error, Reason}. #### run(String | Binary, State, MexReds, Flags) -> {Result, State} | {error, Reason}. #### run(String | Binary, State, MexReds, Flags, Timeout) -> {Result, State} | {error, Reason}. This is the old interface to run. It still works but the new interface is recommended. Spawn a new process which runs the string `String` in `State` where the default sandbox state will be used if none is given. `MaxReds` limits the number of reductions and `TimeOut` (default 100 msecs) the time to run the string, `Flags` are spawn options to the process running the evaluation. luerl-1.2.3/doc/src/luerl.3.md0000664000175000017500000001264614677012037016402 0ustar debalancedebalance% luerl(3) % Jean Chassoul, Robert Virding % 2018-2023 # Name luerl - Basic interface to the Luerl system # Interface functions The **Lua State** parameter is the state of a Lua VM instance. It must be created with the **luerl:init()** call and be carried from one call to the next. As it is possible in Lua to create self-referencing data structures, indeed the standard libraries have many instances of this, then using the functions which decode their return values will generate an error when they would cause an infinite loop during the decoding. An simple example is the top level table which contains a key **`_G`** which references the top-level table. Note that Lua **Chunks** (see definition below) can travel between different States. They are precompiled bits of code, independent of State. That you can 'carry around' this is no unique to Luerl but a low-level implementation detail of the standard Lua [language](https://lua.org), for more on chunks [read](https://www.lua.org/manual/5.3/manual.html#3.3.2) the official Lua 5.3 [reference manual](https://www.lua.org/manual/5.3/manual.html). ## Spec Definitions **Binary** means an Erlang binary string. **Chunks** means a portion of precompiled bytecode. **State** means a Lua State, this *is* a Lua VM instance. **Path** means a file system path and file name. **KeyPath** means an Erlang list of **atoms** representing nested names, e.g. [table,pack] for table.pack. **Keys** means Lua table keys, the keys of a key-value structure. ## Functions **eval** and **do** functions differ only in what they return. The **do** functions return results and a new Lua State, the **eval** functions return a tuple starting on 'ok' or 'error', then the result, or cause of error. do --> {Result, State} eval --> {ok, Result} | {error, Reason} #### luerl:eval(String|Binary|Form, State) -> {ok, Result} | {error, Reason, StackTrace}. Evaluate a Lua expression passed in as a string or binary, and return its result. #### luerl:evalfile(Path, State) -> {ok, Result} | {error, Reason, StackTrace}. Load and execute a file, and return the result. #### luerl:do(String|Binary|Form, State) -> {Result, NewState}. Evaluate a Lua expression and return its result, and the new Lua State. #### luerl:dofile(Path, State) -> {Result, NewState}. Load and execute the Lua code in the file and return its result, and the new Lua State. Equivalent to doing luerl:do("return dofile('FileName')"). #### luerl:load(String|Binary[, CompileOptions], State) -> {ok,Function,NewState} | {error, Reason}. Parse a Lua chunk as string or binary, and return a compiled chunk ('form'). #### luerl:loadfile(FileName[, CompileOptions], State) -> {ok,Function,NewState} | {error, Reason}. Parse a Lua file, and return a compiled chunk ('form'). #### luerl:path_loadfile([Path, ], FileName[, CompileOptions], State) -> {ok,Function,FullName,State} | {error, Reason}. Search Path until the file FileName is found. Parse the file and return a compiled chunk ('form'). If Path is not given then the path defined in the environment variable LUA_LOAD_PATH is used. #### luerl:load_module(KeyPath, ErlangModule, State) -> State. Load `ErlangModule` and install its table at `KeyPath` which is encoded. #### luerl:load_module1(KeyPath, ErlangModule, State) -> State. Load `ErlangModule` and install its table at `KeyPath` which is **NOT** encoded #### luerl:init() -> State. Get a new Lua State = a fresh Lua VM instance. #### luerl:call(Form, Args, State) -> {Result,State} #### luerl:call_chunk(Form, Args, State) -> {Result,State} Call a compiled chunk or function. Use the call_chunk, call has been kept for backwards compatibility. #### luerl:call_function(KeyPath, Args, State) -> {Result,NewState} Call a function already defined in the state. `KeyPath` is a list of names to the function. `KeyPath`, `Args` and `Result` are automatically encoded/decoded. #### luerl:call_function1(KeyPath, Args, State) -> {Result,NewState} Call a function already defined in the state. `KeyPath` is a list of keys to the function. `KeyPath`, `Args` and `Result` are **NOT** encoded/decoded. #### luerl:call_method(MethPath, Args, State) -> {Result,NewState}. Call a method already defined in the state. `MethPath` is a list of names to the method. `MethPath`, `Args` and `Result` are automatically encoded/decoded. #### luerl:call_method1(MethPath, Args, State) -> {Result,NewState} Call a method already defined in the state. `MethPath` is a list of keys to the method. `Keys`, `Args` and `Result` are **NOT** encoded/decoded. #### luerl:stop(State) -> GCedState. Garbage collects the state and (todo:) does away with it. #### luerl:gc(State) -> State. Runs the garbage collector on a state and returns the new state. #### luerl:set_table(KeyPath, Value, State) -> State. Sets a value inside the Lua state. Value is automatically encoded. #### luerl:set_table1(KeyPath, Value, State) -> State. Sets a value inside the Lua state. `KeyPath` and `Value` are **NOT** encoded. #### luerl:get_table(KeyPath, State) -> {Result,State}. Gets a value inside the Lua state. `KeyPath` and `Result` are automatically encoded. #### luerl:get_table1(KeyPath, State) -> {Result,State}. Gets a value inside the Lua state. `KeyPath` and `Result` are **NOT** encoded/decoded. You can use this function to expose an function to the Lua code by using this interface: `fun(Args, State) -> {Results, State}` Args and Results must be a list of Luerl compatible Erlang values. luerl-1.2.3/doc/src/luerl_new.3.md0000664000175000017500000001457214677012037017253 0ustar debalancedebalance% luerl_new(3) % Jean Chassoul, Robert Virding % 2018-2023 # Name luerl_new - New basic interface to the Luerl system # Interface functions - New Version The **Lua State** parameter is the state of a Lua VM instance. It must be created with the **luerl_new:init()** call and be carried from one call to the next. As it is possible in Lua to create self-referencing data structures, indeed the standard libraries have many instances of this, then using the functions which decode their return values will generate an error when they would cause an infinite loop during the decoding. An simple example is the top level table which contains a key **`_G`** which references the top-level table. Note that Lua **Chunks** (see definition below) can travel between different States. They are precompiled bits of code, independent of State. That you can 'carry around' this is no unique to Luerl but a low-level implementation detail of the standard Lua [language](https://lua.org), for more on chunks [read](https://www.lua.org/manual/5.3/manual.html#3.3.2) the official Lua 5.3 [reference manual](https://www.lua.org/manual/5.3/manual.html). ## Spec Definitions **Binary** means an Erlang binary string. **Chunks** means a portion of precompiled bytecode. **State** means a Lua State, this *is* a Lua VM instance. **Path** means a file system path and file name. **KeyPath** means an Erlang list of **atoms** representing nested names, e.g. [table,pack] for table.pack. **Keys** means Lua table keys, the keys of a key-value structure. **CompileOptions** means a list of compiler options. Currently supported options are 'return', which returns the errors and warnings, and 'report' which will log the errors and warnings. **LuaCallReturn = {ok, Result, State} | {lua_error, Error, State}** This is the return value from evaluating a Lua call. ## Functions #### luerl_new:init() -> State. Get a new Lua State = a fresh Lua VM instance. #### luerl_new:gc(State) -> State. Runs the garbage collector on a state and returns the new state. #### luerl_new:load(String|Binary[, CompileOptions], State) -> {ok, Function, State} | CompileError; Parse a Lua chunk as string or binary, and return a compiled chunk ('form'). #### luerl_new:loadfile(FileName[, CompileOptions], State) -> {ok, Function, State} | CompileError. Parse a Lua file, and return a compiled chunk ('form'). #### luerl_new:path_loadfile([Path, ], FileName[, CompileOptions], State) -> {ok,Function,FullName,State} | {error, Reason}. Search Path until the file FileName is found. Parse the file and return a compiled chunk ('form'). If Path is not given then the path defined in the environment variable LUA_LOAD_PATH is used. #### luerl_new:load_module(KeyPath, ErlangModule, State) -> State. Load `ErlangModule` and install its table at `KeyPath` which is **NOT** encoded. #### luerl_new:load_module_dec(EncodedKeyPath, ErlangModule, State) -> State. Load `ErlangModule` and install its table at `KeyPath` which is encoded. #### luerl_new:do(String|Binary|Form, State) -> {ok, Result, NewState} | {lua_error, Error, State} | CompileError. Evaluate a Lua expression and return its result which is **NOT** decoded, and the new Lua State. #### luerl_new:do_dec(String|Binary|Form, State) -> {ok, Result, NewState} | {lua_error, Error, State} | CompileError. Evaluate a Lua expression and return its result which is automatically decoded, and the new Lua State. #### luerl_new:dofile(Path, State) -> {ok, Result, NewState} | {lua_error, Error, State} | CompileError. Load and execute the Lua code in the file and return its result which is **NOT** decoded, and the new Lua State. Equivalent to doing luerl:do("return dofile('FileName')"). #### luerl_new:dofile_dec(Path[, State]) -> {ok, Result, NewState} | {lua_error, Error, State} | CompileError. Load and execute the Lua code in the file and return its result which is automatically decoded, and the new Lua State. #### luerl_new:call(FuncRef, ArgRefs, State) -> {ok, Result, State} #### luerl_new:call_chunk(FuncRef, ArgRefs, State) -> {ok, Result, State} | {lua_error, Error, State}. Call a compiled chunk or function. Use the call_chunk, call has been kept for backwards compatibility. #### luerl_new:call_function(FuncRef, ArgRefs, State] -> {ok, Result, State} | {lua_error, Error, State}. Call a function already defined in the state. `Result` is **NOT** decoded. #### luerl_new:call_function_dec(KeyPath, Args, State) -> {ok, Result, State} | {lua_error, Error, State}. Call a function already defined in the state. `KeyPath` is a list of keys to the function. `KeyPath`, `Args` and `Result` are automatically encoded/decoded. #### luerl_new:call_method(ObjRef, Method, ArgRefs, State) -> {ok, Result, State} | {lua_error, Error, State}. Call a method already defined in the state. #### luerl_new:call_method_dec(KeyPath, Method, Args, State) -> {ok, Result, State} | {lua_error, Error, State}. Call a method already defined in the state. `KeyPath` is a list of keys to the method. `KeyPath`, `Method`, `Args` and `Result` are automatically encoded/decoded. #### luerl_new:get_table_keys(KeyPath, State) -> {ok, Result, State} | {lua_error, Error, State}. Gets a value inside the Lua state. `KeyPath` and `Result` are **NOT** encoded/decoded. #### luerl_new:get_table_keys_dec(KeyPath, State) -> {ok, Result, State} | {lua_error, Error, State}. Gets a value inside the Lua state. `KeyPath` and `Result` are automatically encoded/decoded. #### luerl_new:set_table_keys(KeyPath, Value, State) -> State. Sets a value inside the Lua state. `KeyPath` and `Value` are **NOT** encoded. #### luerl_new:set_table_keys_dec(KeyPath, Value, State) -> State. Sets a value inside the Lua state. `KeyPath` and `Value` are automatically encoded. #### luerl_new:get_stacktrace(State) -> [{FuncName,{file,FileName},{line,Line}}]. Return a stack trace of the current call stack in the state. #### luerl_new:encode(Term, State) -> {LuerlTerm,State}. Encode the Erlang representation of a term into Luerl form updating the state when necessary. #### luerl_new:encode_list([Term], State) -> {[LuerlTerm],State}. Encode a list of Erlang term representations into a list of Luerl forms updating the state when necessary. #### luerl_new:decode(LuerlTerm, State) -> Term. Decode a term in the Luerl form into its Erlang representation. #### luerl_new:decode_list([LuerlTerm], State) -> [Term]. Decode a list of Luerl terms into a list of Erlang representations. luerl-1.2.3/doc/luerl_sandbox.txt0000664000175000017500000000744014677012037017403 0ustar debalancedebalanceluerl_sandbox(3) luerl_sandbox(3) Name luerl_sandbox †Fuctions for sandboxing Luerl evaluation Interface Functions The Lua State parameter is the state of a Lua VM instance. It must be created with the luerl:init() call and be carried from one call to the next. As it is possible in Lua to create selfâ€referencing data structures, indeed the standard libraries have many instances of this, then using the functions which decode their return values will generate an error when they would cause an infinite loop during the decoding. An simple example is the top level table which contains a key _G which references the topâ€level table. Note that Lua Chunks (see definition below) can travel between differ†ent States. They are precompiled bits of code, independent of State. That you can ‘carry around’ this is no unique to Luerl but a lowâ€level implementation detail of the standard Lua language (https://lua.org), for more on chunks read (https://www.lua.org/manual/5.3/manu†al.html#3.3.2) the official Lua 5.3 reference manual (https://www.lua.org/manual/5.3/manual.html). Spec Definitions Binary means an Erlang binary string. Chunks means a portion of precompiled bytecode. State means a Lua State, this is a Lua VM instance. Path means a file system path and file name. KeyPath means an Erlang list of atoms representing nested names, e.g. [table,pack] for table.pack. Keys means Lua table keys, the keys of a keyâ€value structure. Functions init() â€> State. init([ State | TablePaths]) â€> State. init(State, TablePaths) â€> State. Create a new sandboxed state. If a state is given as an argument then that state will be used otherwise a new default be be generated. TablePaths is a list of paths to functions which will be blocked. If none is given then the default list will be used. run(String | Binary) â€> {Result, State} | {error, Reason}. run(String | Binary, State) â€> {Result, State} | {error, Reason}. run(String | Binary, Flags, State) â€> {Result, State} | {error, Reason}. Spawn a new process which runs the string String in State where the de†fault sandbox state will be used if none is given. Flags is a map or keyword list which can contain the following fields #{max_time => MaxTime, max_reductions => MaxReds, spawn_opts => SpawnOpts} MaxReds limits the number of reductions and MaxTime (default 100 msecs) the time to run the string, SpawnOpts are spawn options to the process running the evaluation. run(String | Binary) â€> {Result, State} | {error, Reason}. run(String | Binary, State) â€> {Result, State} | {error, Reason}. run(String | Binary, State, [ MexReds | Flags ]) â€> {Result, State} | {er†ror, Reason}. run(String | Binary, State, MexReds, Flags) â€> {Result, State} | {error, Reason}. run(String | Binary, State, MexReds, Flags, Timeout) â€> {Result, State} | {error, Reason}. This is the old interface to run. It still works but the new interface is recommendded. Spawn a new process which runs the string String in State where the default sandbox state will be used if none is given. MaxReds limits the number of reductions and TimeOut (default 100 msecs) the time to run the string, Flags are spawn options to the process run†ning the evaluation. AUTHORS Robert Virding. 2023 luerl_sandbox(3) luerl-1.2.3/doc/man/0000775000175000017500000000000014677012037014547 5ustar debalancedebalanceluerl-1.2.3/doc/man/luerl.30000664000175000017500000001420114677012037015754 0ustar debalancedebalance.\" Automatically generated by Pandoc 3.1.6.1 .\" .\" Define V font for inline verbatim, using C font in formats .\" that render this, and otherwise B font. .ie "\f[CB]x\f[]"x" \{\ . ftr V B . ftr VI BI . ftr VB B . ftr VBI BI .\} .el \{\ . ftr V CR . ftr VI CI . ftr VB CB . ftr VBI CBI .\} .TH "luerl" "3" "2018-2023" "" "" .hy .SH Interface functions .PP The \f[B]Lua State\f[R] parameter is the state of a Lua VM instance. It must be created with the \f[B]luerl:init()\f[R] call and be carried from one call to the next. .PP As it is possible in Lua to create self-referencing data structures, indeed the standard libraries have many instances of this, then using the functions which decode their return values will generate an error when they would cause an infinite loop during the decoding. An simple example is the top level table which contains a key \f[B]\f[VB]_G\f[B]\f[R] which references the top-level table. .PP Note that Lua \f[B]Chunks\f[R] (see definition below) can travel between different States. They are precompiled bits of code, independent of State. That you can `carry around' this is no unique to Luerl but a low-level implementation detail of the standard Lua language (https://lua.org), for more on chunks read (https://www.lua.org/manual/5.3/manual.html#3.3.2) the official Lua 5.3 reference manual (https://www.lua.org/manual/5.3/manual.html). .SS Spec Definitions .PP \f[B]Binary\f[R] means an Erlang binary string. .PD 0 .P .PD \f[B]Chunks\f[R] means a portion of precompiled bytecode. .PD 0 .P .PD \f[B]State\f[R] means a Lua State, this \f[I]is\f[R] a Lua VM instance. .PD 0 .P .PD \f[B]Path\f[R] means a file system path and file name. .PD 0 .P .PD \f[B]KeyPath\f[R] means an Erlang list of \f[B]atoms\f[R] representing nested names, e.g.\ [table,pack] for table.pack. .PD 0 .P .PD \f[B]Keys\f[R] means Lua table keys, the keys of a key-value structure. .SS Functions .PP \f[B]eval\f[R] and \f[B]do\f[R] functions differ only in what they return. The \f[B]do\f[R] functions return results and a new Lua State, the \f[B]eval\f[R] functions return a tuple starting on `ok' or `error', then the result, or cause of error. .IP .nf \f[C] do --> {Result, State} eval --> {ok, Result} | {error, Reason} \f[R] .fi .SS luerl:eval(String|Binary|Form, State) -> {ok, Result} | {error, Reason, StackTrace}. .PP Evaluate a Lua expression passed in as a string or binary, and return its result. .SS luerl:evalfile(Path, State) -> {ok, Result} | {error, Reason, StackTrace}. .PP Load and execute a file, and return the result. .SS luerl:do(String|Binary|Form, State) -> {Result, NewState}. .PP Evaluate a Lua expression and return its result, and the new Lua State. .SS luerl:dofile(Path, State) -> {Result, NewState}. .PP Load and execute the Lua code in the file and return its result, and the new Lua State. Equivalent to doing luerl:do(\[lq]return dofile(`FileName')\[rq]). .SS luerl:load(String|Binary[, CompileOptions], State) -> {ok,Function,NewState} | {error, Reason}. .PP Parse a Lua chunk as string or binary, and return a compiled chunk (`form'). .SS luerl:loadfile(FileName[, CompileOptions], State) -> {ok,Function,NewState} | {error, Reason}. .PP Parse a Lua file, and return a compiled chunk (`form'). .SS luerl:path_loadfile([Path, ], FileName[, CompileOptions], State) -> {ok,Function,FullName,State} | {error, Reason}. .PP Search Path until the file FileName is found. Parse the file and return a compiled chunk (`form'). If Path is not given then the path defined in the environment variable LUA_LOAD_PATH is used. .SS luerl:load_module(KeyPath, ErlangModule, State) -> State. .PP Load \f[V]ErlangModule\f[R] and install its table at \f[V]KeyPath\f[R] which is encoded. .SS luerl:load_module1(KeyPath, ErlangModule, State) -> State. .PP Load \f[V]ErlangModule\f[R] and install its table at \f[V]KeyPath\f[R] which is \f[B]NOT\f[R] encoded .SS luerl:init() -> State. .PP Get a new Lua State = a fresh Lua VM instance. .SS luerl:call(Form, Args, State) -> {Result,State} .SS luerl:call_chunk(Form, Args, State) -> {Result,State} .PP Call a compiled chunk or function. Use the call_chunk, call has been kept for backwards compatibility. .SS luerl:call_function(KeyPath, Args, State) -> {Result,NewState} .PP Call a function already defined in the state. \f[V]KeyPath\f[R] is a list of names to the function. \f[V]KeyPath\f[R], \f[V]Args\f[R] and \f[V]Result\f[R] are automatically encoded/decoded. .SS luerl:call_function1(KeyPath, Args, State) -> {Result,NewState} .PP Call a function already defined in the state. \f[V]KeyPath\f[R] is a list of keys to the function. \f[V]KeyPath\f[R], \f[V]Args\f[R] and \f[V]Result\f[R] are \f[B]NOT\f[R] encoded/decoded. .SS luerl:call_method(MethPath, Args, State) -> {Result,NewState}. .PP Call a method already defined in the state. \f[V]MethPath\f[R] is a list of names to the method. \f[V]MethPath\f[R], \f[V]Args\f[R] and \f[V]Result\f[R] are automatically encoded/decoded. .SS luerl:call_method1(MethPath, Args, State) -> {Result,NewState} .PP Call a method already defined in the state. \f[V]MethPath\f[R] is a list of keys to the method. \f[V]Keys\f[R], \f[V]Args\f[R] and \f[V]Result\f[R] are \f[B]NOT\f[R] encoded/decoded. .SS luerl:stop(State) -> GCedState. .PP Garbage collects the state and (todo:) does away with it. .SS luerl:gc(State) -> State. .PP Runs the garbage collector on a state and returns the new state. .SS luerl:set_table(KeyPath, Value, State) -> State. .PP Sets a value inside the Lua state. Value is automatically encoded. .SS luerl:set_table1(KeyPath, Value, State) -> State. .PP Sets a value inside the Lua state. \f[V]KeyPath\f[R] and \f[V]Value\f[R] are \f[B]NOT\f[R] encoded. .SS luerl:get_table(KeyPath, State) -> {Result,State}. .PP Gets a value inside the Lua state. \f[V]KeyPath\f[R] and \f[V]Result\f[R] are automatically encoded. .SS luerl:get_table1(KeyPath, State) -> {Result,State}. .PP Gets a value inside the Lua state. \f[V]KeyPath\f[R] and \f[V]Result\f[R] are \f[B]NOT\f[R] encoded/decoded. .PP You can use this function to expose an function to the Lua code by using this interface: \f[V]fun(Args, State) -> {Results, State}\f[R] .PP Args and Results must be a list of Luerl compatible Erlang values. .SH AUTHORS Jean Chassoul, Robert Virding. luerl-1.2.3/doc/man/luerl_new.30000664000175000017500000001552714677012037016641 0ustar debalancedebalance.\" Automatically generated by Pandoc 3.3 .\" .TH "luerl_new" "3" "2018\-2023" "" .SH Name luerl_new \- New basic interface to the Luerl system .SH Interface functions \- New Version The \f[B]Lua State\f[R] parameter is the state of a Lua VM instance. It must be created with the \f[B]luerl_new:init()\f[R] call and be carried from one call to the next. .PP As it is possible in Lua to create self\-referencing data structures, indeed the standard libraries have many instances of this, then using the functions which decode their return values will generate an error when they would cause an infinite loop during the decoding. An simple example is the top level table which contains a key \f[B]\f[CB]_G\f[B]\f[R] which references the top\-level table. .PP Note that Lua \f[B]Chunks\f[R] (see definition below) can travel between different States. They are precompiled bits of code, independent of State. That you can `carry around' this is no unique to Luerl but a low\-level implementation detail of the standard Lua \c .UR https://lua.org language .UE \c , for more on chunks \c .UR https://www.lua.org/manual/5.3/manual.html#3.3.2 read .UE \c \ the official Lua 5.3 \c .UR https://www.lua.org/manual/5.3/manual.html reference manual .UE \c \&. .SS Spec Definitions \f[B]Binary\f[R] means an Erlang binary string. .PD 0 .P .PD \f[B]Chunks\f[R] means a portion of precompiled bytecode. .PD 0 .P .PD \f[B]State\f[R] means a Lua State, this \f[I]is\f[R] a Lua VM instance. .PD 0 .P .PD \f[B]Path\f[R] means a file system path and file name. .PD 0 .P .PD \f[B]KeyPath\f[R] means an Erlang list of \f[B]atoms\f[R] representing nested names, e.g.\ [table,pack] for table.pack. .PD 0 .P .PD \f[B]Keys\f[R] means Lua table keys, the keys of a key\-value structure. .PP \f[B]CompileOptions\f[R] means a list of compiler options. Currently supported options are `return', which returns the errors and warnings, and `report' which will log the errors and warnings. .PP \f[B]LuaCallReturn = {ok, Result, State} | {lua_error, Error, State}\f[R] .PD 0 .P .PD This is the return value from evaluating a Lua call. .SS Functions .SS luerl_new:init() \-> State. Get a new Lua State = a fresh Lua VM instance. .SS luerl_new:gc(State) \-> State. Runs the garbage collector on a state and returns the new state. .SS luerl_new:load(String|Binary[, CompileOptions], State) \-> {ok, Function, State} | CompileError; Parse a Lua chunk as string or binary, and return a compiled chunk (`form'). .SS luerl_new:loadfile(FileName[, CompileOptions], State) \-> {ok, Function, State} | CompileError. Parse a Lua file, and return a compiled chunk (`form'). .SS luerl_new:path_loadfile([Path, ], FileName[, CompileOptions], State) \-> {ok,Function,FullName,State} | {error, Reason}. Search Path until the file FileName is found. Parse the file and return a compiled chunk (`form'). If Path is not given then the path defined in the environment variable LUA_LOAD_PATH is used. .SS luerl_new:load_module(KeyPath, ErlangModule, State) \-> State. Load \f[CR]ErlangModule\f[R] and install its table at \f[CR]KeyPath\f[R] which is \f[B]NOT\f[R] encoded. .SS luerl_new:load_module_dec(EncodedKeyPath, ErlangModule, State) \-> State. Load \f[CR]ErlangModule\f[R] and install its table at \f[CR]KeyPath\f[R] which is encoded. .SS luerl_new:do(String|Binary|Form, State) \-> {ok, Result, NewState} | {lua_error, Error, State} | CompileError. Evaluate a Lua expression and return its result which is \f[B]NOT\f[R] decoded, and the new Lua State. .SS luerl_new:do_dec(String|Binary|Form, State) \-> {ok, Result, NewState} | {lua_error, Error, State} | CompileError. Evaluate a Lua expression and return its result which is automatically decoded, and the new Lua State. .SS luerl_new:dofile(Path, State) \-> {ok, Result, NewState} | {lua_error, Error, State} | CompileError. Load and execute the Lua code in the file and return its result which is \f[B]NOT\f[R] decoded, and the new Lua State. Equivalent to doing luerl:do(\[lq]return dofile(`FileName')\[rq]). .SS luerl_new:dofile_dec(Path[, State]) \-> {ok, Result, NewState} | {lua_error, Error, State} | CompileError. Load and execute the Lua code in the file and return its result which is automatically decoded, and the new Lua State. .SS luerl_new:call(FuncRef, ArgRefs, State) \-> {ok, Result, State} .SS luerl_new:call_chunk(FuncRef, ArgRefs, State) \-> {ok, Result, State} | {lua_error, Error, State}. Call a compiled chunk or function. Use the call_chunk, call has been kept for backwards compatibility. .SS luerl_new:call_function(FuncRef, ArgRefs, State] \-> {ok, Result, State} | {lua_error, Error, State}. Call a function already defined in the state. \f[CR]Result\f[R] is \f[B]NOT\f[R] decoded. .SS luerl_new:call_function_dec(KeyPath, Args, State) \-> {ok, Result, State} | {lua_error, Error, State}. Call a function already defined in the state. \f[CR]KeyPath\f[R] is a list of keys to the function. \f[CR]KeyPath\f[R], \f[CR]Args\f[R] and \f[CR]Result\f[R] are automatically encoded/decoded. .SS luerl_new:call_method(ObjRef, Method, ArgRefs, State) \-> {ok, Result, State} | {lua_error, Error, State}. Call a method already defined in the state. .SS luerl_new:call_method_dec(KeyPath, Method, Args, State) \-> {ok, Result, State} | {lua_error, Error, State}. Call a method already defined in the state. \f[CR]KeyPath\f[R] is a list of keys to the method. \f[CR]KeyPath\f[R], \f[CR]Method\f[R], \f[CR]Args\f[R] and \f[CR]Result\f[R] are automatically encoded/decoded. .SS luerl_new:get_table_keys(KeyPath, State) \-> {ok, Result, State} | {lua_error, Error, State}. Gets a value inside the Lua state. \f[CR]KeyPath\f[R] and \f[CR]Result\f[R] are \f[B]NOT\f[R] encoded/decoded. .SS luerl_new:get_table_keys_dec(KeyPath, State) \-> {ok, Result, State} | {lua_error, Error, State}. Gets a value inside the Lua state. \f[CR]KeyPath\f[R] and \f[CR]Result\f[R] are automatically encoded/decoded. .SS luerl_new:set_table_keys(KeyPath, Value, State) \-> State. Sets a value inside the Lua state. \f[CR]KeyPath\f[R] and \f[CR]Value\f[R] are \f[B]NOT\f[R] encoded. .SS luerl_new:set_table_keys_dec(KeyPath, Value, State) \-> State. Sets a value inside the Lua state. \f[CR]KeyPath\f[R] and \f[CR]Value\f[R] are automatically encoded. .SS luerl_new:get_stacktrace(State) \-> [{FuncName,{file,FileName},{line,Line}}]. Return a stack trace of the current call stack in the state. .SS luerl_new:encode(Term, State) \-> {LuerlTerm,State}. Encode the Erlang representation of a term into Luerl form updating the state when necessary. .SS luerl_new:encode_list([Term], State) \-> {[LuerlTerm],State}. Encode a list of Erlang term representations into a list of Luerl forms updating the state when necessary. .SS luerl_new:decode(LuerlTerm, State) \-> Term. Decode a term in the Luerl form into its Erlang representation. .SS luerl_new:decode_list([LuerlTerm], State) \-> [Term]. Decode a list of Luerl terms into a list of Erlang representations. .SH AUTHORS Jean Chassoul, Robert Virding. luerl-1.2.3/doc/man/luerl_sandbox.30000664000175000017500000000754614677012037017510 0ustar debalancedebalance.\" Automatically generated by Pandoc 3.1.6.1 .\" .\" Define V font for inline verbatim, using C font in formats .\" that render this, and otherwise B font. .ie "\f[CB]x\f[]"x" \{\ . ftr V B . ftr VI BI . ftr VB B . ftr VBI BI .\} .el \{\ . ftr V CR . ftr VI CI . ftr VB CB . ftr VBI CBI .\} .TH "luerl_sandbox" "3" "2023" "" "" .hy .SH Name .PP luerl_sandbox - Fuctions for sandboxing Luerl evaluation .SH Interface Functions .PP The \f[B]Lua State\f[R] parameter is the state of a Lua VM instance. It must be created with the \f[B]luerl:init()\f[R] call and be carried from one call to the next. .PP As it is possible in Lua to create self-referencing data structures, indeed the standard libraries have many instances of this, then using the functions which decode their return values will generate an error when they would cause an infinite loop during the decoding. An simple example is the top level table which contains a key \f[B]\f[VB]_G\f[B]\f[R] which references the top-level table. .PP Note that Lua \f[B]Chunks\f[R] (see definition below) can travel between different States. They are precompiled bits of code, independent of State. That you can `carry around' this is no unique to Luerl but a low-level implementation detail of the standard Lua language (https://lua.org), for more on chunks read (https://www.lua.org/manual/5.3/manual.html#3.3.2) the official Lua 5.3 reference manual (https://www.lua.org/manual/5.3/manual.html). .SS Spec Definitions .PP \f[B]Binary\f[R] means an Erlang binary string. .PD 0 .P .PD \f[B]Chunks\f[R] means a portion of precompiled bytecode. .PD 0 .P .PD \f[B]State\f[R] means a Lua State, this \f[I]is\f[R] a Lua VM instance. .PD 0 .P .PD \f[B]Path\f[R] means a file system path and file name. .PD 0 .P .PD \f[B]KeyPath\f[R] means an Erlang list of \f[B]atoms\f[R] representing nested names, e.g.\ [table,pack] for table.pack. .PD 0 .P .PD \f[B]Keys\f[R] means Lua table keys, the keys of a key-value structure. .SS Functions .SS init() -> State. .SS init([ State | TablePaths]) -> State. .SS init(State, TablePaths) -> State. .PP Create a new sandboxed state. If a state is given as an argument then that state will be used otherwise a new default be be generated. \f[V]TablePaths\f[R] is a list of paths to functions which will be blocked. If none is given then the default list will be used. .SS run(String | Binary) -> {Result, State} | {error, Reason}. .SS run(String | Binary, State) -> {Result, State} | {error, Reason}. .SS run(String | Binary, Flags, State) -> {Result, State} | {error, Reason}. .PP Spawn a new process which runs the string \f[V]String\f[R] in \f[V]State\f[R] where the default sandbox state will be used if none is given. \f[V]Flags\f[R] is a map or keyword list which can contain the following fields .IP .nf \f[C] #{max_time => MaxTime, max_reductions => MaxReds, spawn_opts => SpawnOpts} \f[R] .fi .PP \f[V]MaxReds\f[R] limits the number of reductions and \f[V]MaxTime\f[R] (default 100 msecs) the time to run the string, \f[V]SpawnOpts\f[R] are spawn options to the process running the evaluation. .SS run(String | Binary) -> {Result, State} | {error, Reason}. .SS run(String | Binary, State) -> {Result, State} | {error, Reason}. .SS run(String | Binary, State, [ MexReds | Flags ]) -> {Result, State} | {error, Reason}. .SS run(String | Binary, State, MexReds, Flags) -> {Result, State} | {error, Reason}. .SS run(String | Binary, State, MexReds, Flags, Timeout) -> {Result, State} | {error, Reason}. .PP This is the old interface to run. It still works but the new interface is recommended. Spawn a new process which runs the string \f[V]String\f[R] in \f[V]State\f[R] where the default sandbox state will be used if none is given. \f[V]MaxReds\f[R] limits the number of reductions and \f[V]TimeOut\f[R] (default 100 msecs) the time to run the string, \f[V]Flags\f[R] are spawn options to the process running the evaluation. .SH AUTHORS Robert Virding. luerl-1.2.3/doc/luerl_new.txt0000664000175000017500000001626314677012037016541 0ustar debalancedebalanceluerl_new(3) Library Functions Manual luerl_new(3) Name luerl_new - New basic interface to the Luerl system Interface functions - New Version The Lua State parameter is the state of a Lua VM instance. It must be created with the luerl_new:init() call and be carried from one call to the next. As it is possible in Lua to create self-referencing data structures, indeed the standard libraries have many instances of this, then using the functions which decode their return values will generate an error when they would cause an infinite loop during the decoding. An simple example is the top level table which contains a key _G which references the top-level table. Note that Lua Chunks (see definition below) can travel between differ†ent States. They are precompiled bits of code, independent of State. That you can ‘carry around’ this is no unique to Luerl but a low-level implementation detail of the standard Lua language ⟨https://lua.org⟩, for more on chunks read ⟨https://www.lua.org/manual/5.3/man†ual.html#3.3.2⟩ the official Lua 5.3 reference manual ⟨https://www.lua.org/manual/5.3/manual.html⟩. Spec Definitions Binary means an Erlang binary string. Chunks means a portion of precompiled bytecode. State means a Lua State, this is a Lua VM instance. Path means a file system path and file name. KeyPath means an Erlang list of atoms representing nested names, e.g. [table,pack] for table.pack. Keys means Lua table keys, the keys of a key-value structure. CompileOptions means a list of compiler options. Currently supported options are ‘return’, which returns the errors and warnings, and ‘re†port’ which will log the errors and warnings. LuaCallReturn = {ok, Result, State} | {lua_error, Error, State} This is the return value from evaluating a Lua call. Functions luerl_new:init() -> State. Get a new Lua State = a fresh Lua VM instance. luerl_new:gc(State) -> State. Runs the garbage collector on a state and returns the new state. luerl_new:load(String|Binary[, CompileOptions], State) -> {ok, Function, State} | CompileError; Parse a Lua chunk as string or binary, and return a compiled chunk (‘form’). luerl_new:loadfile(FileName[, CompileOptions], State) -> {ok, Function, State} | CompileError. Parse a Lua file, and return a compiled chunk (‘form’). luerl_new:path_loadfile([Path, ], FileName[, CompileOptions], State) -> {ok,Function,FullName,State} | {error, Reason}. Search Path until the file FileName is found. Parse the file and re†turn a compiled chunk (‘form’). If Path is not given then the path de†fined in the environment variable LUA_LOAD_PATH is used. luerl_new:load_module(KeyPath, ErlangModule, State) -> State. Load ErlangModule and install its table at KeyPath which is NOT en†coded. luerl_new:load_module_dec(EncodedKeyPath, ErlangModule, State) -> State. Load ErlangModule and install its table at KeyPath which is encoded. luerl_new:do(String|Binary|Form, State) -> {ok, Result, NewState} | {lua_error, Error, State} | CompileError. Evaluate a Lua expression and return its result which is NOT decoded, and the new Lua State. luerl_new:do_dec(String|Binary|Form, State) -> {ok, Result, NewState} | {lua_error, Error, State} | CompileError. Evaluate a Lua expression and return its result which is automatically decoded, and the new Lua State. luerl_new:dofile(Path, State) -> {ok, Result, NewState} | {lua_error, Er†ror, State} | CompileError. Load and execute the Lua code in the file and return its result which is NOT decoded, and the new Lua State. Equivalent to doing luerl:do(“return dofile(‘FileName’)â€). luerl_new:dofile_dec(Path[, State]) -> {ok, Result, NewState} | {lua_error, Error, State} | CompileError. Load and execute the Lua code in the file and return its result which is automatically decoded, and the new Lua State. luerl_new:call(FuncRef, ArgRefs, State) -> {ok, Result, State} luerl_new:call_chunk(FuncRef, ArgRefs, State) -> {ok, Result, State} | {lua_error, Error, State}. Call a compiled chunk or function. Use the call_chunk, call has been kept for backwards compatibility. luerl_new:call_function(FuncRef, ArgRefs, State] -> {ok, Result, State} | {lua_error, Error, State}. Call a function already defined in the state. Result is NOT decoded. luerl_new:call_function_dec(KeyPath, Args, State) -> {ok, Result, State} | {lua_error, Error, State}. Call a function already defined in the state. KeyPath is a list of keys to the function. KeyPath, Args and Result are automatically en†coded/decoded. luerl_new:call_method(ObjRef, Method, ArgRefs, State) -> {ok, Result, State} | {lua_error, Error, State}. Call a method already defined in the state. luerl_new:call_method_dec(KeyPath, Method, Args, State) -> {ok, Result, State} | {lua_error, Error, State}. Call a method already defined in the state. KeyPath is a list of keys to the method. KeyPath, Method, Args and Result are automatically en†coded/decoded. luerl_new:get_table_keys(KeyPath, State) -> {ok, Result, State} | {lua_er†ror, Error, State}. Gets a value inside the Lua state. KeyPath and Result are NOT en†coded/decoded. luerl_new:get_table_keys_dec(KeyPath, State) -> {ok, Result, State} | {lua_error, Error, State}. Gets a value inside the Lua state. KeyPath and Result are automati†cally encoded/decoded. luerl_new:set_table_keys(KeyPath, Value, State) -> State. Sets a value inside the Lua state. KeyPath and Value are NOT encoded. luerl_new:set_table_keys_dec(KeyPath, Value, State) -> State. Sets a value inside the Lua state. KeyPath and Value are automatically encoded. luerl_new:get_stacktrace(State) -> [{FuncName,{file,File†Name},{line,Line}}]. Return a stack trace of the current call stack in the state. luerl_new:encode(Term, State) -> {LuerlTerm,State}. Encode the Erlang representation of a term into Luerl form updating the state when necessary. luerl_new:encode_list([Term], State) -> {[LuerlTerm],State}. Encode a list of Erlang term representations into a list of Luerl forms updating the state when necessary. luerl_new:decode(LuerlTerm, State) -> Term. Decode a term in the Luerl form into its Erlang representation. luerl_new:decode_list([LuerlTerm], State) -> [Term]. Decode a list of Luerl terms into a list of Erlang representations. AUTHORS Jean Chassoul, Robert Virding. 2018-2023 luerl_new(3) luerl-1.2.3/doc/luerl.txt0000664000175000017500000001407614677012037015670 0ustar debalancedebalanceluerl(3) luerl(3) Interface functions The Lua State parameter is the state of a Lua VM instance. It must be created with the luerl:init() call and be carried from one call to the next. As it is possible in Lua to create selfâ€referencing data structures, indeed the standard libraries have many instances of this, then using the functions which decode their return values will generate an error when they would cause an infinite loop during the decoding. An simple example is the top level table which contains a key _G which references the topâ€level table. Note that Lua Chunks (see definition below) can travel between differ†ent States. They are precompiled bits of code, independent of State. That you can ‘carry around’ this is no unique to Luerl but a lowâ€level implementation detail of the standard Lua language (https://lua.org), for more on chunks read (https://www.lua.org/manual/5.3/manu†al.html#3.3.2) the official Lua 5.3 reference manual (https://www.lua.org/manual/5.3/manual.html). Spec Definitions Binary means an Erlang binary string. Chunks means a portion of precompiled bytecode. State means a Lua State, this is a Lua VM instance. Path means a file system path and file name. KeyPath means an Erlang list of atoms representing nested names, e.g. [table,pack] for table.pack. Keys means Lua table keys, the keys of a keyâ€value structure. Functions eval and do functions differ only in what they return. The do func†tions return results and a new Lua State, the eval functions return a tuple starting on ‘ok’ or ‘error’, then the result, or cause of error. do â€â€> {Result, State} eval â€â€> {ok, Result} | {error, Reason} luerl:eval(String|Binary|Form, State) â€> {ok, Result} | {error, Reason, StackTrace}. Evaluate a Lua expression passed in as a string or binary, and return its result. luerl:evalfile(Path, State) â€> {ok, Result} | {error, Reason, StackTrace}. Load and execute a file, and return the result. luerl:do(String|Binary|Form, State) â€> {Result, NewState}. Evaluate a Lua expression and return its result, and the new Lua State. luerl:dofile(Path, State) â€> {Result, NewState}. Load and execute the Lua code in the file and return its result, and the new Lua State. Equivalent to doing luerl:do(“return dofile(‘File†Name’)â€). luerl:load(String|Binary[, CompileOptions], State) â€> {ok,Function,New†State} | {error, Reason}. Parse a Lua chunk as string or binary, and return a compiled chunk (‘form’). luerl:loadfile(FileName[, CompileOptions], State) â€> {ok,Function,NewState} | {error, Reason}. Parse a Lua file, and return a compiled chunk (‘form’). luerl:path_loadfile([Path, ], FileName[, CompileOptions], State) â€> {ok,Function,FullName,State} | {error, Reason}. Search Path until the file FileName is found. Parse the file and re†turn a compiled chunk (‘form’). If Path is not given then the path de†fined in the environment variable LUA_LOAD_PATH is used. luerl:load_module(KeyPath, ErlangModule, State) â€> State. Load ErlangModule and install its table at KeyPath which is encoded. luerl:load_module1(KeyPath, ErlangModule, State) â€> State. Load ErlangModule and install its table at KeyPath which is NOT encoded luerl:init() â€> State. Get a new Lua State = a fresh Lua VM instance. luerl:call(Form, Args, State) â€> {Result,State} luerl:call_chunk(Form, Args, State) â€> {Result,State} Call a compiled chunk or function. Use the call_chunk, call has been kept for backwards compatibility. luerl:call_function(KeyPath, Args, State) â€> {Result,NewState} Call a function already defined in the state. KeyPath is a list of names to the function. KeyPath, Args and Result are automatically en†coded/decoded. luerl:call_function1(KeyPath, Args, State) â€> {Result,NewState} Call a function already defined in the state. KeyPath is a list of keys to the function. KeyPath, Args and Result are NOT encoded/decod†ed. luerl:call_method(MethPath, Args, State) â€> {Result,NewState}. Call a method already defined in the state. MethPath is a list of names to the method. MethPath, Args and Result are automatically en†coded/decoded. luerl:call_method1(MethPath, Args, State) â€> {Result,NewState} Call a method already defined in the state. MethPath is a list of keys to the method. Keys, Args and Result are NOT encoded/decoded. luerl:stop(State) â€> GCedState. Garbage collects the state and (todo:) does away with it. luerl:gc(State) â€> State. Runs the garbage collector on a state and returns the new state. luerl:set_table(KeyPath, Value, State) â€> State. Sets a value inside the Lua state. Value is automatically encoded. luerl:set_table1(KeyPath, Value, State) â€> State. Sets a value inside the Lua state. KeyPath and Value are NOT encoded. luerl:get_table(KeyPath, State) â€> {Result,State}. Gets a value inside the Lua state. KeyPath and Result are automatical†ly encoded. luerl:get_table1(KeyPath, State) â€> {Result,State}. Gets a value inside the Lua state. KeyPath and Result are NOT encod†ed/decoded. You can use this function to expose an function to the Lua code by us†ing this interface: fun(Args, State) â€> {Results, State} Args and Results must be a list of Luerl compatible Erlang values. AUTHORS Jean Chassoul, Robert Virding. 2018â€2023 luerl(3) luerl-1.2.3/VERSION0000664000175000017500000000000614677012037014273 0ustar debalancedebalance1.2.3 luerl-1.2.3/test/0000775000175000017500000000000014677012037014206 5ustar debalancedebalanceluerl-1.2.3/test/lib_os_SUITE.erl0000664000175000017500000001011114677012037017124 0ustar debalancedebalance%% Copyright (c) 2023 Mark Meeus %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. -module(lib_os_SUITE). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). -export([all/0, groups/0]). -export([os_date_formatting/1, os_date_table/1, os_date_integrated/1, os_date_integrated_table/1]). all() -> [ {group, date_support}, {group, integrated} ]. groups() -> [ {date_support, [parallel], [os_date_formatting, os_date_table]}, {integrated, [parallel], [os_date_integrated, os_date_integrated_table]} ]. os_date_formatting(_) -> Date = {{2023, 1, 2}, {3, 4, 5}}, ?assertEqual(<<"2023">>, luerl_lib_os_date:format(Date, <<"%Y">>)), ?assertEqual(<<"23">>, luerl_lib_os_date:format(Date, <<"%y">>)), ?assertEqual(<<"02">>, luerl_lib_os_date:format(Date, <<"%d">>)), ?assertEqual(<<"01">>, luerl_lib_os_date:format(Date, <<"%m">>)), ?assertEqual(<<"03">>, luerl_lib_os_date:format(Date, <<"%H">>)), ?assertEqual(<<"04">>, luerl_lib_os_date:format(Date, <<"%M">>)), ?assertEqual(<<"05">>, luerl_lib_os_date:format(Date, <<"%S">>)), ?assertEqual(<<"01/02/23">>, luerl_lib_os_date:format(Date, <<"%x">>)), ?assertEqual(<<"03:04:05">>, luerl_lib_os_date:format(Date, <<"%X">>)), ?assertEqual(<<"1">>, luerl_lib_os_date:format(Date, <<"%w">>)), %% Day of week %% Hour in 12H ?assertEqual(<<"12">>, luerl_lib_os_date:format({{2023, 1, 2},{0,0,0}}, <<"%I">>)), ?assertEqual(<<"12">>, luerl_lib_os_date:format({{2023, 1, 2},{0,59,0}}, <<"%I">>)), ?assertEqual(<<"01">>, luerl_lib_os_date:format({{2023, 1, 2},{1,00,0}}, <<"%I">>)), ?assertEqual(<<"12">>, luerl_lib_os_date:format({{2023, 1, 2},{12,00,0}}, <<"%I">>)), ?assertEqual(<<"11">>, luerl_lib_os_date:format({{2023, 1, 2},{23,00,0}}, <<"%I">>)), ?assertEqual(<<"AM">>, luerl_lib_os_date:format({{2023, 1, 2},{0,0,0}}, <<"%p">>)), ?assertEqual(<<"AM">>, luerl_lib_os_date:format({{2023, 1, 2},{11, 59,0}}, <<"%p">>)), ?assertEqual(<<"PM">>, luerl_lib_os_date:format({{2023, 1, 2},{12,0,0}}, <<"%p">>)), ?assertEqual(<<"PM">>, luerl_lib_os_date:format({{2023, 1, 2},{23,59,0}}, <<"%p">>)), ?assertEqual(<<"09">>, luerl_lib_os_date:format({{2023, 1, 2},{9,0,0}}, <<"%I">>)), %% Hour in 12H ?assertEqual(<<"01">>, luerl_lib_os_date:format(Date, <<"%W">>)), %% ISO Week number ?assertEqual(<<"Jan">>, luerl_lib_os_date:format(Date, <<"%b">>)), ?assertEqual(<<"January">>, luerl_lib_os_date:format(Date, <<"%B">>)), ?assertEqual(<<"Mon">>, luerl_lib_os_date:format(Date, <<"%a">>)), ?assertEqual(<<"Monday">>, luerl_lib_os_date:format(Date, <<"%A">>)), ?assertEqual(<<"%">>, luerl_lib_os_date:format(Date, <<"%%">>)), ?assertEqual(<<"2023-01-02 03:04:05">>, luerl_lib_os_date:format(Date, <<"%Y-%m-%d %H:%M:%S">>)). os_date_table(_) -> Date = {{2023, 1, 2}, {3, 4, 5}}, ?assertEqual([ {<<"year">>, 2023}, {<<"month">>, 1}, {<<"day">>, 2}, {<<"hour">>, 3}, {<<"min">>, 4}, {<<"sec">>, 5}, {<<"wday">>, 2} ], luerl_lib_os_date:format(Date, <<"*t">>)). os_date_integrated(_) -> State = luerl:init(), Chunk = <<"return os.date('noformat'), os.date(), os.date('%c', 1683371767)">>, {[NoFormat, _, FromTimeStamp], _State1} = luerl:do(Chunk, State), ?assertEqual(<<"noformat">>, NoFormat), %% Date is "Sat May 6 13:16:07 2023", %% Just check year to avoid test flakiness ?assert(re:run(FromTimeStamp, <<"2023">>) =/= nomatch). os_date_integrated_table(_) -> State = luerl:init(), Chunk = <<"return os.date('*t').year">>, {[Result], _State1} = luerl:do(Chunk, State), {{Year, _, _}, _} = calendar:local_time(), ?assertEqual(Year, Result). luerl-1.2.3/test/luerl_return_SUITE_data/0000775000175000017500000000000014677012037020672 5ustar debalancedebalanceluerl-1.2.3/test/luerl_return_SUITE_data/fun_return_multi.lua0000664000175000017500000000022614677012037024776 0ustar debalancedebalancefunction retfun(value) return value end function retfun2(value) return value, 2 * value end return retfun(7), retfun("str 1"), retfun2(5.5) luerl-1.2.3/test/luerl_return_SUITE_data/simple_return_1.lua0000664000175000017500000000001114677012037024475 0ustar debalancedebalancereturn 1 luerl-1.2.3/test/luerl_return_SUITE_data/check_unicode.lua0000664000175000017500000000125014677012037024156 0ustar debalancedebalancefunction check_hun(erl_str) local lua_str = "árvíztűrÅ‘ tükörfúrógép" return check_values(erl_str, lua_str, 31) end function check_lambda(erl_str) local lua_str = "λ" return check_values(erl_str, lua_str, 2) end function check_aquarius(erl_str) local lua_str = utf8.char(9810) return check_values(erl_str, lua_str, 3) end function check_values(erl_str, lua_str, length) assert(string.len(lua_str) == length, "invalid lua length") assert(string.len(erl_str) == length, "invalid erl length") assert(lua_str == erl_str, "different values") return erl_str, lua_str, erl_str == lua_str, string.len(erl_str), string.len(lua_str) end luerl-1.2.3/test/luerl_return_SUITE_data/variable_args_multi.lua0000664000175000017500000000054114677012037025410 0ustar debalancedebalancefunction make_table(...) local t = {} for i = 1, select('#', ...), 2 do k = select(i, ...) v = select(i + 1, ...) t[k] = v end return t end print(make_table) local tab = make_table("x", 9, 7, "banana", "z", 8) assert(tab["x"] == 9) assert(tab[7] == "banana") assert(tab.z == 8) return tab["x"], tab[7], tab.z luerl-1.2.3/test/luerl_return_SUITE_data/simple_return_multi.lua0000664000175000017500000000003214677012037025472 0ustar debalancedebalancereturn 1, "string 2", 3.4 luerl-1.2.3/test/luerl_return_SUITE_data/table_indexed_table.lua0000664000175000017500000000015214677012037025331 0ustar debalancedebalancetk1 = { a = 1 } tk2 = { b = 2 } t = {} t[tk1] = 111 t[tk2] = 222 t[t] = 333 return t[tk1], t[tk2], t[t] luerl-1.2.3/test/luerl_return_SUITE_data/variable_args_1.lua0000664000175000017500000000053714677012037024423 0ustar debalancedebalancefunction get_from_table(Map, Key, ...) local Value = Map[Key] if select('#', ...) > 0 then return get_from_table(Value, ...) else return Value end end local tab = { a = { x1 = { x2 = 99 } }, b = 88, c = { d = 77 } } return get_from_table(tab, "a", "x1", "x2"), get_from_table(tab, "b"), get_from_table(tab, "c", "d") luerl-1.2.3/test/luerl_new_tests.erl0000664000175000017500000000223714677012037020134 0ustar debalancedebalance- module(luerl_new_tests). -include_lib("eunit/include/eunit.hrl"). encode_test() -> State = luerl_new:init(), ?assertMatch({nil, _State}, luerl_new:encode(nil, State)), ?assertMatch({false, _State}, luerl_new:encode(false, State)), ?assertMatch({true, _State}, luerl_new:encode(true, State)), ?assertMatch({<<"binary">>, _State}, luerl_new:encode(<<"binary">>, State)), ?assertMatch({<<"atom">>, _State}, luerl_new:encode(atom, State)), ?assertMatch({5, _State}, luerl_new:encode(5, State)), ?assertMatch({{tref, _}, _State}, luerl_new:encode(#{a => 1, b => 2}, State)). encode_map_test() -> ?assertMatch({{tref, _}, _State}, luerl_new:encode(#{a => 1}, luerl_new:init())). encode_table_test() -> {Table, State} = luerl_new:encode(#{a => 1}, luerl_new:init()), {ok, [], State1} = luerl_new:set_table_keys([<<"foo">>], Table, State), ?assertMatch({ok, Table, _State2}, luerl_new:get_table_keys([<<"foo">>], State1)), ?assertMatch({tref, _}, Table), ?assertMatch({Table, _State}, luerl_new:encode(Table, State1)). invalid_table_test() -> ?assertException(error, badarg, luerl_new:encode({tref, 42}, luerl_new:init())). luerl-1.2.3/test/luerl_return_SUITE.erl0000664000175000017500000000424114677012037020406 0ustar debalancedebalance%% Copyright (c) 2019 Ferenc Boroczki %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. -module(luerl_return_SUITE). -include_lib("common_test/include/ct.hrl"). -export([all/0, groups/0]). -export([simple_return/1, fun_return/1, variable_args/1, check_unicode/1, table_tests/1]). all() -> [ {group, return} ]. groups() -> [ {return, [parallel], [simple_return, fun_return, variable_args, check_unicode, table_tests]} ]. simple_return(Config) -> Tests = [ {"simple_return_1.lua", [1]}, {"simple_return_multi.lua", [1, <<"string 2">>, 3.4]} ], run_tests(Config, Tests). fun_return(Config) -> run_and_check(Config, "fun_return_multi.lua", [7, <<"str 1">>, 5.5, 11.0]). variable_args(Config) -> run_tests(Config, [ {"variable_args_1.lua", [99, 88, 77]}, {"variable_args_multi.lua", [9, <<"banana">>, 8]} ]). check_unicode(Config) -> St = run_and_check(Config, "check_unicode.lua", []), check_unicode_call_fun(<<"árvíztűrÅ‘ tükörfúrógép"/utf8>>, 31, check_hun, St), check_unicode_call_fun(<<"λ"/utf8>>, 2, check_lambda, St), check_unicode_call_fun(<<9810/utf8>>, 3, check_aquarius, St). check_unicode_call_fun(Input, Length, LuaFun, St) -> {[Input, Input, true, Length, Length], _} = luerl:call_function([LuaFun], [Input], St). table_tests(Config) -> run_and_check(Config, "table_indexed_table.lua", [111, 222, 333]). run_tests(Config, Tests) -> [run_and_check(Config, Script, Expected) || {Script, Expected} <- Tests]. run_and_check(Config, Script, Expected) -> DataDir = ?config(data_dir, Config), ScriptFile = DataDir ++ Script, {Result, St} = luerl:dofile(ScriptFile, luerl:init()), Expected = Result, St. luerl-1.2.3/test/luerl_funcall_tests.erl0000664000175000017500000000753114677012037020771 0ustar debalancedebalance%%% @author Hans-Christian Esperer %%% @copyright (C) 2015, Hans-Christian Esperer %%% Licensed under the Apache License, Version 2.0 (the "License"); %%% you may not use this file except in compliance with the License. %%% You may obtain a copy of the License at %%% %%% http://www.apache.org/licenses/LICENSE-2.0 %%% %%% Unless required by applicable law or agreed to in writing, %%% software distributed under the License is distributed on an "AS %%% IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either %%% express or implied. See the License for the specific language %%% governing permissions and limitations under the License. %%% %%% @doc %% %%% @end %%% Created : 11 Jan 2015 by Hans-Christian Esperer -module(luerl_funcall_tests). -include_lib("eunit/include/eunit.hrl"). external_fun_test() -> State = luerl:init(), F = fun([A], S) -> {[A + 2, [A + 3, A + 4]], S} end, State1 = luerl:set_table([<<"testFun">>], F, State), {_, State2} = luerl:do(<<"function test(i)\n local a, b = testFun(i)\n return (a == i + 2), (b[1] == i + 3), (b[2] == i + 4) end">>, State1), {Res, _State3} = luerl:call_function([test], [2], State2), [BoolVal, BoolVal2, BoolVal3] = Res, ?assertEqual(true, BoolVal), ?assertEqual(true, BoolVal2), ?assertEqual(true, BoolVal3). external_nostate_fun_test() -> State = luerl:init(), F = fun([A]) -> [A + 2, [A + 3, A + 4]] end, State1 = luerl:set_table([<<"testFun">>], F, State), Chunk = <<"function test(i)\n" " local a, b = testFun(i)\n" " return (a == i + 2), (b[1] == i + 3), (b[2] == i + 4)\n" "end">>, {_, State2} = luerl:do(Chunk, State1), {Res, _State3} = luerl:call_function([test], [2], State2), [BoolVal, BoolVal2, BoolVal3] = Res, ?assertEqual(true, BoolVal), ?assertEqual(true, BoolVal2), ?assertEqual(true, BoolVal3). return_lib_function_test() -> State = luerl:init(), {_, State1} = luerl:do(<<"function test()\n return string.find end\n">>, State), {[{M,F,A}], _State2} = luerl:call_function([test], [1], State1), {Res, _State3} = apply(M, F, [A, [<<"barfooblafasel">>, <<"foo">>], State1]), ?assertEqual([4, 6], Res). define_fun_in_lua_test() -> State = luerl:init(), Chunk = <<"function mkadder(incby)\n" " return function(i)\n" " print(\"Call into Luerl!\")\n" " return i + incby\n" " end\n" "end\n">>, {_, State1} = luerl:do(Chunk, State), {[Fun], _State2} = luerl:call_function([mkadder], [1], State1), {[Fun2], _State3} = luerl:call_function([mkadder], [2], State1), ?assertEqual([5], Fun([4])), ?assertEqual([5.0], Fun([4.0])), ?assertEqual([6], Fun2([4])). define_fun2_in_lua_test() -> State = luerl:init(), Chunk = <<"function mklist(numentries)\n" " return function(entryval)\n" " local list = {}\n" " for i = 1,numentries do\n" " list[i] = entryval\n" " end\n" " return list\n" " end\n" "end\n">>, {_, State1} = luerl:do(Chunk, State), {[Fun], _State2} = luerl:call_function([mklist], [5], State1), {[Fun2], _State3} = luerl:call_function([mklist], [10], State1), ?assertEqual([[{1,4}, {2,4}, {3,4}, {4,4}, {5,4}]], Fun([4])), ?assertEqual([[{1,4.0}, {2,4.0}, {3,4.0}, {4,4.0}, {5,4.0}]], Fun([4.0])), ?assertEqual([[{1,4}, {2,4}, {3,4}, {4,4}, {5,4}, {6,4}, {7,4}, {8,4}, {9,4}, {10,4}]], Fun2([4])). newindex_metamethod_test() -> State = luerl:init(), Chunk = <<"local t = {}\n" "local m = setmetatable({}, {__newindex = function (tab, key, value)\n" "t[key] = value\n" "end})\n\n" "m[123] = 456\n" "return t[123], m[123]">>, {[TVal, MVal], _State1} = luerl:do(Chunk, State), ?assertEqual(456, TVal), ?assertEqual(nil, MVal). luerl-1.2.3/test/luerl_tests.erl0000664000175000017500000000167314677012037017266 0ustar debalancedebalance- module(luerl_tests). -include_lib("eunit/include/eunit.hrl"). encode_test() -> State = luerl:init(), ?assertMatch({nil, _State}, luerl:encode(nil, State)), ?assertMatch({false, _State}, luerl:encode(false, State)), ?assertMatch({true, _State}, luerl:encode(true, State)), ?assertMatch({<<"binary">>, _State}, luerl:encode(<<"binary">>, State)), ?assertMatch({<<"atom">>, _State}, luerl:encode(atom, State)), ?assertMatch({5, _State}, luerl:encode(5, State)), ?assertMatch({{tref, _}, _State}, luerl:encode(#{a => 1, b => 2}, State)). encode_map_test() -> ?assertMatch({{tref, _}, _State}, luerl:encode(#{a => 1}, luerl:init())). encode_table_test() -> {Table, State} = luerl:encode(#{a => 1}, luerl:init()), ?assertMatch({tref, _}, Table), ?assertMatch({Table, _State}, luerl:encode(Table, State)). invalid_table_test() -> ?assertException(error, badarg, luerl:encode({tref, 42}, luerl:init())). luerl-1.2.3/test/luerl_time_SUITE.erl0000664000175000017500000000342214677012037020025 0ustar debalancedebalance-module(luerl_time_SUITE). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). -export([all/0]). -export([os_date/1]). -if(?OTP_RELEASE >= 25). -define(START_NODE(Name, Env), (fun(Name, Env) -> case ?CT_PEER(#{name => Name, env => Env}) of {ok, _PeerPid, Node} -> {ok, Node}; Err = {error, _Reason, _NodeName} -> Err end end)(Name, Env)). -else. -define(START_NODE(Name, Env), (fun(Name, Env) -> ct_slave:start(Name, [{env, Env}, {monitor_master, true}]) end)(Name, Env)). -endif. all() -> lists:flatten([windows_tests(), linux_tests()]). os_date(_Config) -> {ok, LusakaNode} = ?START_NODE(africa_lusaka, [{"TZ", "Africa/Lusaka"}]), ok = set_path(LusakaNode), {ok, LondonNode} = ?START_NODE(europe_london, [{"TZ", "Europe/London"}]), ok = set_path(LondonNode), LusakaLocalTime = rpc:call(LusakaNode, calendar, local_time, []), LondonLocalTime = rpc:call(LondonNode, calendar, local_time, []), ?assertNotMatch({badrpc, _}, LusakaLocalTime), ?assertNotMatch({badrpc, _}, LondonLocalTime), ?assert(LusakaLocalTime =/= LondonLocalTime), ?assertEqual({ok,[<<"Sat May 6 13:16:07 2023">>]}, rpc:call(LusakaNode, luerl, eval, ["return os.date('%c', 1683371767)", luerl:init()])), ?assertEqual({ok,[<<"Sat May 6 12:16:07 2023">>]}, rpc:call(LondonNode, luerl, eval, ["return os.date('%c', 1683371767)", luerl:init()])), ok. windows_tests() -> []. linux_tests() -> [os_date]. set_path(Node) -> [case rpc:call(Node, code, add_path, [Path]) of true -> ok; Err = {error, _} -> throw({badpath, Path, Err}) end || Path <- code:get_path(), filelib:is_dir(Path)], ok.luerl-1.2.3/Emakefile0000664000175000017500000000006314677012037015033 0ustar debalancedebalance%% -*- erlang -*- {'src/luerl*',[{outdir,ebin}]}. luerl-1.2.3/priv/0000775000175000017500000000000014677012037014207 5ustar debalancedebalanceluerl-1.2.3/priv/images/0000775000175000017500000000000014677012037015454 5ustar debalancedebalanceluerl-1.2.3/priv/images/logo.png0000664000175000017500000004510414677012037017126 0ustar debalancedebalance‰PNG  IHDRúúˆìZ=ZiTXtXML:com.adobe.xmp LuErl-Logo-14 DÁ!fiCCPsRGB IEC61966-2.1(‘u‘»KA‡¿DEñ-±°°-$´L(‘ÁW“\^BÇ]‚ˆ­`Pm|úh+X ‚¢bm­h£áœ31³ìì·¿vgÁJ)i½~Ò™œô{í‹KËöÆW,Øhg®°¢«“ssjÚçƒD‹Ý¹ÌZµãþµ–hLWÀÒ$<¡¨ZNxZ8°žSMÞîV’á¨ð¹°S“ ß›z¤Ä¯&'Jüm² úÀÚ)lOTq¤Š•¤––—ãH§òJù>æKZc™…yYûdö¢Ä;3LáÃÃãâ=¸p3$;jäÿæÏ’•\E¼Êk$H’Ã)j^ªÇd‹“‘bÃìÿß¾êñQw©z«^ ã½w X0Œ¯cÃ(ž@Ý3\e*ùÙ#û½Pчб×-²—ÛÐ󤆵ð¯T'ÓÃÛ´-íšWJ=+Ÿsú¡MùªØ?€‰ïXýHïgØä»Ù pHYs  šœ IDATxœíw˜\eÙÿ?ÓûlOÙL’MïFhJ(‚QA¥¾VDQ|-¯ þTÅQT@T)„LB KHï}7™ìn²}vz;¿?f“l™9çÌffvv÷|®+W’=gÏÜ3s¾çyžû¹ ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( ª6@¡ÿ8œÕF`20 Ø"‰¿U@ð÷ú»÷¿À~à€ÇíjË×ûRÈ>ŠÐ ‡³Z”“sï?ÈßwØF7áwû÷ÛåÍ“ ýDzápVkÀE]ÎJÔ(qÀfà=` ðžÇíjX“z£}€q8«ÕÀl’¢¾p¶5êôÙÏ)á¯ö{Ü.a`MÞ(BÎê1À•$…}!P1°åœàßÀ?€µ·+1Àö ;¡ç ‡³Ú\ Ü \Âðýìÿ")úe¤ÏÃõfË ]ÓòóIŠûS€u`-*8ꀒýFEô¹Czp8«'·7Ue‡Z¥ÂlÔ`1j°µXÌ:t5ˆ'½h Œãiê$Ðõà àqe+/û(BÏ]£÷uÀÝÀ¹¹~½R›ž3&—2m\c*lŒª°2f„¥tZ5:­­F^§F«QK^O ¹=H}³c-~šÛ´´iîr¬%Àác>öñŒÄrýÖüÀ“À#·ëP®_l¸ ý4q8«5$§åßfeûúevçŸ1’ cìŒ*·0ºÜƘvÆ.¨×dûåD‰Åk ÐÐìgßá66ï9ƺíjèDÈþ¤;¼<ìq»j²~õa†"ô~Òµßýà»À´l]×fÖq³ŠsϨdÎÔ‘ŒaC­*ì¯iO]ëw6°mí:ÆO'ñDV•ÿð0ðªÇíŠgóžƒ ‡³ZGríý¿À¤Ó½žV«bÞäR–-Ü©#™7½‹IwÚv$»k[Y¿³‘û›x[‡|Ùºô~àÇÀ³Ê]f(B—‰ÃYmn¾Œ?kiÔ*.ž?Š‹8˜9i$gL‰Z=t¿Š]µ­¼¿¥ž¯ÜÇÖ-Ù¸äzà·ëýl\l80tï®,âpV_üždly¿P«T\¶x,Wœ3ŽyÓGQUYœ=ëw6òн,_WGsGøt/÷<ðmÛu8 ¦ i¡‹àpV>ÝßkŒ,5òµOÎácçMfD©%{Æ r¼þÿ~w¯¯9ÀG{š‰Æú=¿ò¸]Y[# 5¡§ Ë“þeà§$S;3fÑô2nùØT.\4»ÕUû†vç…{ùï{iëŒô÷2õ$—UÏ(ë÷¾(Bï…ÃY=x XÔŸß¿pÞHn¾b:ç/˜€Q¯Í®qC_ Ê¿WíãÅûظ§©¿—YÜîq»vdÑ´A"ô.Îj+ðCà@FÔ*\µÄÁg/›Î’¹ãÐÈPQ§f{#ým=ëwëÏ}øð;%¬6‰"tN:ÛÆeò{*|æ’IÜpé4ΚQ™ã†9/¯:ÀožßÀ~O¿j[¼IrtöùñÃZè]kñ“Ü—Z _¸j:ŸZ6é†z†éÀŽÄyüåmüù•í4·‡2ýõfàó·ë•˜6h¶Bw8«G'™.›ySËyðË‹9cÚèܦ–æö ?³Vî#É8@î1à^ÛåÏiϰºÃY½„dNô¹¿c4hxð‹ ¹öâtù1WèÉîÚV~öÔzV~äAÈl¿ø¬ÇíÚ#Ó –a%ô®B‹_'7-Û%~½s÷Þ4Ÿ±£‡gK¡òîGGxèéØžY´] øšÇíz,Gf$ÃFè]^õ?7Èý1~~çÙ8ô; N!Ç4·¹õ‡o±ãP ñxF£ûCÀw†Ëžû°ºÃY=ƒdÊã 9ç«ÕpÏgpÛÇÏ ÈfÌ­q ýbÃîãüã­lÚQG±)A‘ÍÌî†8uÇ™\æ_À­·+˜#3 †!/t‡³ú|à5dF¸(6òØýKY0Û‘[Ã2&ŽñÒªý¼úîn:Ú[)2õ¼}Õj5èm¬ÙÞšÉÞûûÀ5·«9ËæCZègõ¥ÀË€IÎùÌÅ/ª/ ²¢_Q¯ 9¢½3Ìã/måíµ»±ëcHÚí6Öí Ðê•N»ø˜ÇíÚwš¦,CVègõu$³›ôrοçÆ9ÜñéùJØjáõGxüß[y}õNJLq2)¨£×éhظ¿C×zÜ®÷úajÁ3$…îpVßü¡¬fƒ†ßßwŸ}Ú5$²D§?Â/oã¿î¤Gp1̶"Vln“[ñ&Üâq»þÑÿW,L†œÐÎê;HæŽK2{b ¿ýæR&+˱U rˆDã<öïm¼¼b;E†(†,M®ìv;ïn÷ Ë ²Hîµ?ŸW/ †”ÐÎêûHn›HrÓe“ùÎígc·*^õB`Íæ£<ø§÷ÑÅ;±³[Z­><’»nŸð¸]¯fÝbH½+æÇ$+±Jr÷ s¸ës Ѩ•,³¦¹=Èÿ´Ž-;1ºHE.ë`šŒö8|LÖnZ¸Òãv­ÈEùc¨ÜéßC¦È¿wÛ<î¾i±"òàÙ7wsÝ=/â©«¥²8·"†ÂL*M0»JVKðŸ®péAÏ Ñ»oOË9÷g_YÄç®:#Ç)H±§®ïýá=:Zš(³æÿT©TÄ46>Ø%«!L°ÔãvmαY9eP Ýá¬vo¢õ‘Õjøõ]çð‰‹gæÇ0…”D¢q~v#¯½»1Å0Ðõ9ôæ"Vni•sjpÇíÚc“rÆ ºÃY= ø(;O­†Ç¾u—Ÿ75?†)¤äȱNîøÙ;Äüm”X ç¶Ó‹po“%ö£Ày·«6·å†ÂùÄ3 +—ü`¢ØyZµš¿|ÿB–.T’R’w><Ìw]M¥-б{S:;kwÊšÆyÜ.YO†BbÐ Ýá¬6+³ÅÎS«áï?ZƹóN«×‚Âi~ùô^\¾•ªr…Û£BEDcåÃÝírNþ/põ`ËzTº:–>\*uîoï9eK&çÞ(…”´t„øâƒo³eû¥¹÷¨Ÿ.Z¢”•Xil•l*1ˆxëjÖäÁ¬¬1Øö˜~ \/uÒwnžË5Nσ9 ©Ø°û8×Þû¾ÖFFØ \á]‚€M”»õö€ÃY}I®mÊ&ƒã[Îê«ÉH¥›.›Ìƒw^ ì“O½¶“ß>WÄrЯ@«ÑPïÓ³×#Ùô¥˜çq»³AÃòß^ËøJÑPw…,%¸ñ»¯ÓÞ||Ðì‘g»ÝÆ›;Hˆ——m¦bEÙ‚ÑÎjð¡_ßuŽ"òà¿rÓØ8¼Dàõvrá™’÷[2+囂:ð5@4võÆK&rÅùÓòdŽÂ ~þÔzÖm>ȸ!¼&#ì÷2eŒUê´Û»Ò§ Š‚ºÃY]ü@ìœÑåf¾sûÙƒ~¯v°ñÜ[{xöõ­LQP·Lž˜T¡B«‘¼ùþØ53- í[ûU~wÏù”™ódŽÀêMGyðOk™6jðÜ.>€ófJNá§÷åÁÙŒÐÎêÙÀ—ÅÎùÊu3YtÆØ¿€e²R²@,–àx«&€5uÖ;^¯—³¦Kv©ÃY}A>ì‘bÀ…Þ÷°Ø9+m\{‘’_žO~ñÌ5S>UZ ¥ÆfƒdâË÷óa‹.tà+$«v¤åG_\ˆY™;æuÛxêÕ­LBI*¹  sþ,ÉQý’B¨ ? ßd×hþm±s.:«ç¥¸c¾èôG¸ûa7“G¨¼ó` àë`ÜHÉ®Ü>ªôWyP™î Z ÷ß:ÕpßÓÉ#÷?ºuÜŸ“þgCA˜åúgõ‚|Ø“Žz—§ý^±s>Õ4fL™'‹^ZµŸw?<ÈØÒ~þ.:½^…=ªä7zpfºƒj5|þ%3-_xŽûøÁßW‚bú…Àìq’B¿Úᬞ›kR1B¿Gìàm›Ê˜‘Eù²eX#p×먰(ûåýÅßéet™d nY@sÁ€½«rŒhy¨—)I+ùâ™7w±çà1F³Œ´l"s«$ƒh®ïŠÍ;5¢‹Žæ—.£¬Íó„/åág60±Bùéâëô2ªD24VôÞÏyzWéæ›ÅÎùÂÕ³òd¯ŸÛˆŽ0ƒ"ôÓEæN”,;õ)‡³:ïYY1¢ßA28%3ƳhŽ#æ _j¼üí¿;_¦xÙ³EÀ×IE‘è¨n®Ë“9'Éë7ܵ¥v»Ø9wÝp%R#/<ðd £ì Tø ›D"!gT¿5¶t'ߊZ ŒKw°Ôn`éªüY3ŒY»¥ž5ë†|qÇ  ¢o{‰ÃY×ik¾…þi±ƒß¸a“Òi%×üøOë_¦.àVƃ—p8Â,ñf*à¦<™äQè]-E…¾t¾RT"<·|7žÆ6%3-‡Œ)‘,}K>ëÀçsD?HÛiaÞÔr&8ÊòhÎð$OðÈs›_¦ˆ?'$÷Ê …ÂT–‰NßgwÕiȹžÌ+vðü¹ò¼› ýç•5)µ¨ò’¼‰A#:½ƒ^‹Q¯#Žâ „âa¬ºxÁ$ÑÄPZZÄ™S+DÏ Gâ|ãW+9|¤ ³ÕÂ?vMÑ9—:ÀÄQFŽ6ÅN¹x^ÖÅúA®….º>Ÿ¥¬ÏsÎkkæ|ÚŒª‰kÌœ1}wÞp•å=ó±C‘îhäwÏoÄçëÀª—Ø|Îþ¸žïß²Xò¼o>²ŠFÏQìz΀šÎ@»å”.‘÷^¬ÒKù‹ÄBO»>W«aòxEè¹dÇÁ7t°hbî*KtFõÌŸSÅwn_ŒQŸúv2êµ\0ÏÁùsügõ~a#6ÀF÷xÊJ‹™3¹\ô¼÷·Ösðp#v݉l@(zRè±xŸ?„UÆ8 ¢V©H¤ÏŒÉi‚KÎÖègµ8+Ýñ3'•RbÏ{é¬aÅ«kRjÍÍ´=!@GÌÌWn8›}ùÜ´"ïŽJ×:'óÈ}ËèŒ[Hd –M1-w|*í­y’?½´«öTÀ‹ P$~òÿ<ñ¨¬×ŒD£Œ!ºNŸÖ•Êr錛‰ÈŒaÙ"%÷<×¼ºæ 9Šk÷ÆLüêÞe\uþ¤Œwê¸\ߺB²äRNPëL,š•6õ€¶Î0Ç[¼=’j*JN‰uýÎHÈÏGQ,ºçnr&Š\ ]ô˜=Q™¶ç’­ûš©?ÞI±9ûBïŒê¹ó†…L¯ê"Òä±Å,[2™@4¿A< F•Û¤J=ñÌë;PÇ=~¦Óë°tÛ%ú`k=½üÏ×n’|¯9ë >`BY>0OóáÂòš:J,ª¬'°¢jΞ7±_#yo¾ú©¹Zñ °l㨸â\ñhLA€w××aé5÷Þ nlîÌhY¤×H®UfÈ¿Zf ˜ÐË‹¡ç’ší9).!è¬|ûVioµtZ5ç5–¼envКX¶¸Jô”Ú†"¡¾[afã)å74û ‡B½t<.é¡Z#ºA¯¡¬DqÄåŠX,Á–}MØ%ûþe†?¢æ“—LG'‘ŽÄihöÓÜ$&±Ï¼tþ8"‰üÕ›¶[MXÍâAZk6yP%zŠ8˜?ãÔº~åúÃËLèÁ`µø+gBÏåöZÚùÑœ‰%hÔJ‚E®Øº¿™h4†YŸ]iŒ6>{yúÙe$çñoå­@<Š€ NÇ%‹'pÇõsѦx@Ì™\ŽJk}/˜eâ S.Z€µ›öY{ÇU.={ÂÉÿ»7–³7ÞƒD"Áˆ­iƒKègµ‘B3«J2¾æÏÿò Í©o†}å\Šl’,‡ ëwÞåi{$³gŽ@›¦¹ÆòšZ~÷üG¨¢~¬ºÄ©;Kòöêmì­kÃußÅ}|&ƒ‹ÙáÜ ÝóæJ—Soi÷£ëe§Nodâ˜d6© @S«c?>âQâBépV—xÜ®¶Ì¯,N®Fô $kW§dâÉ¢y}¨kìdÇ›òX4&/ q¸ðáÎÆ¬ =”ÐrÍÒ))mòñÈ35ibVlÑ'¨=|”ç—ïâ3—õhÔ*ò±¥®ÒX,±­ÖÜ$ £ë¦ A€Š2ëɇԡú¢‘p¿ZL[$gYÓ2¿²8¹š?‹:âÆTdîˆS‹¸7E¢†%í<–õõ¹FgbnЏðxBàî‡WbQ‹È]œwjêR‹Åâ)žm´:=cFˆOÝ×mk@èµööEàÂ…ãOþÿíšZÔBfëóÈx8ä¤ÜR®„.º1²,s¡‹í{&*ĪÙw¤öÎÖ,wG-²SNÛóÜ"þ6ÉÊ5*’SâTÏä|ÍÈìV“ävãŠõu˜õ½ŒÔ¹há©Nbë2Ü?ïŽZzî’“j3¹ºhJPYqæw1¡ ʈ~’õ;±³öšÊ‘P³í(&­<¡Æ¢Ž6ùzü¬¡ÙO4šûýµH ª*¥+ÈÔ÷öyhMFF–&ïÙh,AKGßtU¹‚äg5¨„.ªd£>óŘ—^ÑO±u_3¶ ½ÁrÐiú®-;ýüùSX!bݶú?ûíó0¨DÓ7³B0 ‹f‰§EB±>ï'ž€ÊŠS>¥ÿ®=H"Ü¡'¤ó×3w`É`@„®ïǶ؈W„~’Ú/Æ~N+Ó!©¿³š}Ö³bXôðŠ{ÿÉé{]ƒ—­ûÉò.`JÔ:ƒdÙ²M{Ž“ˆö|?þˆŠËÏ9µ}áíÝX¥3¤%—ôGädDÏ•×]\èºÌ_V̧LÝOQ×à¥(ËE{T*ðú–-þ`«ƒFþM¯QCG[37~ç,&Çš;0ça4@­eühqGÜ;5µ{-CT:çÍMúÇ[ü´wø°†jdª:Swƒ.»#º2uO‹%hhöcì½ œ|¾YZF½6£Æƒfmu¸[#vmmš[Á7V!ËðFÈ,ä’‹É6à{·ö) iµ˜NæŸ?ùò6tÂé=˜bÒ#zN¦îyÑ ‰<Êöš4GŽwOÈ(–1ÁP„H4޾ÛCzÜè"ÜqY[F}sbZ®ºh6_ºî Y¯í¿|éƒ3$°šÅË2ÇÞÎ`"¾ˆš[¯J«%vÖ÷ë½v'‘H ×©‰DÓ>¹†Æˆ^$gœeD—¦®¡£Žœ´\bvjíñ³‹Žm–7ìAcä ×Î9ùÿ)ãŠùúóñGûwï$=îâúÙ{¸ !ÞsÖ¢ÒY¸Æ™löþ–z¢¡þ;áºc¡÷Ó%¬ŒèÒÔ5xs2m0hb¼üîÞ?+/61¶²ŒP–KÀÙ¬Æ>É—-™€ÎØ¿D¨PL`ö¤¢ç¬ßÑ€*qÊŠÁüY•'xþöÚv,ºì¼Q³Até:4¼îöœŒèýºä£®Ñ{ÚSËt´°ëPsŸŸÿúÞ Ñ˜Jñ†4’ å¢O±pW©À$£†z*4Œ!ž÷¾~Gæn»QLÜqý\¼þõÇ;²› Õˆ^('ß`Þ×èv‰µR:”]šÚ†ÎœŒè | ±h”„ ômz-ÏÛCÑþÅ5‹ ]Y£PßäËjÛ¥H‚‰ò2;_¸b-—2ŸÚ¨×²dÎh–tu!„äìbÕGGxáímØ4™yªÃiî¶§Ðã ð%LXL&¢!&MêÎ¥‚JÓ£Ö[o‚@§?|Òçé¸ûsO_Qs¨Oµ™ÓABè9IãË•ÐS§™ÍýKŒSæî¾`Kc‘8„03câHî»eÑÉðO¹¨TP5ÚÎmŸÅÊõµD;3z§/D|¿+?<Ô77ý4QK×JBBgž,V=³FtQû²ô J÷0‰'Báx—ò®åi™6i,?¿Ë)U™”—ÞÝÇ_^ÙŠñcÑDZç¸Óu0®ãM•}þ®ÚVb‘PÊèhF•‹ï¡Gcq‚Qw~!¾¯¬>@<œÝÑÄÊ] *¡§º„úYQèS÷ÑÁ®ÏTNq]_Tǹ ¦ðí[‹NÕ~öT ït«.œõ›>“™3Äk»uçß+÷ #µÃ,pH”jõF¨ª,çò%É*¯‚Ͻ±«>û%®TCLèÙÑ }ê.¢˜l¥Ñ¦‹¨ê.tñ +ðÇ \»lŸ¿fŽèyáHœ»o0©¥ IDAT~¹‚††F¬ºüÔtD`é¹ãz<€‚ÀšMõœ1¥œ’!ÔÛ÷7¥ŒÅ‘¬÷ë{/bÚøS•‰kv4 ø°å`æ¢NQÀ£}óÀ€ÝëË|»¢Ð“Zò1¢‹MÝѤ×Yl„Ä4,™?IRä Aà󼿭³.¿Ÿm\cæÖ«N9ᢱ_èn`êD¿ýÖÅ=Îoõ†ðùØÒèG¥ÑRV,¾åÑ»}òþµ ‹67å­â‚¤Ðäâusëî;xäXgÆ,ô5z>*àˆMÝ ¤ÍÄ ¸´œoߺHòu~ûüF:ÛZ1æ[ä Y^D©ýTÜìþøõõ˜´ ÆWöÍ÷xóýZT"UnÔjmÊY@:ÕwÐÜ’½¸öÞÂ’AƒJè©#GºØDtÀO‰FdNZBÏGœtÛx"­+‡ U,† @DcçwߺDÒñvðho­Ý‡9ÃézB€Îˆ–ÚNLWL@°â™ˆdàŽñÇ ÜsÓ“ÿ÷÷±uO=&@TeäÆKûÖ„»æϸJ¥îñàâ‘g7`R÷/zSÑDåâus2u÷¸]­gõq enà†½™/CòáÕ>Ty˜qˆèV³•*9*öõÅt|óöEØ$¶ã oýfÖ bÓã $LŒ¬(æëWÏáœ3+O~W­Þßÿý{ÔyŽaÓ‰/×â QQ̬ní´òäû˜ºJMYÌf½2Т±-m>,bE•»Už±­3Ì#Íi—Ù ©CtIàñ¸]ò®g@.{¯í&зh%‹£KWG(ƒÚ랇í5­FQ¯%–HÐ}ÿ:!€ÕfÇyÖXÉë?ýßDüí²8Â1ˆëŠxôþK?ºï´ºÔnäÑû/áëøÕÓ5Ø5þ´>„@ÂÀo=ûäÿwjåðÑfì:EaɼÊ>¿³vëQ‘ ˆÌ̵µä,æ¿ÿç&´ é,µhB = `ÓÉ_Ë«T*š;Du|PöÅ2$—w§;‰%8ÖœÙ:]LH…P6>©È8›Eß§¶š/ªçîÏ-”ñövM-™N#q0Ú+xîÿ]RäݹdÑxüÚR:c©§ÐñŒ(/aæ„Ò“?ûé_>À¢IŠ"ª2ð™Ëúöü÷н’K ÌB¤ñ„@Í6& O{(¦Be*åWßúŸ½j¾¨ü±Òd4‹‹Þ 9YŸÃ  ±¹o̶¿½6€!°'t6³®Ç=ž€’’"ϯgà DéðÊK…NÕØyì/=.*ÅYÓFpáâÉ¢}‡KÂľtîÉÿ×lo ¥¥Ñ¢f³™±#{n‘ n8uN:ô2 ‘î:ÔJ<*¾6F5Œªó^ÅÔq%|ú’© ‘ïèÓh%÷ë¥Ðw‰ìݱCŠB÷º‹Û—×ÑÍzºçKø£Zî¼a¾¬k¿µ®bòÖæ¾˜ÿ÷µ¥’kþÞÜsÓÌöº'´¢®8o*U]³A€_=³kך>…¹ÓúÏì=Ü–Œ†“@'Sè«7A#¤÷#øcZ¦MÏ£÷_ròá±z³ò½ •¤Ü¥ÐEGôƒG3ó¼+ktñ5:$§îÝGtµÎÀüéâµÒNðÞf¬=sA»ÝÊìIé›!DÒŽP«Tüâ’ûÚ±8¬Å|õÓóNžóvM~Ÿ÷äöV7¦èÀêFÒ;rý@ãGRËÁѳxî~öõSá Í~~ùÔ:¬Zù¾³¿äç›3¡çÒw‘ÌwèÃæý­©~œ–‚ŸºçaÆ‘î38q}»YÏánB·š²§®mÞ ä4ÀÕpÇÇRg•­ÛÖÀ/Ÿ®! SYQÄÃ÷\H‘µçÔÖ1Âʬɣػï Q?wÛòK|a#Ön.£Ét²/ywl=*µH/öx‚>¯ŸŽ‹寯– ¶žìŠBDmå·,bÙâSÝTOñXÔ™U}:tLtÆvftÁ ÈÙˆîq»ˆì§¯Þز)@:Ä„wpäÑ4Õ,ÍÝ¥Öè£Ê,„cB×Ï`d™x2GwAyÑŠƒ…ËÏ™ÐççÿqïçÇV¡¶Q¤ ÐÞÜÀ—|+åè~ÿígÓ2ãºoYê5/¼³—XðTíöp fNJݯ³È¢‰©p4Žh ©îõZþüƒ+¨tŒ#¡/A0–±xÁLžùÉÕ=Dð¿®!î ÛãúFÇÚD—Di×è]{j“Å#É×Ri²¼ímÞ0‚Œ§Q$®áüy}<ñ>Uߛآxóý)Ãr{?³ž|eD{:hÕZ3'–’ µJÅ—>q&m¡¾cU$13—^0›.&òŽ2cÿ‘vþòŸÍXûï Kîo®é—Q2Éõˆþ®ØÁ·>ôð?×Í;å$….tñ©{~¶×¦Œ-&O†ÁªÔZÆTÈ›ºÇâ T*iÕ-¥E=].±X‚úãXÒ¸â±(í¾°h¼y0ãµÕû°êz>l¬–¾ºsÅ9ió†ùûÛQ QAH>¦Ž ú3ó©,ïg]­4¶ø“m¡´ý›]{š%wÞï×…e’S¡{Ü®F‡³z0+Õñu;ŽÑÖ ¤HºFÙ Þ^ËÖ>zoÙ‰÷_^l¢Èj ‰"èä¯br;ª4”õº@—"Ï/§¥#(*ôß>¿MÔ×#ß=!@E‘øúZ¥‚Ï]1ƒë.œBs{P$ÆÄÊ"´™,žep¼5Àx“Ð)+ß¿7:­–ÃÇEq»=nWSí“C®§î 2}O$`×!yï¯à½î"ŸdÖ¼îéÖèÝ®?É‘\§«ÌŒ’x\HŸöÖ•º[§UcЧÑè )½æ'èð…Y½±S¯Ä”P¦ïg~³Q˸Q6¦Ž+ɺțۃ|á70&¼i;¿Ja4›¤¢7sº>‡ü}¥ØÁM»O_èÃ%6ÝÈÛSèÅ"*’{ÍÙD«Q§\>˜ÒT}Eጩ£D?›_>½]¼ï6•ŠdVÞ@â9îãó?~}¼ÿ"Ç$e–Óõ9äGèn í7öÚûu².RðSw‘Q*ꤾNêºûöâdGI}'Òžß›Êr ‚ZzO)gO7^6“ÎhÏ‘>–€¨ÆÆwn?»Ïù'hj ²i×Ñ”ÕaTªô[2aݶnüÎ+Üpÿ+¼¸bŸì~=Ä—ø/úxGʦ™°ç¨dÄáàÑ=nW;°!ÝñíÛh”‘àRðÎ8‘Q¶FÖ´Bïöþ§ŒMŽè‰xœ™]q´Z5“t`‰ˆâIQWþªó'qö¼ ´‡õøÂ¾ˆµœGï…ÿÞï×`L³å¤Ó@ýñ̤»ÓÜ䎟.çÁÇVB°u¸…¿¾´Žîÿîž´‚?x´ƒûYÅïŸ{Ÿ"m £½òTX-fŽ6‹ ½žå w'×^÷¬¦;X³ÕÃ5¥Þ/=A¡¯ÑÅêuûùúŒ e„" !Æëk0wjꀓÞÛL´‡Ä«È ±›öcܨ¾5ؾû?KØsñ4>ÚÕˆI¯ãM͘{ëƒZŽ6O[—M£†Úú¶>M¥ˆÅüáÅͼµv?Fü=®oÕÅ­<ôä*~c2c³Qj!ŽÇië  ÐÎZ½¸ˆ y¡—=nWÎoà|LÝAb?ý¯¯‹¤¤"ã¾'“Q¯Iû0òÉŒ:“—ffÐ]èŽV#mDâÛöÉwä~ýƳð¥I#=Õ ðR¯é'P©`zU)7]1“ë/¹?åwÿøH2—;ðÑÎc’¶Ÿ`ùº:®¿ï%ÞY³ ›ÆŸrÊ­R]Åï â=NÝÁC4×Á×Z.Ú†]Îjëé]Éí¸dïÕÒ“/¡¯Ò·´»™}uâUg ݧR©(K³…Ôé?ý=O°ïhê*Ú½VçÍ­¤= Ðé ÈžMÌžTΌɣ[e¨UÐÜÚI‡ïôŠ üè±µèâÒË5«.ÆÃO(¹®Þw¤Ï}ï5\O¯Á„s[‹µxAÍÓÁj5ÓÐ"º|jÖææÕ{’—©»Çí ;œÕÏ_MwλfÊøòt‡ ¾ ,@©MOSŠuqgàôGtO£7m»ÝÞÅ Î=£’WWí¥ÌäÝ Gøøùe½Æƒ_=;¢¥é8&mjG˜6à±·ð-E&S±a×1vì«—ÕB­‚¿›ð_ÍEY‘™¥fÂÑ8w5rèh¾@˜`0ˆY–§ºór '$ß俽¸%³÷ À]¿X6æÍxª¬QƒI6£Šb³Š"HtBp¬V m¢Ÿ»ø OæäÍëŽÇíÎê¿ÿ/Ý9¯½WË¢9©3® }{ ÀžFèíþ›v5²pv߇rضçk·§wJ¥zÐ7·’7ÜíŒ1úøùS5üôkdôšåÅ&¾ÿ…%@Ò“]Û襾Éצ£3̘òS`~õìG47Ç\àÍ~éZrÿìJåÎ ùžðÉ Jy›¶Cž…îq»<ˆlµEb >Ø’zŠ*K^(S÷3§¥/ÛäÞÚÈò ÖË`”=¶–]‡ÅoAèûô\2§’h\M$&U€Ÿü)§ÉQiyö<üÔZ캜”+/H4F Á°èC­ø0Oæyœºwã)à’t]ÿÜʲ%“Ðöò®ˆèÇÛ‚¬ßž~}Ÿ-Šl¦Š$ZŒ]DE‘1¥çàÏmÂn5pö™ÉÎáÍ>þߟױ£®]–mBBèáǰšuœ9¥œ¶¶fFÚUÔzšÙ¸ç8g‰<Œ²‰ ÀOþü5›R$Ѽa(¡R©Ø|@2¢ï¯ù’éÎ@ý%À¤\äm?ØÆ{ëXº°g¹"±5úŽºvîÿCîG¬‹ææ»_87íq•JŵLà‰WSÀøÞãë¸àŒQÜrÕlªÆ÷¼ ÔÖwðÒÊ=¼^s¤Ïþ±Õ¨¥Ìn îxßixBP÷z|\·t2¿ü[#í*lÚßýí»üú›Ë˜^•º˜C¶ˆDãÜõË•ÔmÈk'ÖBÀb³Ó¼W´bø}žÌ9IÞ…îq»ügõ¿€ÛÓó«¿oâüùã{4Ï$ 2WÈY"\uÁžg?"‘'«·6²zk#£–ÉcìŒ(6Qßìç`C'ÁHzaüïm ùï{S =!ôÉ ¿Æ9‰?YC8-صî~ø~÷í˘äHŸ:z:lÛßÌ{D¨=ïX =G%ó þæq»ä—Vʵûø+±ƒ›öµòÁæÃ=~&6¢ç 9N?«YÏW®MYg£þPŒ-Zy{ÃQvÔµ‹ŠüæK§°xΘôµÝSÄÛ \¼p,MÞä1µ ì?_h9‡3ïh+ÆñÖwþìmîd9ÚhFíð¹ÝfãP£dȫ轟+Dè·k;ðo±s~ýü–Â,B¸ì¼ÉÜrÙÔ¬½îÒ¹£¹éªdOótŸƒÆ¶O^4…c§¼òjXU>îøÉëüð±µiãçåŠÄøé_køŸ¾JãQv]8g-‡ £í’÷Ç=n—h¿ƒ\1»šŸHwðÃMÔl=Â’¹ã€Á3u‡dÑ„[>>FÅ_ߨ#;:_¼jŸ¾læIkdT™éÎE Çb6é E°»®¡»:À–m{¹ñþz.?w2_þÄ™èdædB1Þ®©å÷~Ž·t¢Žû± Ãizw,fk·Jn© Èh(tÛµÙá¬~øxºs~óÏ-œ}æXT*UAŒè™lã©T*nºrçœéÀõÜF¶Õ¦aMňb#wß8Esz–ÃN;¢§yšh5j®qNâ ÷ΓB?QF|,woeùûû±YŒT”XX8k4ógŒÄlÔÑê ÑÒ¢±ÙG}³íû›hi÷A$€Õ $KD`øi¾9îÓH=Ð7#Q,5— ¨zÎê…Hì'¾øÓËX4g,þ0¯º÷åɲÔT”˜Y¶D^‚Hwâ ޳zÃÞZïÁJ'¾xzW;'±`VeŸ-F€5s¤±oÛ'.žŽÑú¹½í@3Wßý2‹&j$§Õñ¢¨ ¨T*„DœD<ŽZ•@§QaÐæ.Ûk°b·Ûxcc»”Ðoö¸]Ïäɤ> øWæpV¿\žîøóFñ̯­à2˜ˆDãÔï¤Í¢µ#H8§¼ÄDE±™²b3v™-„2å’;_Dé Ü:4>ÇÂAůžºc¢N¸£ÀÛ•Ý"~pšÕ°N{ÕâƒÀçÓ¯kô1gb“Æævï7_h4jŠíFFWX™è(aÊøRÆŒ°Sb7aÈa¦F8g冣Œ°)BÏ&V{ö¥®Ðï{Ü®¼%°¤bÀWW]€hšo?ºŽ6oÎÚR >{ùtPëñ‡‡·Ó,›è´ZÖí‘ܦÜü!æˆ2à#:€½jq-"4P *Áyså'R(ôD¯Õ‰%X½©reTÏ jƒÝG$“…n¨-µî øˆàq»Vo‹óè‹;ؾ¯1O M>õl"‚Ž,¼ö˜ÍFÖîÜIY¼žs$)¡wq'É8à”üï>­B£ ŽÕ¬ãöÏâHëÀÓì4ûµDÅÛu'€{ò¼’Ž‚ºÇíÚüDìœM{[xyå€Ï‚5_¼v6Á¸–,¦–Øìv6î— Žù£ÇíÚ‘{äP0Bïâ!’΋´|÷±il’ôr*¤¡Èjà¶+gr¤MÕûƒÑh`ÍNI\ðy0G6%tÛ¾,vN0ç'ù°`ªÊ F¾xÝmÊâ b¨¨÷jð% cþØãv‰×/Ï3áu®¦Î^µ¸ ˜›îœÝuíŒ-70kr~Š( 5L-í¾0î8F™@#“­˜šÝ’…@ö·yëj Ê™TP#z7îZÄNøö£*^øÓà+Ÿ8ƒ`B'Ú°AáV«™U[D J@²¢×?1Z GŽK¶>ÞH9àºS#:€·®{ÕâHFÌ¥m¶³»®ÊRs¦(ëõþ0Æþøònʬd·“Æf·±r«äº<\æq»äw„Ì3+to]MKWÒË'ÅÎ[¹á(/¨ddYfM Ôn$ž€Uë•ÐØ^X­Vm÷õém—‚»_(a®bôÔýÞºš¸½jñ[À-€9ÝyõÍj¶qÉ¢ñ贃⭠•å޵‡Ø°§‰RËð«T*ZBFö•ÕÂêÓ·ks®mʃF Þº¯½jñ&àfD*ãì÷xinëdé‚q=êÂ+H³hÖ(žzc:UƒvxŠ=®•ÇðÇíðØÑÄ‘FoŸþmƒ •JEDceÝ.É$•üxÀ[W“C«òÃàýÖRàpV_M²³älÁŒ ÿÎÅT”*‰0rð£\sï+èâ” Âm7ƒ^Ç1¿Žíµ²ó!îó¸]¿Ì¥MùdHŒè'ðÖÕì±W-ÞG²³èÝXßàe÷Ϩ`T¹-?bô: ÎË“¯íâK DwŽÍfaS]ŒZñþh'€;†D$t+>:Ì9³GPZ,º-?ìqŒ°qöœ1<ýÖA,ú…–(h6›Øß¤bgìõx¸ÚãvDû¤\P`_QvñÖÕ´Ú«?œHvhléñ÷·÷2yŒ…)ãʆԾq¶UfÁ9O¿}ƒ:†NS–ÝngõN?Í^Ù…X½À·kUî¬x†´ÐádEÙ¿“L‚™%u~"!ðÚÚ:öÖ53oj9v«hΰ¦¼ØÄÅ‹ÆóÌ;uhˆh¨¬A¯#„÷öv¢1ÙIe;eƒ9âM.C^èÞºš˜½jñ‹$×ëçÊù}G:øûò½Œ+70yl™M—†›‘Ë—TñüÊÃ$ba ºüN{ì r¨Q–WýÏ×xÜ®ú™UP »»×á¬þ Ét²½n—-÷o]È”ñå¹3lÓÜäsßu¤=oé­‹‰ºØ}ėɯE{€GC ¨l1ì„àpV/žE"§½;ZµšïÞ6Ï}l¶Ò0" íanþ¿7 w¶ä4\V£Ñ 6XY³£˜üi:€ø”Çí­?8S÷ÞxëjêíU‹ÿ”‘,b!IBpojàµ5™0Ú¸ÑÅʾ{/Œ-W_0‰U››©oêÄšƒpY›ÝÆö£q¶×vÊÝ6;Á;À¥·koÖ K¡xëj¢Þºš×ìU‹7— ‘êz‚v_„—܇X»ùãGšqŒ*Ê­¡ƒ ½NÃuK'ÓQ±jS#E&Ȇ{Ãj5ÓÖóÞNÙÁ/ÝydO´ŒæøC eHÎêQÀ_€Ë3ýÝ+—ŒåK×Íæ¬™c²oØ gýÎc|ó‘•iƒX ý»Õl6 õí*¶ê“7Þ›ÃÀ— ½¹B>¶#zw¼u5¾®-¸’…'e;êöy¼üãýÔmeÜ(+#J-9³s°1¦ÂÊuK§òÞŽ6g˜ùf³Yi èx·—ƶp¦/&é¶+Ó_Š(#z/ÎêY$G÷…ýùý+–Œã¶+§³hŽ’óÞ'^ÞÎ/¬g|¢a³6›•º–D&Qm½©!9Šoéï†"ŠÐSàpV«›€Ÿ•ý¹Æ¤16î¼~6KN ¢D ©غ¯™o<¼‹ÊßÃQ§V«±X-:Ët«¬;ÀýÀã·Ké7Ó Eè"8œÕVà[À}H”ªJ‡É¨åËWOcÙÙ8cꨬÚ7ñ¢Ü÷ÛÕìØ]Çt‡_TÖC>¼þÓªžüÓo·ëIDATY3F3­ªìô+`Ž6ùX¾®ŽÕ›Ž°jC=±ÓïäXKrYõ”ÇíÊØS7Q„ž!]ë÷Ïߦdãšó¦”ò‰¥9kÆhfNªN¼ž–¯«Å½ÑCÍÎÆL#ØÒ±ø ðì`ë”2Ð(Bï'gµø8p/É4ج`1j¹d¡ƒ3*˜:¾ŒéÊ)µv]$gëþf¶íobÇfÖniÄÓ”ÕØ”Ý$ƒ^þáq»2Ž–QP„žÎêE$ÿI²Üs^­†ùÓ*¸`îh¦/eÜèb*+¬” øc±ž&;¶°ã@3»5S³óøé:ÓÒ±xxÑãvÅsñÃEèYÄᬞÜ|ÈiäL©ÝÈ™SJ™<¦G…•åF–ZYfÁbÔa2ê03+‹•‚á^_„£M>š|kñÓÐâãÈ1ûŽ´s¨¾“x"çI_ï¿þ£l•eEè9Àá¬.¾|˜4PvhÔ*ìV=%vÅ=v‹›Y‡ @8ňáõGh÷Eh댎Æúfš-j¿ó¸]ÌŠ!Š"ôâpV«€³€O7ãÖ¢‚£“d¯ñ§€÷”Ñ;w(BÏ]¢_DRðŸ†kL‚dÊèSÀË·+£²0 ýCúеEwIÑ_ŒX‹rN°X¼îq»Ž°=ÃEèL×H?™äÝù]ge~ñn’Â^ lNe› EèHW~üyœÿ\²¼m—eZMœöe¿»°P„>p8«m$Å>©ÛŸÉ]K6§È àÉà• LuErl-Logo-14 *ZÚIiCCPsRGB IEC61966-2.1(‘u‘ß+ƒQÇ?"Æ.”¥áfSâFÙÒ¨¥5S†›íµj›·÷$·ÊíŠ7~]ðp«\+E¤äz×Ä ëõ¼Ûj’=§óœÏùžçy:ç9` §•Œ^?™lN ù½Ž…È¢£±€…Ú 'ªèêd0 ¦}>J´Ø½Û¬U;î_kY‰ë Xš„'UË O 6rªÉ{ÂJ*º"|!ìÒ䂦+sÁäd™¿MÖÂ!XÛ…É_ûÅJJËËËqfÒëJå>æKlñìüœ¬½2»Ñ áÇ‹ƒ¦ð1Ê0ãâGqãaPvÔÈ*åϲ&¹Šx•M4VI’"‡KÔu©—5!z\FšM³ÿûª'F<åê6/4¼Æ{4îB1o_'†Q<…º¸ÎVó׎aìCô|Us}.oªZl®v ëYjÑ’T'ÓšHÀÛ9´F ãš—Ê=«œsöá-ùª[88„~‰·/ÿagą̃Uß pHYs  šœ IDATxœìÜmåaÆñkÆŽ“Ì’ "' 6‰jTÚ‰ äMã7%Ÿc>Ì|ޤo°*•@Õ‘RHC „PRÜ&fl#D 6„]ööÅœíÙc¯×Oë½ÏÃï'ÝšÁǼ<ç¯;`Q,•תª›¥$»“Ürѹu“?»ž¿³{ô¯ZKraô¼Ü¹‘Ï/þìB’O“¬&9·á¬^æý\ßµk7ô?¦ˆÀ€mSÕÍ®${“|1ɾ ç‹Wñ¾Ùg·gó(}=@gâ·Œà·øluÃóã$g“|t¹gßµŸïÔ‹Ià@ªº¹5ÉW“ÜqÑsýý˹ú ùµ’qð¾e ¥gßµçwz<ÓOà0'F·§ïÏd˜¾Y¬¾Ùçû Lf±}’!vÿ Éû£ó¿=/~?ÓwíZ‘µì;Àªêf)íé÷ŒÎÝ£çl¯ß1:»Jì…r>WŽàEñ3Là°ƒªº¹=—Fë—;·š óärQüé$§.:ïõ]{¾ÐN"p¸aUÝìNrW®¬ß“äK…fWv!É»Ù<~ßxÞï»öB©‘óLà°…ªnö%9”äþ$Œž÷'¹7ãhý@|ß ‹äó !üVü©$ô]»Vj$À,òƒ °°ªºÙ•áæõáúúYÿ³;‹ fݧ™¼ þd’?$y;É;£ó¡`LàÌ­ªnnÏ¥áúÆxýP’[‹ HÎf»¿“Éøý¾k?,3   ;0“ªºYJòµ\zûúÆþZ±ÛãL.¿gàÏ”™psÜ€©5ŠØïJò`’‡6<×ß÷—[0>ÌÖüÙ2³®À(jÃMì›ìEÄp#þ”ä÷IN$ykô<‘äDßµ•°;pÓmˆØ7 ØLò¥rëÖé\¾¿•äí¾k?+9 X\w`[l±_³‹ØfÃù ·¾_¾ŸHrºïÚµ‚Û€9'p®IU7»’<äá çÛBv;À|û8ãè}âö÷¾kÏ–Ì;°©Ñ쇒<’ɘý[IöœÀtz7“áû›I~“¤wë;pµî°àF!û}™ŒØ×oeß_póáL’72Äîÿÿì»öƒ¢«€©$p€1 ÙïÉ¥!ûÃI¾\p‹éT&£÷ß$ùmßµ+EWE Ü`UusWÆñú#Þï(¹ ®àB’ÿÎ¥áûïú®=_r°3î0êºÙä[IK²œä»‚ö%wÀ6[Mòf&£÷7’œê»v­ä0`{ Ü`FTu³'C¼¾<:%ùN’=%w@AÊdôþz’_÷]û碫€ë&p€)TÕÍþ ·±¯‡ìËI¾dwÉ]0.$ùÏ$Ç7œ×ú®ý¸è*àªÜ °ªnî̱¯‡ìËIŠïï`»¬åÒèýUÑ;L?À©êf)ɽ™¼•ý±$”Ü j-É[¹4zÿ¨è*Xpw¸ F1û×3¾‘}=f¿»à,`kkINäÒèýlÑU°@î° ªºùj’¿Lr$ÉãI~ä+EGÛe³èýLÙI0ŸîpªºÙä‘ 1ûzÐþÍ¢£€ö_ï¿Lr¼ïÚ•²“`ö Üà ªº¹;ã˜ýH†ÛÙ÷L›Ï’¼–äÅ$/%y±ïÚ?–³GàTusk’ïf¸•}=hÿFÑQÀ¬:™Qì>z¾Úwí¹²“`º ÜXhUÝT‡ì'ù^’ÛŠŽæÕ¹$Ç3Äîë·¼Ÿ.; ¦‹À€…QÕÍž û‘ §*: XtÈä-ï¿î»ö³²“ ;s«ª›CIžÈp3û‘$&¹¥è(€­­$y9ã[Þ_ê»ö½²“`çܘ UÝ,%ùz’zÃùFÉMÛäw™¼åý¾k?/; n;3i´?˜É ýPÑQ;ãã ±û¿ŒÎ¿÷]ûYÉA°]îÌ„QÐ~8ã˜ýo’,: `:|’ä_3¼Zr\/;S©ª›]IÎdÐ~WÑQ³a%“ÁûË‚wf…À€©PÕÍ’|'ã ý¯“ÜYtÀ|XIòb&ƒ÷s%ÀåÜ(¢ª›ÝIË8h"ÉWŠŽX «™ Þ%x`ZÜØUÝÜ’äûí•dÑQ$CðþRÆÁû¿ Þ(EàÀMQÕÍR’ÃI~4:u’}EGp5V“ü2“ÁûjÉA,;Û¦ª›IžJòt†¨½*»€mp.Cðþ|’ç’ï»ö|ÙIÌ+;×­ª›Û’<žñ-íËñÀ¼û ãØý¹¾kÿXxsÄ\µªn–’Î8hÿa’½%7PÜo3ŠÝ“t}×þ¹ðf˜À€-Uus ÉSIžÎµWe0Å>Mò‹ ±û?%y½ïÚ e'0KîL¨êæ¶$g|Kûr|Àõy/ÉÏ3Äî?ï»öÝÂ{˜r~˜XpUÝ,%9œqÐþÃ${Kn`n½žñíî¿è»vµð¦ŒÀ`Uus ÉSIžÎµWe°€V“tb÷ç’¼ÙwíZÙI”&pX£[Ú—“üxt¾ß 0]NfÝŸKò|ßµïÞ@~ĘSUÝìMò·IŽfˆÚ–]Wm-Éñ$ÿ˜äÙ$¯ô]{¡ì$v‚À`ŽTus0CÌ~4É“In/»¶Åé$Ç2Äî/ô]ûIá=Ü$w€VÕÍR’å AûÑÑ;̳Õ$ÏgÞõ]{²ð¶‘À`ÆTu³7ÃíìG“ü]’ƒe@Q¯d¸ÙýÙ$¯ô]»Vx7@à0ªº¹/É3DíO&ÙSvL¥Snv6É }×®ÞÀ5¸L¡ªnv%YÎ8j_.»fÎJ’2ÄîÇú®=UxWAà0%ªºÙ›ávö£Âö{Ë.€¹rP¸`D0px‚JµÖ•ä¼´Fí¯H2³l0 <œäŠ´ï×5õ¾Â=Ö;0浿 ­QûË“ô”-F±G“|.­±û7›úÂ=Ê;0&Uªµö$g'y]’_M2£l0mMkèþÉ$×6õÂ=ŸcJ¥Z;.­Qûk“,.œð¸ Iþ%ÉeInn6ꃅ{Š0pF½Jµ¶(ÉEi ÛO(œð‹Ü•ÖU÷i6ê÷–ŽJîÀ¨T©Ö¦'ù•´FíçÄë ÀÈôÝ´®º_ÞlÔ7•Ž8Ü<ØFJµ6!ÉKÒµ¿8IWÙ"€C¦?É×Ó»¾Ù¨ï(ÜpX¸#Z¥ZëHrnZ£öW%™V4àðÛ—ä‹iÝ¿ÚlÔ{ ÷2îÀˆS©ÖÚ’œœÖ¨ý¢$ó˳5ÉgÒ»_ÛlÔ ÷<#îÀˆQ©Ö–&ymZÃöU…s†› Iþ%É'“ÜÒlÔ ÷ßlÔ÷îF8wàI«Tk=I.Jò¦$§Î`xÙ–ä²´Æîßo6ꃅ{€ÈÀø¹*ÕZ{’sÓµ¿*É„¢AŒ·'ùh’n6ê–ŽFw৪Tkó’¼%­aû‘…s™z“|&ɇ’|ËUwà1p~¤R­µ%9'Éo§u­}\Ù"F‘Û“\’ÖU÷í¥c€áÉÀH¥Z›–äד¼5É1…sÝö$¹,ɇšúJÇË;Œa•jí„´®µÿz’É…s{nJëªû¿6õ=¥c€ò Ü`Œ©Tk㓼*­kíg΀a£­-éhoKG{{Æu$íííI’ÁÁÁ &­¿Zoƒß2˜Áƒø©ÿ9ÿ®üù@’d{’K“|¸Ù¨¯.”càcD¥Z;"ÉJò–$³ËÖ@käÝ9®=“'tdêÄÎLÜ™îÉ]™:±3S&ufℎL?.“&ŒË„®ŽLè—ñézü­«#éìlO׸ŽtŽëHçÁÏuvvd|gGÆëhý»ÿ{믴\˜·~hûÑàü‰okkûÑÏ}âçÛÚ’¶ƒ¿æ‰¿þ'?þ³Íã“ýúÒ{` û{ûôþ¾ÞþôèÏþƒ?î{ÂûÿØÛן}­÷üøý}­ÏèOïã{Âûû{[Ÿß×Û—=ûú²göîëKÿ€¥=ÃJ#­«îW4õÞÒ1ÀÐ2p€Q¬R­µ'yaZ×Ú/Œ×x:ÚÛ2³»+ fMɼ3«gB¦OŸi“»2q|G&Žo ÐÇwËø®ŽtkÿÑ}\GûÁú¸tŽkOWgëçŒï—ñ]ã~bøÍÐêü‰ñüþýÙ±»÷Ço»ögûÁ÷·ïÚŸ»z³}wovîÙŸ»dûîýÙ±»7»÷ÈÀÀÏ¿\OÑ#I>šä#ÍFýþÒ1ÀÐðÈF¡Jµ6+É“\œdiᆑ¶¶dbWGfLŸ³&föô‰™Õ=!Ó§Ïô)ã3urW¦NêÊ”‰™4±+“'vfòÄ®ÖÛ¤ñéêì(ýŸÀ0508˜»áwïÏö]­qüãCùíåwõfÇÁQüö]½Ùyp,¿g_JÿW0L &¹*­«îW6õþÂ=Àadà£D¥ZkKrF’ßNòš$ãËp¸µ·µeVÏø,š=¹5Vži­‹êÝ“©wfʤ®Lšð„±ú¤ñß5®t>ü„¾¾ƒ—âŽâ^ŠßþøH~×þlÛµ?›¶ìÍ£[÷ä‘-{òè¶½9Ðg0ƬOò÷Iþ±Ù¨?T:8ô Ü`„«Tk““\”ä­IN.œÀ3ÔÞžÌ>1+õdɼ)Y8{ræÍœœÝ2mòÁ‘ú„®LžÔºªn¨ÎX·eǾ<ºuoÙ²'›ßÙ²7lÝÓzñÎ IDATÛÒúÜî}J§phõ'ù|ZWÝÿ­Ù¨ûŠ'% Ü`„ªTkG¥u­ý7’t—­àéêlÏìî®1ZÏ’ù³&eÎô‰™Ù=1Ó§MHÏÔ ™>mbz¦MJWgGé\uvï;ðã!ü–ßÝúø?·>·uç¾ –®à)Z“äÃI>ÞlÔ+<3î0‚TªµqI^–Öµöó çpЄ®Ž1wJ–V¦dÑœ)™7cbfõLLÏÔ éžúãñz÷Ô‰ikó², g}}ytÛÁ ð[ödÓÁkð­!|kÿÈÖ=ytÛÞôõ9 0ÌìOrY’¿n6ê·”ŽžOR`¨Tks’\œä·’,(œ0¦ŒkoÏ‘ §fÕâî]^ŸÕ313¦µÆëÓ§NLO÷ÄLßY:b[vì;8xß›æ#;³nãßÖoÚé<@YÿžäI¾ÜlÔû ·O; c•jíØ$¿›äõIÆÎ•º§tåÄå3sô’ž±`ZæÎ˜”™Ý­«ë=¯®w´{)xêví=õ›~rô¾n㎬۴3ÍM»²w_éD€±à¾$“ä£ÍF}GéàóT†™JµÖ–äIþÛÁx:;Úrä‚©9~iO–.èÎÂ9S2oæäÌž19³§OÎôîI¥1êÑ­{óàÆY¿igÖoÜ™4‚ß™íNÿ€óï‡ÐÎ$Kò7ÍF}méàg3p€a¢R­MLòº´.¶S8`Déìh˲…Ssü²éY¶ ; æLÉÜ“2{úäÌž9%=S'–NxJúúÒ|tWÖoÜ™u›~|þÁ;²~ãÎlÛµ?ƒöïOÇ`’/%ùë$ßl6êþo ÃŒ;V©Öæ&yëÁ·Y…s†­Î欬t縥ӳlÁ´,œ3%sfLΜ“2{Æ”L<¡t"ÀÙµç@ÖmzüâûŽ¬ÛØÁ¯Û´3ÍM»²¯·¯t"ÀHp[ZC÷ËšúÞÒ1@‹;R©ÖŽOëZûë’tÎ:;Û²jqOŽ;rz–.œ–Êì)™;srfϘœ93¦dÒDÿ»x2Ù²'ë6íÌý¶çîu[³fݶܳ~[zdWœ~ø6'ùp’6õ‡JÇÀXgàC¨R­µ'¹ ­aûó çÑÞž,¯ô䔣ffy¥;•9“3wÆäÌž>9sfNÉ„ñ¥F­½ûû²vý¶Ü³n[֬ߚ{ÖmË=붦¹igú ß1¯/ɧ’üu³Q¿©t ŒUî0*ÕÚ¤$¿žämIVÎ2GÌ›’3Ÿ“㎜™#LKeî´,˜3͈`˜ÙßÛŸµÍm/½·.¾¯Y¿5>¼3}ý¥óJøv’$ù\³Qï+c‰;F•jm~’ßIrq’™…s›Ù=ræ±srü²Yº°;•¹S³pNwz¦M,À3p o ÷6·eÍúÖ¥÷Çð<´#ú ß1a}’¿MòÍF}Ké Üà0¨Tk'%ùÝ$%q¦5¦MêÌ©«få„å3³¬2-‹^dŸ;sjÚÛ½Ü0Vôõäþ‡vdͺ­Y³~[î~°õã}¶§÷@é<€ÃaO’O$©7õ;KÇÀhæ‰"•j­=É‹“ü·$Ï+œðŒLžÐ‘cìÉI+ffy¥ûGCö…s»3¾k\é<†©ÁÁ<ðÐŽŸ¸ø¾fýÖ¬]¿=ûzûJç*_Kò$W7ußÎ1wx†*ÕÚä$oHò¶$+ ç<%mmÉâ9“ræ±ssô=Y°%·­Ýœû7ìÈÀà`é<€§ëÎ$ïKòÉf£Þ[:F wxš*ÕÚÂ$¿“äâ$Ó çüBí9í˜Y9uÕì¬\Ô“Eó¦eÁì©™;kjÚÚ¼TÀÐÛ½ï@î¸÷±Üºvsn[»9·®Ýœû7lOÿ€Ñ;0¢lHòþ$i6ê;KÇÀHç©kQNY57«Žœ™#ÎHG»—Ù`,Ú³¯/?¸û‘ÜtÇÆÜ´zS~p×#Ù½ï@é,`ôøR’÷6õo•€¡äÉ£Z¥Z;-É&ùåÒ-ÀÈ´dîä¼è¬E9eÕœ¬\Ò´·´?EÿÀ`VßÿXnºcSnZݽoÚ²§t0ò}+É{’\ÙlÔKÇÀáæI£N¥ZkKò¼$”äüÂ9À³láÔ\pF%'5;+—ÌÌ’íÀÓ·nãÎÜ´º5x¿qõÆÜ»~{íS§å‡Iþ"É ÝÍ<™`Ô¨TkíI^–ÖÅöÓ ç#@[[²¢2-/<£’“V>>hŸž¶6/›‡Ç¶ûsÓ›ò½ƒ£÷[ÖlNïþÒYÀÈrK’w%ù\³Q(‡š'uŒx•jm\’_KkØ~Lá`kkKŽ^ÒœVɉ+geÅ’YY<zìÙ€Rzôç–5æÆ;6å{w¶Þ¶íÜ_: nOkèþCwFî±Û_—äO’,+œ CmmÉqK{òK§.Ì +ZÚ+ó Ú€áížu[sã­ ï7Þ±1ÍGv•N†·Õi Ý?ÝlÔ}KF<òq*ÕZG’‹’üi’…s€a¤½­-'.ïÉù§Vrüò™Y¹dV*ózJg<#÷?´=×ßüP®ýá†|ûÖ‡²cwoé$`xº+É»“|ªÙ¨÷•Ž€§ËÀ€ãà°ýÕIþ,ÉQ…s€a ­-9aùô¼ð´JŽ_>++–Ì̹íÀè508˜›ï~4×ß¼!×Þ¼!?¸ë‘è( /kÒº_fèÀHdàÀ°W©ÖÚ“üjZÃö£ ç…­¨LËKŸ³$Ï:jvV,™™sºK'³g__¾sÛíÁû7dÍú­,] ÷&ùË$ÿÜlÔ”Ž€'ËÀ€aëà°ý•i Û+œ2cÚ„¼úü¥9û„ùYuä¬Ì›5µtÀ°µiËž\wó†\ó†\wóCydËžÒI@y÷'ùŸI>ÑlÔ{KÇÀ/bàÀ°S©ÖÚ’¼"ÉŸ'9¡l 0ÔÚÛ“sŸµ žµ$'¯š›¥‹f¦£ÝËXOÇÝn͵?ÜënÞn8{öõ•NÊY—ä%ùX³Qß_:~O6Û_šä$9©p0„Í™œW{dÎ7=Ó&–Nuúúò½»6µï?ÜÛÖnNÿÀ`é,`è5“¼'É?6õ}¥cà?2p ¸ƒÃö§5l?¥p0º:Ûó¢3+yÞ³æ„s²lñ¬´»Ò0¤¶ïÚŸoÝòP®»yC®»ù¡<øðŽÒIÀÐz(­¡û?4õ½¥càqžPÌÁaûIþ<Ééek€Ã©­-9úˆî¼ä¬Å9åè¹9f™+íÃÍúM;tÝý[·>”m;÷—N†ÆÆ$ïMò‘f£¾§t ¸0äÛ)­‹ígΓS;ó‚Óæìæç˜es²Ü•v€cp0¹uí£¹ö‡rýÍò½;IïþÒYÀáµ)Éû’\ÒlÔw—Ž`ìòD€!spØ~^ZÃö³ ç‡X[[r²éyÑ™•œ|Ôœ³|^z¦ºÒ0ìÝß—nߘk¸!×þ°™{ÖmÍà`é*à0y4É_&ùp³QßW:€±ÇÀ€!Q©ÖÎMkØ~NáàšÐÕ‘ Ÿ]Iõä9nÙœ,s¥`LhnÚ™«oX—knx0ß½ccúúJ'‡Þú$žäÍF½¯p cˆ§V•jí¹i ÛŸWº84Žœ?%¯:÷ÈœvÌÜ»|nº]iÓvîîÍ7¿¿>Wß°.ßüÞúìØÝ[: 8´îIò'I>ÓlÔ}5 ‡;‡E¥Z;;­aûù¥[€g¦£½-/8}a^xæâœ¸rN–VfºÒÀOÕ×?nߘknX—kn|0ë6î,:?LòÎ$W5õÁÒ1Œ^žDpHUªµg%ùŸI^XºxúæLŸ˜_{þÒœ}â‚·|n¦M™P: €èî·æš×åšÌÍw?šA›X®OòGÍFýºÒ!ŒNî•jmY’w'ùµÒ-ÀÓó¬£få¢ç¯È©ÇÎ˲E3ÒÖæ¥#ÍÛöæë7®ËÕ7¬Ëõ7oÈÞý}¥“€gæ«IÞÙlÔX:€ÑÅSJž‘Jµ67É'¹8ɸÂ9ÀSÐÞž<ÿ”J^úÜ%9íØY8·»tcÄþÞþ\{ó†\sÃùúëòèÖ½¥“€§ïÓIþ´Ù¨ßU:€ÑÁÀ€§¥R­MMò{IÞždráàIšÐÕ‘—?gqžú¢œ¼j~æÎšZ: òûÉ57¬ËÕ7<˜{ÖmÍà`é"à)Hòñ$ÑlÔ,ÜÀgàÀSR©Öº’üV’?I2»pð$ôLéÊ/Ÿ³$Õ“䤣df¯I`øZ¿ig®¾áÁ\súÜpÇÆôõ ”Nž¼Þ$—$ùŸÍF}SéF&wž”JµÖžä5IÞdiáà˜Õ=>¿ò¼#òÜæ„UóÓ3ubé$xÊvîîÍ¿}o}®¾a]þýûë³cwoé$àÉÙäIþªÙ¨o+ÀÈbàÀÏU©ÖÚ’üR’÷$9¹pðsÌ11¯9ÿÈœ}‚œpÔüL™4¾t2}ýùîísÍÁëîë7í,übÛ’¼7Éß4õÝ¥c Üø™*ÕÚ©i ÛÏ/Ýüt‹fOÊkž¿4g° ǯœŸ‰ã;K'À¸ë-¹æ†u¹ú†sëšÍ,ülÓú®€ßlÔ}+~.wþ•jmEZ_]ºø-[85¯9oiÎ<~AŽ]1/]¥“ ¨M[öäË×ß—/]{_~p÷#±u‡aë$žäŸ›zÙ†+w~¤R­ÍKò§I~3ɸÂ9À}Dw^sþ²œqìü½ln::ÚK'À°Ô|dW¾|Ý}ùâu÷åö{7»Ãðtg’?Nò¹f£îw)?ÁÀ€TªµiIÞžä÷’L*œtÒŠùÕç-ÍéÇÍÏÊ#椽ÝK9ðT<ððŽ|éÚÖØýî·»ÃðsC’ßk6êß*Àðá©(ÀV©ÖÆ'¹8­‹Y³ çIÎ8vV~åÜe9íØùYºhVÚ¼z‡ÄšuÛòÅëîÍ—®»/÷6·—Î~Òg“¼£Ù¨¯-@y‘ŒA•j­=Ék“¼+Éek`lkkKª'ÍË+Î92§3?KÎ(£Þ÷=–/]w_¾xí}Y¿igé å@’&yW³Q¬t 希!•j­-É “¼'ɉ…s`L«ž4?¯>iN=fAÌí.cÖ-kÍ÷åË×ß—‡7ï.$Û“¼;Éß4õý¥czîcD¥Z;=É{“œ[8ƬU‹»óÆ—¬ÊsO^”Eó{JçÿÁM«7å‹×Þ›+¿uݺ·tŒu$yG’Ë›ú`á†;À(W©Ö–¥u±ýWJ·ÀX4»gBÞô’£rÞi‹sôÒ9ikór wƒƒùîmóÅkïÍW¿ý@¶ìØW: Ʋ’¼½Ù¨__:€¡á‰*À(U©Öº“¼3ÉÛ’tÎ1eBWG^÷‚e¹à¬#ròÑ 2¾k\é$àiêÌõ7oÈ®½/_ûÎÙ±»·tŒUW$yG³Q_S:€ÃËÀ`”©TkIÞœäÝIfÎ1£½­-žUÉ+Î]šÓ«¤gÚÄÒIÀ!v o ÿþƒf¾xí½ùú ë²kïÒI0Öô%ù»$ïj6ꕎàð0pE*ÕÚyIÞŸä„Ò-0Vœ~ô¬\ôKËsæ •Tæõ”ΆÈþÞþ|ã¦uùâµ÷åß¾·>{÷÷•N‚±d{ZÇþ¶Ù¨ï+À¡eà0 TªµåIÞ—ä¥[`,8rþÔ¼á‚å9û¤JV-›6¯°À˜¶g__®¹áÁ|áÚûÒøA3½úK'ÁXñ@’?Lò©f£>X¸€CÄãW€¬R­u'ùã$ÿ5IgáÕ¦OëÊëiYÎ=uQNZµ0]¥“€ahçîÞ\õòÙo®Íwn}8ƒ6·0nLò{ÍFýúÒ!w€¦R­—äIŽ/Ý£QG{[Î=yn^þÜ#sÆ •,˜Ó]: ¾}ëùüëwç+ßz {÷÷•ÎѬ/É“¼«Ù¨o.ÀSgà0BTªµIÞ—äå¥[`4Z¹hZ^ÿÂåyö •µtNé`”Úµ÷@¾tí}¹üë÷äûwmÊà`é"µ¶'yw’¿m6êûJÇðä¸ s•j­'É'©%é,œ£Ê”‰ù/Ïù§-Ή«¤s\Gé$` ¹·¹=ŸþÆ=ùÌ7ÖdÓ–=¥s`´z É;’\ÞlÔ}I À`à0LUªµqIޜ֥©Y…s`ÔhoO^òì%yÕó–æ´ã*™:y|é$`ŒLãûÍ\þõ{rõ ëÒ{ ¿tŒF$µf£~ké~>w€a¨R­ŸäýIŽ/Ý£ÅqK§ç-/;:Ï9iQæÎšZ:à§Ú¾k>ÿï÷æS_¿'·ß»9ƒîMá4äCIþ´Ù¨o)ÀOgà0ŒTªµIþ*ÉËJ·Àh0mrg~ëÇäÅg™å‹}#`d¹ë-¹üë÷äŠo®ÍcÛ÷•ÎÑä±$ïLòÍFÝ·Lf ܆JµÖ“äO’ü—$…s`Ä;çÄyyóËŽÉY'-ÊÄñ~K#[_ÿ@¾qÓú|êš{òÍï¯O_ß@é$-nNò_šúõ¥Cø1w€‚*ÕÚ¸$oIò®$ÎKÃ30}jW.~Å1¹àÙGf颙¥s‹ÍÛöæŠo®Í§®¹'÷¬ÛZ:F‹O&ùƒf£¾¡tîÅTªµç'y’ãJ·ÀHÕÖ–<ÿÔyÝ Wæ¬gÒÄ®ÒICæ–5æS×Ü“/^{_¶ïÚ_:FºÝIÞäýÍFÝo(€‚ ܆X¥Z[–Ö°ý¥¥[`¤š7cbÞô’•yþéGdųKçÕ{ ?_ûîƒùÔ5÷äú›7¤`°tŒdk“¼­Ù¨_Y:`¬2p"•jmb’?HòŽ$ã çÀˆ3®£-/:ca^yyââL™ì·ÀôðæÝùÌ¿­É§¿¾&÷?´½tŒd_Iò»ÍFýžÒ!c;À¨Tk/Nò7I––n‘fÑìÉyË–åÜS—dÕÒ¹¥sFŒ›Vo̧®¹'W^ví=P:F¢IþO’¿l6ê;KÇŒî‡Q¥Z[’äI^QºF’ö¶¶¼àôùÕ󖿬“–dêä ¥“F¬=ûúòùÆÚ\úåÕY}ÿ–Ò90=œä¿'ùd³Q,0Ú¸•j­+Éï%ù“$ çÀˆ1sZWÞüÒ£rþiKrÌòy¥sF›VoÊ¥W®ÎW¾uô ”ΑæÛIþK³QÿAé€ÑÌÀà«TkÏOò·IŽ*Ý#A[[òÜçæu/\™³OZœî©¾&àpÛ¼moþåkw矿zgÚ¼»tŒ$ƒIþ>É;›úæÒ1£‘;À!R©Ö&ù?I^]ºF‚É;ó›/[™ Î:2Ç,›—6¯R ¹ÁÁ\ýÝó‰+ïÌõ·lÈà`é"1¶¥õÝ/i6ê}¥cFŽž¡JµÖ™¤–äÏ“L)[Ãß)«få-/]•眼$=Ó\k.îmnÏ'¾²:ŸþÆšìÜÝ[:FŠÛ’Ôšú¿—- ÜžJµvN’¿Kr\éÎÆwuäM®ÌKŸ»4Ç­˜ïZ;À0¶w_®øæÚ\úåÕ¹ó-¥s`¤¸<ÉÛ›úúÒ!#ÇÉOC¥Z››ä}I~½t gÇÑ“ß~屩ž²$Ó»'•Îà)ºiõÆ|üËwæ«ß¾?úJçÀp·;ÉŸ%ùëf£ÞW:`¤2px *ÕZG’ßNòî$Ý…s`X×Ñ–×_°"¿rÞŠœ°r^Úœkñ6oۛˮº+ÿ|Õ]yxóîÒ90ÜÝ’ä·šú ¥CF"O˜ž¤Jµvf’&9¹t G‹çNÉÛ^sBÎ;}IföL.ÀaÐ?0˜«¿û`>qåê|ëÖ‡28Xº†­Á$—$ù£f£¾­t ÀHbàð TªµYIþW’·”náèyÏš—·¼ìØœuÒâtŽë(ÀYÛÜ–O\yg>óok²swoé®6%ùÝ$ÿÚlÔ}IÀ“`àð3Tªµö$oNòž$3 çÀ°ÒÙٖ߸`E^yÞŠ·b~é Ú³¯/W|sm.½ruîz`Ké®®Nò;ÍF}mé€áÎÀ২Tk§$ù`’ÓK·Àp2³{Bþó+Îg/Ke^Oé†™ïØ˜K¯¼3_ýöý9Ð7P:†›ýIÞä}ÍF}é€áÊÀà *ÕÚô´2ývü™ ~äØ#zrñ+ÉóN[šî©Jç0Ì=ºuo.ûÚ]ùäUwåáÍ»KçÀpsW’‹›z£tÀpd¬¤R­µ%yC’÷%™]8†…¶¶ä…g,Ì^´*gž¸8ã:J'0Âô æêï>˜K¯\oßúPKÁ°ri’·7õÍ¥C†w`Ì«Tk+“|$Iµt ]ãÚòÆ WæåÕå9~åüÒ9Œk›Ûò‰+ïÌgþmMvîî-ÃÅ–$¿ŸäcÍFÝ—€ÄÀÃ*ÕZg’·'ù³$ã ç@q³z&äw^yt.xö²Tæõ”Î`”Úµ÷@.»ê®üãnÏC›w—Îáâº$7õÕ¥CJ3pƤJµvZ’HrBé(í¸X> IDAT¥=¹øÇäÜÓ–¦{ê„Ò9Œ}ýùBã¾|øŠ[sç[JçÀpp Éû’¼»Ù¨ï-PŠ;0¦TªµÉIþ"ÉÛ’´ÎbÚÚ’±0¯ѪœyââtŽë(Àví7ä’ÏÞšëoÙÁÁÒ5PÜ}I~§Ù¨_U: w`̨Tk/Hòá$GNbºÆµå®Ì+Î]žãVÌ/?áŽûË%WÜš/_úúJç@i—'y[³Q¸tÀP2pF½Jµ63ÉÿIò†Ò-PÊÜérñ/ ž½,•y=¥sàçÚðè®üÃçoÏ¿^}wví=P:JÚ‘ä’\ÒlÔûKÇ w`ÔªTkmI.Jò$³ ç@',žßúåcrîiGfÚ” ¥sà)Ù±»7ÿô•;óÑ/Ý‘G¶ì)%ݔ䷚úK‡nîÀ¨T©Ö'ùP’—n¡ÖÖ–¼øÌ…yý«rƉ‹Ó9®£t<#úrÅ7׿’+nÍÚõÛJç@)Iþ:ÉŸ6õ]¥cw`T©TkIÞšä%™\8†T縶¼é•yŹËsÜŠù¥sà°øúërÉ·æÆ;6fp°t ñ@’ßl6ê_/p8¸£F¥Z;.É?$9£t ¥©“:ó¶W— Ÿ», çö”΀!qó=æ’ÏÞš«¾ó@ú,Ý“þ1ÉÛ›ºokŒ*îÀˆW©ÖÆ'yg’w$é,œCfñÜÉyûkOÊùg™iS&”΀"ÖmÜ™|þ¶\~Í=Ù»¿¯t µ‡’\ÜlÔ¿T:àP1pF´JµvvZWÛW•n¡rÌ=ùƒ_VÎ9eIÆë(ÃÂÖûsé—Wçã_¾#mßW:†ÚeIþk³Qß\:à™2pF¤Jµ6-É{’üvé*'¯œ™ßÝÉyöI‹ÓÑÑ^:†¥ý½ý¹ü÷äï?w{îh{éJ&ùÏI>ÝlÔKÇ<]îÀˆS©Ö^–äƒI–n¡ðœç¦ö«'挥½ÝåàÉL®úιäŠ[óƒ»)CéóIÞÚlÔ.ðtx*Œ•jm^’z’_-ÝCá§Urñ«ŽË©ÇVÒæOðð´Ý´zc>ôÙÛò×e`ÐakÆ„mI~7É¥®¹#ÇãÀ°W©ÖÚ’¼1ÉÿŸ¤§pVmmÉËŸ³8o~ùq9iÕ‚Ò90ªÜÛÜž|î¶|ö›k²¿·¿t …¯%ùOÍF}]é€'ËÀÖ*ÕÚ²$Ir^é8œÚÚ’‹Î_š×¿øè¿r~éÕ6oÛ›~éŽüÓWî̶ûKçÀá¶+ÉOòáf£>P:à1p†¥JµÖ‘ä¿&ùË$ çÀa3®£-o¸`y~í«rô²¹¥s`LÙ³¯/ûÒùÈçnË–ûJçÀávm’77õµ¥C~w`Ø9xµýãIžS8›ñ]íyË…+óÊóÊÊ#f—΀1mϾ¾\zåê|øŠ[óØvCwFµ½Iþ$Éšz速ÆÀ6*ÕZ{’‹“¼/ɤÂ9pXL™Ð‘ß|ùQyŹGe颙¥s€'Ø»¿/—~yu>ü¹Û²yÛÞÒ9p8ÝÖ5÷;J‡üGîÀ°P©Ö'ùh’óK·Àá0cjWþÓËÊKÏY‘Å f”Î~޽ûûò‰+ïÌ%WÜjèÎhv É_$yo³Q?P:àqî@Q•j­-É“| ÉÔÂ9pÈMŸÚ™ÿüÊcrá9+³pnwéà)Ø×Û—úÊùÐgoÍ£[ ݵnIò¦f£þƒÒ!‰;PP¥Z[ä¸t j3¦OíWŽÉ…ç¬È¼YÓJçÏ@kè~W>ôÙ[ Ý­ú“üï$ÑlÔ÷•ŽÆ6w`ȼÚþÚ$“dzá8¤fvOÈï¾æØ\øÜ™5}JéàÚßÛŸújë¢û#[ö”ÎÃá®´®¹§t0v¸CªR­ÍIrI’_.݇ҬîñyûkOÈ‹Ÿ³"Ó»'•Σý½ýùç«îÌ?cèΨ4˜äýIÞéš;P‚;0d*ÕÚ«Ò·Ï*݇Êìž ùï¯?1/zΊtO™P:B½úóÉ«îÊ?sk6>¶»tj«“üz³QÿAé`l1p»Jµ6#Éß&¹¨t *ó¦OÌ;Þpr^xö²L™4¾tPPïþ\öµ»ówŸ¾ÅÐѦ/ÉÿHòžf£ÞW: ܀êR­½$Éß'™Wº…ù3'å¿ñ¬¼à¬e™8¡³t0ŒèÈeWÝ•¿ûÌ-yx³¡;£Êw“¼¡Ù¨¯)Œ~îÀaQ©Öº“¼?ÉK·À¡°pöäüñOÉóÏ\š ]ãJçÃØ¾üëÕwço/¿9º3zìIòûI>Ôlü_öî4Îî²°ûÿ÷œY’Ìš$'€R7D@@R¨mõ¤ußÚê±´ÞÚºU­ ÚÛÚk±z ‚Š nÞp”*dM€°/ÙCHÈ>™ù?HÛ¿µ Èäš3ó~?äõºàó`È+×ü¾çwšc¥c€©ËÀØêjõÆK’œ˜dQéx¢¶Ÿ=+{Û¾9ô ÝÒÛcØŒßÈÈhN;oY¾xÆ•¹ó¾‡KçÀÖrn’·¶[Í;K‡S“;°ÕÔê$ŸMòg¥[à‰êïɇßôœ¼ê…OMÿ¬ÞÒ9@Í7λ>_üæißkèΔð`’?o·šß(L=îÀVQ«7^ä¤$O.ÝOÄÌÝùÀQ{æ_üôÌê+L!##£9ýüëó/ß¼2í{V•έáôlº//LîÀR«7f%ùt’÷ƃÖÛ]IãµÏÊë^¶{vÜn°t0…lÍ7Ï¿!_8ãŠÜaèNç»+É[Ú­æJ‡Sƒñ ð¸Õê’œ’ä©¥[àñêî®äí¯xZ^ØîÙuáÜÒ9À42²i4ßúÉæ¡ûíwºÓñŽKò¿Û­æêÒ!@g3p¶X­Þ˜‘äcIÞŸ¤Z¶Ÿ®j%¯ñ“ó§/ß=ÏØm~é`Û4:–oüxY>êe¹gùšÒ9ðDܘäOÛ­æÅ¥C€Îeàl‘Z½±{’S“ìUºJ%yÅ ó¶Wí‘}žY+ð_ÖmÉ—ÏZ’ã¾}UV­ÞP:¯Ñ$Ç$ùD»Õôƒ l1w`\jõF%ÉŸ%ù\’™…sàq9xÏò¼GÚg×T*®ÄÀäôàªõi~ãò|õ×fÃÆM¥sàñº<›ßæ¾´tÐY<ÍS­ÞØ>ɉI^Yº=ž4'G¹g^¸ß“ÓÓÝU:`\Ú÷>œøÚ¥9ë›2:6V:õI>”äóíVs´t Р܀ߩVo¼4É)Iv,Ý[j—ùýyßQ{åe>%³fö”Îx\®¹eyŽ9ù—i]ÖŽ;ª•äMíVóÖÒ!Àägà<¢Z½1#É1IŽ.Ý[jÎ`o>pÔ^yå Ÿ–¡™¥s¶ŠŸ_uW>}Ò/så ÷•NÇcU’÷&9¹Ýjú¨ð¨ Ü€ÿ¡VoìžäÔ${•n-1³·+}äùãßz¶Ÿ;P:`Bœó³›ó_ûUnùõC¥Sàñ8;É;Ú­æ½¥C€ÉÉÀø/µz£’ä]Iþ1‰×^Ó1º»*y×áOÏë{fí8»tÀ„Ù4šSt]>Úå¹ÅÚÒ9°¥îKòÖv«yNé`ò1p’$µzcû$'&yeé¯J%9ê%»å-¯~Vž²Ëö¥s¶¹5ëFrüw®Î¿yU^»±tl©/$y»Õ\W:˜< Ü€Ôê—&9%ÉŽ¥[`¼þà€Eù‹×î‘=Ÿ¶ t @q<´.ÿtÚeùú®ËÆ‘ÑÒ9°%®JrD»Õ¼¶t09¸À4V«7f$9&ÉÑ¥[`¼öß}‡¼ï¨ggÿ=wNÅ­࿹ýîUùÌW/Í÷~vsFÇÆJçÀx­MÒHrb»Õôƒ Óœ)LSµzc÷$§&Ù«t ŒÇÓwÎß°O^°ï“ÒÕU-0©]}Óý9æ¤ÅùÙw–N-ñÍ$ïh·š+J‡å¸À4S«7*IÞ•ä“Ì,œiÁvýùÈ›÷ÉKž·[fôv—Îè(?½üÎsò/³ä¦J§ÀxÝžäÈv«ùóÒ!@î0Ôê퓜˜ä•¥[à± õõæÃoÞ;¯ª?5ý}3Jçt´³.¼)ŸýÚ¥¹ãžU¥S`<6%ùx’O·[ÍM¥c€mËÀ¦‰Z½ñÒ$§$Ù±t ü.ÝÕjþ÷Q{æÈCwÏœá¾Ò9SÆÈÈhNùÁ5ùÂéWä‡Ö•Îñh%ù“v«Ù.l;î0ÅÕêIŽIrtéx,¯}Ñ“Ò8bïìºpné€)ëáµsÜ·¯Ê g]5ëFJçÀcYžä­íVó¬Ò!À¶aàSX­ÞØ=É©Iö*Ý¿ËÞO—¾å¹Ù÷YµÒ)ÓÆ}®ÍçO½,§·,##£¥sà±ük’÷µ[͵¥C€‰eàSP­Þ¨$yW’L2³p<ªí†gæïØ7‡ô”ôtw•Θ–n¾ó¡|æ«—æ‡?¿%cc¥kàwZ’äˆv«¹´t0q Ü`Š©ÕÛ'91É+K·À£é®Vóþ?Ù3¯?왜U:€$W\_>qÂ%Y|ÍÝ¥SàwY—äè$ÿÖn5}$¦ w˜BjõÆ‹’œšdÇÒ-ðh^û¢'å½Gî“]Ì)À#8»uS>uÒ/s×ý«K§Àïrf’··[Íå¥C€­ËÀ¦€Z½Ñ•äCIþ.Iµp<¢½Ÿº]>ú–}³ï³j¥Sx k×ä g\‘ã¿suÖoØT:M;ÉQíVó§¥C€­ÇÀ:\­ÞØ!Éד¼¸t <’fÏÌÇßþܼì ßKOwWé¶À÷¬ÊÇ¿|q~|Ém+]h4Éß'ùd»Õ)ñŽý³×Óv*@‡zà¡u9ö”Å9ã¼ë3:6V:þS+É‘íVó®Ò!Àgà“@­Þ¨$yo’Ï&é)œéŸÕ“O½ó¹yÕ Ÿ–žî®Ò9LWßx>úo¿È¥×ÞS:þÓ=IŽh·š–þîPX­Þ˜“ä+I/ÝIòæ—?-ïþ_ÏÎóK§0yÁùôI¿Ì=Ë×”N$Mòá$Ÿi·š£¥cw(ªVo<7ÉIv-œÙc·¹ùä;÷Ï>»/,À·fÝHš§_ž/Ÿµ$6n*Iòý$oh·šËK‡ÀtgàÔêJ’w'ù\’žÂ9Ls}3ºò‰·?7‡òôÌèí.À4rÛ]+óñ/_œóßž±±Ò5Û’¼¶Ýj..Ó™;lcµzc8ɉIþ¸t ù’Ýrô럓¶*À4Öº¬qnl¯(’ä¸v«écP€;lCµzcŸ$g$Ù­t ÓÛÓvΧ޵ößsçÒ)$Ù4š“ÎYšÏŸvyV­ÞP:NKòŽv«ùpé˜n Ü`©ÕoMò¯IzK·0}ÍèíÊß½å9yÍ‹Ÿ‘Y3{JçÀÿpÿеùØ—/ÎwzSƼ?›²®Mòšv«yMé˜N Ü`‚ÕêIþ9É;K·0½ýqýIùë?}Ní8»t <¦Öeíüíÿ=wܳªt ÓÛšl~“û×K‡Àtaà¨Vo,Lò­$”naúzò‚Á|úÏÈA{ïR:¶Èº #ùÜ×/Ë g/ÉÈÈh馷/%9ºÝj®+S;LZ½qp6Ûç—nazêí®æCoÜ;¯;ô™éŸÕ[:·knYž÷7–+o¸¯t ÓÛeI^Ón5o)S™;leµz£’ä/’|>IwᦩW´s>ð†}³ë¹¥S`«KN:giþák—æáµKç0}­HòÆv«ùÝÒ!0U¸ÀVT«7feó×”¾¡t ÓÓ¢ù9æÏöÏ žó¤TÜø˜‚îºu>ü¥ŸçÇßV:…éí3I>Ün5GJ‡ÀTcî[I­ÞØ%É™Iö)ÝÂôS­&8êÙùÓWì‘Áþ¥s`Âýè·æ#_úEî~`u馯ó“Ñn5(S‰;lµzã÷“œžd^馟ývß>Ÿz×óòô'ïP:¶©‡×ṉ§,ÎÿýÁµÙ4:V:‡éé–$‡·[Í«J‡ÀTaàO@­Þ¨$y_’c“T ç0ÍÌèíÊ'ß¾oþèÅ»§·§«tsù²{ó/\”ko]^:…éiM’7µ[Ío–€©ÀÀ§Z½ÑŸä+IþW馟C¨åÃoÙ?»,˜S:&…‘M£9þ;WçŸN»qÂ%¹ÅÚÒ)L?7&9¼Ýj.-ÈÀÆ©VoT“|(ÉÇãïÒlC ·ïÏÿyÏórð>»–N€Ž²bÕúüý‰—ä›?¹>cc¥k˜fNò†v«ùÒ!ÐiŒr`jõÆp’S’¼ºt ÓGµš4^ó¬¼ýž¡™¥s cýâê»ò·_¼(7µ*Âôó÷I>Ön5GK‡@§è*“]­ÞxF’ó“Tº…éãYOž“?tHþð÷Ÿ‘½Ý¥s £-š?˜£}F*•ä²e÷eӨ׹³ÍÔ“=Ý]ÕÒ90mÜ¿bmþîø‹sÎÏnÊØX馑&ùT»Õ-“‘;ü†Z½±W’3“<¹t ÓÃá/Ø%û¦ý²`‡áÒ)0m]péùàq?OûžU¥S˜>ÎJò†v«é‡~‹;ü‡Z½ñº$'%™Uº…©o‡Ù3óÙw?/‡ì¿[*nfPÜÚõ#ùÜוÏ^š‘M^¬Í6qM’ÃÛ­æ ¥C`21£`Ú«ÕÕ$—Í_ îí¯|zþâu{gÞìþÒ)ÀoYzóyç1?Émw­,ÂôðP’#Û­æK‡ÀdaàÀ´V«7ú’œœäµ…S˜v[8”ϾûyÙoE¥S€ß²zÝÆœÝº)§»,WÞp_ÆÆJ1Œ%ù`’Ï´[M?yL{îL[µzca’³“<§t S[µšüÕ{æm‡ï•þ¾¥s€ßpÙu÷æ´/Ë9?½9«×m,ÃôöÍ$oi·š—€’ ܘ–jõƾI¾›d§Ò-Lm»-ÊçÿòàìýŒ¥S€ÿ°bÕú|û‚rڹ˲ì¶KçÀoº:ÉáíVóæÒ!PŠ;ÓN­Þxm’S’Ì*ÝÂÔÖxí3ó®×ì“Á~om€Éà߯üuN=wYνøÖ¬ß°i\g*•dn%»î03+ÖVsÓ]«'¸ò`’×µ[ÍóJ‡@ îLµz£’ä#I>^º…©mÑüüÓ{Ê~{.*ÓÞ½Ë×äôó¯Ïéç]ŸÛîZ9îs³z’ùÃÕì0TIo׿V©T2³8^ý`6ŽŒNP1$I6%yO»Õ<®tlkîL µzcV’¯$9¢t SÛÛ_õ´4ŽÜ7³}A”2:6–Ÿ,¾#§»,\zGF6oŒ^­$Û T2¸’áY>©è[H®o?¼µ’áÑ4“üu»Õ)ÛŠ;S^­ÞØ)ÉÙIž[º…©k§y}ùü_”ƒöÞ¥t L[wܳ*§ýxY¾yþ ¹ûÕã>×?£’‡*Ù~¨’îêxOUÒ?8”Ö’‡²næÇÕ ãôÃ$G´[Íñt0w¦´Z½±w’s’,,ÝÂÔõ†CŸ’¿þÓçfîp_é˜v6ŽŒæG¿¸5§þèºüüª»2:66®s]ÕdûÁÍÃö™>1kæŒüzeW–Þ¶êqÿ;`–$ye»Õ¼µtL4w¦¬Z½ñGI¾–Äê˜ ±ÝðÌ|þ/Ì ŸûäÒ)0íÜpûŠœzîu9ó‚³|åºqŸšYÉüáJ¶¨¤kÜoklýƒÃ¹ðꇲ~£·¹3aîMrx»ÕüEé˜HîL9µz£’äƒI>Yº…©ëµ‡<9û¦ý²ýÜÒ)0m¬]?’ïþôæœvîu¹lÙ½çËÚÓÝ•ÌÜ7»¯’‡*™;PIuý>¯R©¤·o(­%fddœ |ØrKò‰v«é‡ €)Ç€)£Voì˜ä¬$û—najzõówɇßz@vÜn°t Ly+WoÈ™ܘÓν.×ܲ|Üçz»“ùC•̪ffÏ>†¾,½s$wÜ»¶\SÝiIÞÒn5ו€­ÉÀ€)¡Vo<;Éw“,*ÝÂÔÓ?«'Ÿ{ÏóòÏJ*^ÛêWß•ÓÎ]–þüÖ¬Û02®3•$sû+™?\Éœ¾Ê¤ùöÅ®®jÆzrÑ’ó¢m&ÄÅIo·š÷”€­e’\éàñ«Õ‡'ùz’¾Ò-L=‡PËß½ý€ÔæÏ.SÖý+ÖæŒó¯Ï7~|}nùõCã>7³'Ùq¨š†*éížÀÀ'hpp —Þ¼.÷­X_:…©i[ IDATé¶$¯h·šKJ‡ÀÖ`à@ǪÕ•$ïOrLüÝ–­l挮|öÏÈ«^ô´tU«¥s`ÊË…¿jç´s—åüÅ·gddt\ç*•d»JæU2»¯s~5ÜÓݵc}¹dÙƒñ2w&Àª$G´[Í”€'ªsnzðjõÆŒ$Ç'yC馞î½S>ùgf—sJ§À”s÷«sê¹Ërú—å×÷¯÷¹Y½ÉNÃÕì0XIw×N°Á¡¡üüºUyhõH馞Ñ$G'ùB»Õô1 :–;§Voìä;I,ÝÂÔÒÛ]Í1¶_þèÅ»§»Ë[Û`kºìº{sâw—æ?¿eÜokO’9ý•,˜]Éœz[ûc™ÑÛ›åëzsùM•Najú×$ïm·š>E@Gš:·?¦…Z½±g’ï&Ù¥t SË{ÌϧÿüÀì¶h^é˜2F6æÿ~KNüîÒ\vݽã>W­$ó‡*Y0»šY½XØÀÐp~ºä¡¬Y¿©t SÏ“¼®Ýj®([ÊÀ€ŽQ«7^žäIJ·0uT«É‡Þ¸OÞôª=ÓÛÓ]:¦„«Öçÿþèº|õû×ä®ûWûÜŒîd§ÙÕì8\I÷4ù’ÅY3gäŽ]¹îŽU¥S˜z®MòŠv«yséØît„Z½ñÎlþJÍiòHƒmaÑü|ñ}ÏÏÞÏXX:¦„n_‘Î^’ï\xcÖ®÷¹¡Y•,˜]ɼþJ*ÓrÉPɬ¡\xÕƒÙ¸i¬t SËýIþ°Ýj^T:ÆkZ^ èµz£’äSIþ¶t SËŸ¼ì÷òþ7î—9C}¥S ãýdñ9ñ»KrÑwflœûìJ%Ù~`ó°}`¦ùB’ô÷÷eÙÝ£¹õîñ¿õÆaC’·µ[ͯ•€ñpC`ÒªÕ½I¾’ä¨Ò-L}3ºòOGœCzÊ4}lkÖä›ç_Ÿ¯œ³47ßùиÏõt%;W²Óp5½ÝØ¡ªÕjºfæ§W?˜M£ÞæÎVõ©$m·š£¥Càw1ç`RªÕ³“œ™äE¥[˜:Ús~>ó˂9¥S cµï}8'³4ßøñ²¬\½aÜçúgl~[ûöƒ•T­Óàà@.¿u}î^¾®t SË·’¼±Ýj®)Æ•€I§Vo,JòÃ$Ï,ÝÂÔP­&zã>yÓ«öLoWBÀãñË¥w焳—ä¼KnÏȦñ¿zn% çT2<ËDaKuwuecW~~̓ó2w¶žÅI^Ùn5ï)Äí€I¥Voì•äI”najX4 _|ßó³÷3–N€Ž322š³~zS¾röÒ\}Óýã>×UMæU²`v53{&0pšÌE׮Ϊ5K§0uÜœäÐv«yCéømîLµzã%I¾d°t Sß¼ì÷òþ7î—9C}¥S £<ðк|õû×äk?¼6÷=¸vÜçfö$ fW3¨’®êNC3gÎÈuåÚÛW•Naê¸?É+Ú­æ%¥Cà7¸0)Ôê7&9!Iwé:_ߌ®üÓÑçЃž’Š[ŒÛ5·,Ï g/ÉwzSÖoØ4îsó*Y0§’¹ýC„ UÉŒþ¡\xÕƒÙ4:V:†©am’×µ[ÍsJ‡Àr¯ ¨Z½QIòá$Ÿ(ÝÂÔpàóóÙ÷œ]Ì)al,ùñ%·å„³–ä’¥welœ»éJ%Ùa°’³+éŸa~°-  äW·¬Ë½+Ö—NajMòçíVóßJ‡@bà@Aµz£'ÉqIÞZº…ÎW­&zã>yÓ«öLo/€ÇòðÚ9íÜe9ù{KsûÝ«Æ}®·+Ùiv5;WÒÓ5üN=ÝÝYµiV.½~E馎O&ùh»Õôõeà@µzc0ÉI-ÝBç[4 _|ßó³÷3–N€Iï¶»Væ+ç,Íç_Ÿ‡×l÷¹•,˜SÉv•T­ &þ¡á\xÕCY¿qS馆““¼£ÝjŽÿØÊ\9ØæjõÆNI¾ŸdïÒ-t¾£^º[>ð¦ý3g¨¯t Ljÿ~å¯sâÙKòÿ.½#›FÇÿ‚æí*Y0»’¡Y&“Uÿ¬,»k4·Þ³¦t SùI^Ón5.Àôäö À6U«7vOòƒ$»”n¡³õÍèÊçÿò vðSSq³€G´a㦜yÁ9ñ»KsÝ­ËÇ}®»šÌ®dÁìjftO` [MµZÍXÏ@.Zú`ÆÆÿùx4—%yy»Õ¼»tÓÛL­Þ¨'9+ÉìÒ-t¶÷˜ŸÏ¾çàì²`N阔î]¾&'ÿšœú£ëòÀCëÆ}nVo²`v5; VÒUÀ@&ÌàÐPþýº‡³rõÆÒ)t¾[’Ön5—•`z1p`›¨ÕG$9%Ioé:Wµš|èûäM¯Ú3½=^¿íæ;Ê¿|óÊœuáÙ82:îsƒ3+Y4·’¹ýfSÁÌ™3r×Ê®,½mUé:ßI^Ùn5Q:€éÃÍ€ U«7*IÞ—ä³¥[èl‹æä‹ï{~ö~ÆÂÒ)0é\{ëò|áô+òƒ¿%›FÇÆ}nxÖæaûì>ó©§’™ùðªåÙ4þŸ xë’Ñn5Ï.Àôà† À„©Õ]Iþ9É_”n¡³þ‚]ò±w˜y³ûK§À¤rù²{Ó<ýŠüdñíÛ‚ óœþJÍ©dh–ÙÀT70П+n]Ÿ»\_:…Î6šä/Ú­æ—J‡0õ¹©0!jõF_’S“¼ºt «ZM>ýÎýrÄaÏJWµZ:&_\}W¾pú¹èÊ;·hؾÝ@%µ¹• Ì0˜NzzºóðȬ,¾~Eé:ß§“|¸ÝjúZ&Œ+[]­ÞØ>É9Iö/ÝBçZ¸}¾ôzžýô¥S`Ò¸àÒ;ò…3®ÈâkîÙ¢s; VR›[M_ï…ц†sáÕe݆M¥Sèl_Mò¶v«¹±tS“;[U­ÞxJ’&Ù­t ë휿×AÙnNé˜~øó[ó…3®ÈÕ7Þ?î3•J2¨’ÚœjföL`¥¯oVn¸g4·Ü½¦t íÇI^Ón5W•`ê1p`«©Õû$ùQ’íK·Ð™ªÕäïßþÜõ{¤««Z:ŠËÙ­›ò/g\™ëopÜ窕dÇáJΩfF÷Ò±ªÕjÒ;Ÿ-y0cc¥kè`—'yy»Õ¼«tS‹;[E­Þxa’ï&,œB‡Úi^_¾ôzöÙ}aé(jdd4ßüÉ ù×o]™[ïZ9îs]Õd§ÿ¶÷tM` SÆÐÐ`~víê¬Z³±t ë¶$‡¶[ÍëJ‡0u¸ð„ÕêW'9=ÉŒÒ-t¦ÃX”OýùAÙ~î@é(fý†Mùú®Ë¿yU~}ÿêqŸë®& æT³`¸’nÃv¶Ð¬Y3rË•Üxçøæà·,OòÊv«ùóÒ!L îöÖ}󧝨3Ý]ÕÒ9PÄêusÊ÷®É—ÏZ’ûW¬÷¹ž®dáœjv®Ä¯×x"ªÕjÆzrÑÒ36Vº†µ.É‘íVó¬Ò!t>w·Z½ñWI>WºƒÎ4ÎÌ|é/̾Ϫ•N€"zx}NüîÒœtÎÒ¬Xµ~Üçft'µ9ÕÌ®¤ê©?[ÑàÐP.\²2k×o*BgMòžv«ù¯¥Cèl®ºl±Z½QIòÉ$,ÝBgzÙ~µ|ú/ÊóK§À6wÿе9þ;Wçk?¸6¯Ý8îs3{’Es«Ùa°’ЧýLþ¾Y¹ö®ÑÜ~ïšÒ)t®&ùd»Õô}<.®¼l‘Z½Ñ•ä‹IÞYº…ÎS­&}ósò†Wî®Ò9°MÝuÿê÷í«rڹ˲nÃȸÏõõV²hn%Û ¶³mtuue]úrÉu+J§Ð¹>Ÿä¯Üx<\}·Z½Ñ›äkIþWé:ϳgæ¸Ô³ß‹J§À6uÛ]+óÅo]™oýä†l÷¹›‡íó<Ú§Œ¡áüäÊ[ôs ¿á¤$ïh·šãÿDÄÀ€qªÕI¾ä¥¥[èôÆ}òæWî®Ò9°M\}Óýi~ãŠüøâÛ2:66îs³û6Û‡gy”ÏäÒÓ݇6ÎÌe7>T:…Ît^’?j·š— 3¸ð;Õê…IÎMòÌÒ-t–í†gæ¸÷¿ ìµséØ&_sOš§_žÖeílÁ®=óú7Ûfz„Ïä6kpv.¸ryF6mÁ8lvq’—·[Íå¥C˜üÜŽxTµzã)I~œd×Â)t˜CöYcßspvÚ~¨t L¸Ÿ]~gš§_‘K–ÞµEÃöí+©Í©¤†G÷tŽÁÁ\rãÚ,_¹¡t gI’—¶[Í»J‡0¹¹%ðˆjõƳ³ùÍí;”n¡³|ð ÏÎ[ÿpïôöt•N€ uÞ%·¥yú¹âúûÆ}¦RIv¬¤6§šY½hFooî~¸;Ko[U:…ÎsS’—´[Í[J‡0y¸ð?Ôêç'ù^¯ßfÜûzrüßÔsð>»–N€ õã‹oËç¾þ«\sËò-:·ãp%‹æV3£{‚Â`›ª¤·o(^õ`F·ä« ùu6¿É}ié&'wþ›Z½ñŠ$ßL2³t cÝææ_ßÿÂìºpné˜0/¹+Çž¼8¿ºîÞ-:·Ý@%»ÌóÆv¦¦¡¡Á\tÝê¬\½±t ey’CÛ­æâÒ!L>îü—Z½ñ'INNÒU8…räKvËGÞö¼ öûLSÓ’›ȱ§,ÎO/ogK^T=»¯’]·«d`†GóLm³fÎÈ-Ë+¹ñÎÕ¥Sè,'yU»Õ¼ t“‹[4I’Z½ÑHòÏ¥;èÕjòéwî—#Û#Õª«SÏ-¿~(ÿðµ_åûÝ’Ñ-X¶άd—y•Ìîó{3¦jµš±ž\´ôÁ-ú ÓÞú$¯k·šg—`òp›˜æjõF%ÉÇ’|´p dÎàŒœðÁf¿=•N€­îžåkò_¿,güäúŒŒŒŽû\_o²Ë¼jæ xÏô584”Ö’•Y³~Sé:Ǧ$on·š_+ÀäàV 0Õêj6¿µýÝ¥[èû>}»|á}/LmÇÙ¥S`«zèáõù—o^™“Ϲ&ë6ŒŒûÜŒîdçyÕì0Tñ’ôõÍʵwmÊ÷®-Bgi´[Í/”Ž šä“íVs¬tå¸bLCµz£/É·’Vº…ÎP­&ÿçÝÏËk^òÌTÜ"˜"FFFót]š§_žûÿ›¦»ªÉÂ9Õ,œ]IWua ˜Ñ?œ ®|0£cöÊŒÛ?%ùëv«9Z:€2LS¦™Z½1˜ä{I^Pº…ΰÃì™9áC‡dïg,([ÅØXræ7æs_ÿUî¸gÕ¸ÏU+ÉN³+©Í©¦§kaŠJkÉʬ^¿©t ãä$oo·š#¥CØö ܦ‘Z½1œä‡IžWº…ÎpОóóù£ëÙiû¡Ò)°Uœ÷ËÛóÙ¯^šën]¾EçæU²ó¼jftOPLqý}³²¤=’;XW:…Îqf’×·[Íõ¥Cض ܦ‰Z½17ɹIö-ÝBgx×îž¿:ê¹™5³§t 7£;Ùy^5; VRñ¶¹žžî<°vF®ºeeé:ÃÙûÕKsí­Ë·èÜü¡JvžWÍŒî ¶ªÞžžÜ»¦'Kn]U:…Éï×Ùü&÷e¥CØz ܦ€Z½±O’ó’Ì-ÝÂäÕ]­æŸŽ>0¯~ÑÓK§ÀY|ÍÝ9æäK³øš»·èܼJv™WM_ï…¦R©¤:s(?½zyÆÆJ×0ÉÝä÷Û­æ5¥CØ: Ü:\­ÞØ?ɹI†K·0yÍœ‘“>rHž³ûÂÒ)0n×Þº<Çž¼8üêŽ-¸Ϫd×í*œé‘8tº¡áü¿«VdÃÆÑÒ)Ln÷eó›Ü—”à‰s›è`µzãà$?H2Xº…Éë™»ÎÉ¿}ðì²`Né—{–¯É±'/ΙܘÑ-X¶÷õ&OÚ¾š9}…ÃT20ПËnYŸ{W¬/Âäö@6¿ÉýÊÒ!<1nõªVo¼(É÷’ô•naòzù‹rì{^Ùƒ³J§ÀcZ¿aSŽûöU9îÛWfͺ‘qŸëîJv™[͎ÕT<‡)iFoO~½ª'×Þ¾ªt “Ûò$/i·š—•àñsµè@µzãeIÎJ2³t “×_¾îYiùÜôtw•N€Çtvë¦sòâÜyßÃã>S©$; W²ó¼jº«L •J%£Ýƒù÷k,Âä¶"ÉKÛ­æâÒ!<>î¦Vo¼"É·“ô–narªV“þ˃rø!Ï(éŠëïËÇ¿|q.½öž-:7·¿’'mWÍ,¿)…i§o`8ç_ñ`FÇÆJ§0y­Lrh»ÕüEé¶œ;@©Õ˜äô$=¥[˜œ†û{sòGɾϪ•N€ßéîV瘓ç¬ oÚ¢‘j_oò¤í«™Óçq7LgƒCC¹pÉʬ]¿©t “×ÃIk·š•`˸ñtˆZ½ñº$_OÒUº…Éé»ÌÎñ<$».œ[:Õú ›rÜ·¯Êqß¾2kÖŒû\wW²ËÜjv®¤âI7d ¿/¿ºuCî[±¾t “×ê$/o·š­Ò!ŒŸk?@¨ÕoHrR’jé&§ÃX”Ï4žŸ9C}¥SàQuáM9ö”Źó¾‡Ç}¦RIv®dçyÕtû )ð[fÌèÍmVsã«K§0y­MòÊv«ù“Ò!Œ;À$W«7Þ–äøø»¢ñÚg彯nz{¼Ü€ÉéŠëïËÇŽÿE~uݽ[tnn%OÚ®šY½L ]]Õ¬íË¥×?T:…Ék]’ÃÛ­æ¹¥CxlFR“X­ÞxW’ãJw09U«É?6Ì¿x÷Ò)ðˆî~`u>}ÒâœÝº)£ccã>××[É“·¯dvŸGÚÀøõö ç‚«–g þ¸azÙäÚ­æ÷K‡ð»ùmÀ$õonÿré&§áþÞ|åÃ/Ê~{,*ÿú #9î[WåKg^•5ëFÆ}®»+Ùe^5;URñ4x††ó“+WdãÈhé&§I^Ûn5Ï.À£ó+€I¨Vo¼1ÉIñ÷5ÁSwÎ <$OªÍ+ÿÃw.¼1Çž¼8¿¾õ¸ÏT*É‚áJÍ«¦»:qÀ´088_\¿&+ÞX:…Éi$Éÿ{w¥wYßÿÿufIf&3CVÜ„@ÀÈŽP¹ÙD­KÕjÕjW«µ_õ®K] îu©ÖuÜÅݪu©Z×*² A@%0a ! I&3™ßøë·~»˜fæš¹çñøÿ}ÎóÎ ÷¹®÷\Ÿ‘á¡-ÀÏÂÀ So4Ÿ•ä³ñ[ÿÆcŽ©çí/:> {K§Ào¹ìç·çõgü(?¹öö–æõÕ²ï’*=ÝSÌI=óçåç·%7Ýqoéf¦ñ$Ïúbéþ+KS3H½Ñü£$_Hâ"þ‹ÿó”ƒò²?yXº»:K§À¸í®-yË'/ο ß»<×Û]Ë~KkÙ­×µ505º:;s×¶yùé¯6–NafÚ™äOG†‡>W:€ßæ¤`†¨7šOIò¥$¥[˜Yª*yÇ ž§zpéøÛFÇòÁ¯ü4ùêOsï¶±]žëìHöY\eù@-57ÖÀ«ÕjIwοêîÒ)ÌLIž=2<ôùÒ!ü_Ž f€z£ù„$_Mâin~KoW>qú‰9æð¥Sà?|íÜëóÖO]œ[ïܲË3µZ²çnµì½¨J§oXÓ¬¯0?¸üîŒïÜõ/M0gŒ'yÆÈðÐWJ‡p î…ÕÍÇ&ùz’îÒ-Ì,«öÈÇ_}rVí½¸t $I®½q}Nûà…¹øêÛZšì©eÕ²*½NA‚úúsÞU›²eûxéfž±$82<ôÒ!Xp(ªÞhžšäIæ•naf9öÐÝóþ—Ÿ˜¥‹”N€lÞº#ïúÜ¥ùä7¯ÎØøÎ]žëîLö]Rei¿«i`fèëëÉåkDzîîm¥S˜yF“üÁÈðп—˜ëœ"Ro4OJòí$óK·0³üacß¼éÇeA¯¿{ ¼¾!ÿðñ5Y·þÞ]ž©%Ùc·ZöY\¥£šº6€ûc^wWn¾§3×l.Â̳-ÉãF†‡Î.0—Yp( ÞhŸä»IzK·0³¼ð©å¥Ï>:]¥S˜ã®ÙWèÂ\pÅ--Í ôÔ²ji-}ó\G3WUUÙVë˯ÝP:…™çÞ$:¿tÀ\åD`šÕÍc“|?I_éf–·<ÿayöãKͯt Úº},ïùÂe9ãëWfÇØÎ]žëêHV.©²û€.`ö˜×7˜³¯XŸ‰‰Ò%Ì0›“÷-¹ßR: ]Ù¬˜dõFsßܷܾwéf†ªJ>øwÇçqÇ?¨t s̺õ÷æ gü(ßúá/31±ës½Ýµ¬ZVË`+e€žƒ9ëò»³³•Hiw×&9adxh]é€vä4`ÕÍIÎK²Oéf†ÞyùÌëNÎч­(À2¾s"ÿ·«òîÏÿ$›·îØå¹Ž*Y±¨Êž»ÕâC„ÿWÿÀ@~pù†ì·äθ*ɉ#ÃCw–h7Ž$&I½Ñ¬ç¾—Û÷+ÝÂ̰ǒÞ|öu§dõ¾ËJ§0‡¬¹ê¶œþ¡ òóµw·4·dA-û.­2¯sŠÂf¹þþœ÷³MÙ²m¼t 3ÇeINÚP: Xp˜õFs÷Ü÷rûƒJ·03ºjQ>vúÉÙsÙ`éæˆ ›¶çûQ¾rö/2ÑÂÃó»’U˪,ìu} ð»ôõõæÒ_nÏGK§0sü8É£F†‡6–hN( z£¹[’s’Qº…™áÔ‡í•w¾ø„ì6ÐS:€9â߆oÈëÏøQîܰµ¥¹½Ö²bQ•ŽjŠÂÚÐüùórÝí¹i]kÿæÒÖ.Hò˜‘á¡Í¥CÚw€ Þhö&ù^’ãJ·03üÙïW?çØÌŸ×U:€9à–;·ä´ü0g]|sKs}ój9`Y- æ»2¸?ºº:sÛæî\sÓ¦Ò)Ìç$yüÈðн¥Cf;§÷S½ÑìNòõ$-ÝÂÌpÚŸ‘ç=õÈtTž»`jML$ŸúÖÏòöÏ\’Í[wìò\UKV,ª²×ÂZjn‹ªª²5}¹øçJ§0s|?ÉŒ m+0›9²¸êfG’Ï%yzéÊ«ªäÝ{lžròA¥S˜~qÓ†¼|è¼\zíí-Í öÔ²ÿ²*=ÝS0'ÕRÍÈyW®/ÂÌñÍ$O-0[YphQ½Ñ¬%ùP’¿.ÝByU•ŸÞÈIG¯*@›Û1¶3C_¼,øòÙ1¶s—ç:«då’*Ë]L•ÞƒùÁåwgçÄDéf†/'yæÈðÐxé€Ù¨£tÀl3°òè·&yqéÊ›?¯#Ÿã)yäQû–N Í]|õºüéë¿—ï\pcvîÜõåÉ% j9hÏŽ öZn˜J;F·ç •ƒY{ÇhKÿNÓ¶N²|`åÑßÞ¸vMé€Y§³tÀlRo4_‘äU¥;(oaÿ¼|î §äÐíQ:€6¶y뎼å“?Îç¾{mK¯ww&«–VY¼Àb;ÀtÙ´qcN9¬?ç_³%›·Ž•Ρ¼ç%¹3Éé¥Cf/¸ì¢z£ùÜ$C¥;(o%½ùÒ›“Wí^:€6væoÊŸ¿þ{¹àŠ[ÒÊ[ÀËk9pÏŽ,˜g¹`ºŽŽfÿ=zsÏÖZîÝ>^:‡ò9°òèM×®¹¨tÀlâD`Ôͧ%ùbü~šó´b0Ÿzí£²÷òÝJ§Ð¦îܰ5¯ùð…ùö¿J ¶§§;ÙY•Áǘ¥ÍŸ?/×Ü:‘_ß¹µt 3ß }ºtÀládàw¨7šNòÍ$]¥[(ëÈÕKrÆi§dÙâ¥ShS_<óº¼ék²aÓö]ž©Õ’úÂZö^T¥r 0cÌëîÊë;rí[J§PÞx’?ú·Ò!³ã €ÿE½Ñ<6É™IzK·PÖIGî™÷¾üÄìÖßS:€6´öÖyÕû˜^qKKs æ×rÀ²Zúæ¹ú˜‰º:;sÛ–î\sÓ¦Ò)”·=É£G†‡†K‡ÌtN9þõFóð$ÃIK·PÖS+󖟾žîÒ)´™ñùè׮̻?ÿ“lÝ>¶ËsU-Y¹¤Ê»Õ\úÌpU6ìèÉ7l,By›’œ02<ô“Ò!3™³€ÿF½Ñ< ÉùIv/ÝBYñ¸Õyõ_=<Ý]¥Sh3WÝpW^1t~®¼áΖæöÖ²jY•ù]SÀ¤«ÕjÙ^-ȯÝP:…òîHrÜÈðÐu¥Cf* îÿz£¹W’ ’ìSº…²^òôCó·üÐttT¥Sh#ÛGÇóŽÏ]š}ýªŒïÜå¹ÎŽd¿¥U–õ»æ˜jI÷@~ø³õ¥C(ï¦$)09ùøOêæ’$ç%9°t e½á9Gå/žôÔüb`ýðŠ[òª÷ÿ0koÝØÒܲþZö]Z¥«cŠÂ˜6]½ƒ9ç Kîäê$Ç ÝU:`¦±®ðõF³?ÉÙI~¯t åTUò®æ±ùÃS*@Ù²mGÞxÆš|áû×fbb×çº;’ýw¯²¨ÏÕ.@;ééß-?¸ì®–þŸ@[Z“䔑á¡Í¥Cf§ Iêæü$ßIrbéÊ鬪|äUÇçÔc÷/@¹ð§·æeï=/#ë6µ4·´¿–UK«tzµ -õ æÌŸÜ¶Üçº3“óÚ“rìû”N MlË›?ñã|æÛ×´´¼ØÕ‘쿬Êâ®sÚ]ÿÀ@μbCÆÆ,¹Ïq_NòÌ‘á¡ñÒ!3`N«7šU’O&ùÓÒ-”3Ø×Ͻñ”¾zÏÒ)´‰K®Y——¾û¼üê–{Zš[¼ –ý—Uéòj;ÀœÑ?Пs®Ü”m£v›ç¸&yþÈð¿væ<Ç"ÀœUo4kIÞ“äy¥[(gŽù⛃÷_^:€60ºcð¥Ëóž¹,;ÆZ{µ}å’*{ ºªà6¯»+7®ïÈ ·n)B9Û“!½=þ¾€ûï7oÈKÞ5œ+~qGKs=µúµ+óOÿ|I¶Žïò\UKöYRe¯Ý\ÏÐšŽŽ*vôäŠ6–N¡œ;’72gýÍ“Ìéu¬åvî—/|ïç9åÿÚÒr{­–¬XTËá{W–Û˜ÛïÉñ‡.,A9''ùX½ÑôChk¶}€¶To4_ûÜ™ƒ^üG‡äïþì˜ttø{NZ³ný½ù?o;;g|ýÊŒîØ¹Ës½Ýµ¼W•¥ýUjVΘBcÛ³_}an\·µt ež¤cãÚ5甘*ŽV€¶So4Ÿœä_ã·ÎœôŠgž>ã÷Rs‹@‹¾~î yõ‡/Ì=›··4W_XËŠÅU*GRL£®žÁœóÓõ¥3(çy#ÃCg”Ž˜ ŽX€¶Ro4MrV’ù¥[˜~¯þ³‡äyO=Ê Y´dóÖ9íäkç^ßÒ\wg²zy•ÁR”ÑÝ7˜³/·ä>G'yÂÈðÐwK‡L6'-@Û¨7š«“\˜dQé¦ßžsTþòÉ)À,sÉ5ëÒ|ǹ¹yݦ–æ/¨å€eU:;¦( vѼ¾Áœ}ÅúLL”.¡€-I#ÃC—–˜LÜ€¶Po4—'¹(ÉÊÂ)ð–ç?,òøÃJg0‹ìœ˜È{¾pYÞ÷ÅË36¾s—çªZ²jY•Ý\µ0sô,Ø-?¸ü.KîsÓmI>2‹«Ôܰ0ƒõöæÌËÖ[rŸ›ÎKrêÈðÐöÒ!”ã`Öª7šµ$ŸLòg¥[˜^U•|àeÌã«K§0KlÞº#§}à‚|íÜë[šëîLV/¯2Øãj€Ù¡o`0ßÿ‰%÷9ê_’ÿ†Sò°C÷.À ·y뎜ö òµs¯oi®»3Y½¼Ê`ëSÚÓÀÀ@¾ņŒYrŸcîHòð‘á¡J‡´Â 0+ÔÍeI.L²ªt Óg^wG¾ð†SòPËíü—^{{^ôOçäæu›Zš[¼ ––Ué옢0˜!~ó’û/¹Ï5¿HrìÈðÐ¥Cv•w`Æ«7š½IÎIò°Ò-LŸîÎ*Ÿ{Ã)9æð¥S˜ÁvNLä=_¸,ïûâåß¹ËsU-Ùoi•僮L˜;úsæ³cl×ÿŸI[¸(ÉÉ#ÃC[K‡ì §5ÀŒVo4«$_LòÔÒ-LŸÎªÊ?¿áä<â!û”N`Y·)/zǹ¹äšu-Í-˜WËêåUzº§( f°þþœõÓÝaÉ}Žùj’?/ð»T¥~‡7ÆrûœRUɧ_{¢åvþW_;÷úœÚüZËËíõ…µ¾·åvæ®M7å”Ã2¯«£t Óë)IÞQ:`WxÁ˜±êæŸ$ùLé¦OU%Ÿ:ý¤œxô~¥S˜¡6oÝ‘Ó>pA¾vîõ-Íuw&«—WìqE IÒß¿ g_¹9ÛwxÐ{ŽyÉÈðÐ{JGüoœÞ3R½Ñ<.ÉYI¼£4GTUò±¿?!zøþ¥S˜¡.ûùíyÁÛÏÉÍë6µ4·¸¯–v¯Òé¡Zø-ý9óŠÙ1¶³t Óg"ÉÓF†‡þµtÀÿÄ‚;0ãÔÍý’¬I²¤t Ó£ª’¼âø<渕N`†:ãëWæ­Ÿº¸¥¼Z-ÙwI•=ws- ÿ“|ÿŠ ›(Âôٞ䤑ᡠK‡üwœä3J½ÑLrQ’K·0=ª*ùÀË™Ç7V—N`Ú¸e4/y÷p¾ÿ£µ-ÍÍëL¼G•þù®DàwéÈ™—oÈØ¸%÷9d}’£G†‡®/ðÿršÌõF³3É·“œZº…éó¾—>"O:Éß3ð_]ñ‹;ò7ÿxvn^·©¥¹E}µ»þAf·±$§Ž S:ÀIPL½Ñ\šäÇIVNaš¼î/Ì_=åÈÒÌ ›·îÈ+†ÎÏ7ÏÿeKsÝɃ—Wèqå Se^ß`κ|}é ¦ÏÝIŽúEé`nsÚQo4ç'9+ɱ¥[˜§ýéCò7tTé fŸýò®üÍ?ž_ÝrOKs {kyÐò*]Sü‡îÞÁœ}…%÷9äçIŽÚP:˜»,¸Ó®ÞhÖ’|&ɳK·0=^ñ¬ÃóÂg<45¿>øÏ~÷š¼áŒeûèxKsû,®²÷"M0:çæÜ+-¹Ï!ßOò¸‘ᡱÒ!ÀÜT•æ¤Ób¹}Îxé3Í Ÿñ{–ÛH’lÙ¶#/ü§srÚ.hi¹½»39´n¹JÛvOyÈÂÒLŸS“¼«t0wùh0­êæÓ’|¨tÓ£ù´ƒó’gªré@ríëóǯþn.ºòÖ–ævë­å½:ÒÛíœ Šßž½—ï–›ïØVº„éqôÀÊ£×m\»æ’Ò!ÀÜã˜6õFó¡IÎK2¿t Sïož|`^ùOGå£A$_øÞÏóÚ\”m£c-Í­X|ß«í.6`&¨e¼³?]swé¦Çx’SG†‡Î.Ì-΀iQo4÷Nòã$ËK·0õžûÄÕ9ý9HG‡åv€¹nëö±¼êý?ÌWϹ¾¥¹®Ždõò*»õºÒ€™¥–ÑjA~üó ¥C˜w'9fdxèºÒ!ÀÜá4˜rõFsA’&9¼t SïÙÞ?oü›G¦«³£t …]wÓÝùë·ž•ëonmn°§–Õ{TévÄ3R­VË–‰¾üä÷”Naz\—û–Ü=ÝL îÀ”ª7šI¾šä‰¥[˜zOlEé ˜˜HþéŸ/Ék?|Q¶ïØõWY«ZrÀò*õ…UjN ííØ±#ìÕ—‘»Æ26>Q:‡©õЕGß¹qíš‹K‡íÃñð€ÕÍ}“\’dQé¦NU%g¼²‘Sq@é ظe4/ü§srÎ%7·47¯39pÏ* 湚€¹¦ ?g^qOÆÆ,¹·¹ñ$:³tМ"H½ÑìKra’ÃJ·0µÞó·Ï>êàÒpíëóWoþAÖÞº±¥¹Ýzkyðò*¾+ sVÿÀ@¾÷“ Ù9aɽÍÝ“ä÷F†‡®/Ì~Ué`öª7šµ$åö¶÷†¿:Êr;ÀõÍó™?ø»o´¼Ü^_XËÁ{Yn€¹nÓÆyÔ‘ Só g»Lòµz£¹ t0ûYpˆ—'yzé¦ÖËžyhþâR:€i¶sb"ÿðñ5yÁÛÏÎ½ÛÆvy®£J¼G••K*Ÿ“’$[6Þ““_T:ƒ©wH’ÿæ¡4€ûÍ{ ÀýRo4OMòÉÄU;{îWçïþì˜T•ÿÌsÉúÛò—ÿpf¾~î -ÍÍïJ­Wìqžü¶ñ۳Ϟ sÓí[K§0µN²yãÚ5–f/'K@Ëêæª$'YXº…©óô“÷Ë[_ÔH—oHÌ)W^gž÷–däöÍ-Í-ê«åAË«tú†4ð?ªeGÇ‚¬¹vCé¦ÖÎ$§Ž U:˜,¸-©7š ’\˜äÐÒ-LdzwÞûw'¥g~Wé¦Ñ—p]Nûà…Ù6:ÖÒÜŠEµ¬Xl³øÝjµZ6Ž÷æŠ6–Najݕ䨑ᡵ¥C€ÙÇ‚;°Ëêf-É—’<µt Sç‡íž3NTúûæ—N`šŒïÌë>ú£|ö;Wgbb×ç:ªdõò*‹ú\;»®££Êº-ósíÍ›J§0µ~’丑ᡭ¥C€ÙÅ3 @+^Ëímíðý烯<Ùr;ÀrÇÝ[óGÿ|æÛ­-·÷v'GìÝa¹hÙøøÎìÑ?š•ËûJ§0µŽLò¡ß<¤°Ë:J³C½Ñ|L’OÄ`ÚÖª½òÙ7§OÀÿ¨ÞhÖ’|%ÉSJ·05:«*_|ó£ò°C÷.À4ظe4ÏëY9ÿò_·47¿+9hÏ*½Ý®€©Ñßß—s®Ú’m£­}]†Yå¢$'Œ y®ø_U¥€í´XnokzÅq–Ûæˆ_ÝrOžðÒky¹} §–Ã÷î°ÜL©M›¶äÄCûÓÙé7G{x’÷–Žf¾ŽÒÀÌTo4—äŒøâKÛzó_?4ø¨ƒKg0 ~xÅ-yÖkþ=·Ýµ¥¥¹ÝjyðU:=›LƒÑí£9pŸÁüò¶í™(ÃTù½•Gß¼qíšËJ‡3—…5࿨7š$¹8É`é¦Fóiçïþôá©ù5Ðö>ûkòÚ^”±±-Í­\R¥¾Ð0ýúúóýËÖg–{»MrÜÈðÐÅ¥C€™É‰ð[êf’5I,ÝÂÔxÚ‰ûæm{Bº:}̠휘Èë>rQ>õ­«[šë¨’ÕË«,ês•”ÓÕ3˜s~º¾tSg$ÉQ#ÃC·—f§RÀ¨7šU’Mò¤Ò-Lã_ž¾úÔôõt—N` mÚ2šçÿãY9ï²_·47¯39hÏ*}ó\#åvôçÇ×n(ÁÔ97É£F†‡ÆJ‡3KU:˜QN‹åö¶µzÅ`†^~¢åv€6·öÖyâ˾ÑòrûÀüZŽXÑa¹˜1æOlÉÁûô—Î`êœäm¥#€™§£t03ÔÍS’|"¾ðÒ–v_8?_xÓc³|é@é¦ÐEWÞš?~õwsË[Zš[Ö_˃÷¬Òéy,`™˜˜ÈÀü‰ì¬ºsÏ|·©‡¬<úºk×\U:˜9,°©7š{%¹,ÉÒÒ-L¾ÞyùúÛ?®Ú½t Sèóß»6¯þÐ…Ù1¶³¥¹•KªÔº6f®ùóçå²µc¹kãh馯Ö$ÇŒ ý´t038©€9®Þhv%9;Éq¥[˜|U•üËOÍÃXQ:€)²sb"oñÍ«21±ësU-Y½¼Êâ® €™oA_oλæÞÜ»}¼t Sã—I:2<´¾tPž oŽåö¶õ—=Òr;@Û|ïŽüÙë¿—£µåöyÉá{[nfÍ[îÍ ‡ô§³Ãï—6µ_’ÏÕÍŽÒ!@y~ÀVo4Ÿ˜ä}¥;˜oxÎQyúc)À¹é¶MyúéßÎO®½½¥¹þùµRïHO—å0`vÙ¾}4î³[n¸mk馯þI:6®]své ,§V0GÕÍý’\šd·Ò-L¾¿yòùû¿<6µšŸ{íhÍU·åyoùAÖoÜÖÒÜÒþZؽJåØ˜ÅºûsöåëKg0už<2<ôõÒ@9Ž®`ª7šó“\äÈÒ-L¾'¿OÞù’“ÒÝåc=íè_¾ÿóœöÁ ²clgKsû,®²÷"׃@{ïìÏE×l(ÁÔØ”äa#ÃC×–ʨJE¼;–ÛÛÒ±‡îž·¾ðxËímhb"yãÇ~”W¼ïü––Û«Zòà=,·í¥s|sÝ·¿tS£?É—ëfoé  î0ÇÔÍ?NòüÒL¾ýëùÀ+NÌ‚Þy¥S˜d›·îÈ_¼ñ{9ãëWebb×çº;“Ãö®²dåv ½LLLdñüѬ\ÞW:…©qH’÷•ŽÊð´'Ì!õFó $ßHÒ]º…ɵdp~þåÍÉžËK§0ÉFÖmÊ3NÿN.¾z]Ks æ×rè^éé¶Ü´§;wfÙ@•M£¹wÛxé&ßCVý«k×\Q:˜^N³`ލ7š ’ü8É¥[˜\óçuäkÿøØrÀòÒ)L²K¯½=Ïù‡ïç®{¶µ4·dA-Z^¥rÌ úzsþµ÷f‹%÷vto’‡Ž ]]:˜>Ué`êÕÍZ’Çr{Û©ªä“§Ÿh¹  ýûE7æ§}§ååö½v«åÁ{XnæŽÍ[îÍñ-HW‡@m¨7É—ëf_é`úXp€¹áyIžU:‚É7ôâGä¸#W–Î`’}üWåùo=+ÛFÇZšÛoi•}—ºæžM›6ç”#¦fǽ”ä¥#€éÓQ:˜ZõFó¨$_‰ÿï·W=ûˆüÉ/À${ãÇ~”w}î'™˜Øõ™ª–ýš“rÂC÷+À$9ëâ›ó‚·-Ûv´4·Ç`-û-«\ô삾ޞ\pݶlÞjɽÍlKrôÈðÐOK‡“Ï«®ÐFêfG’ÏÇr{Ûù‡ç>Ôr;@ùçï^›¿zÓ™-/·¯\Re•åv€]¶åÞ­9þ éìð ªÍÌOòåz£Ù_:˜|Ü ½¼6ÉÉ¥#˜\ùøåOXé &ÉÛ>}qNûà36¾s—gjµdõò*õ…³Zµq㦜|øÂÒL¾%ùH½Ñô#ÚLGé`rÔÍG'ùhâñ¦vrÒ‘{æmÍFº:ýl˜íÆÆvæ%ïΧ¿}MKsUrð^Uõ9ú¸¿vŒnÏŠ=æ¦;¶–Naršä–k×\Z:˜àÿcïNÃë¾ë;ïΑdY¶%[Þ-Ÿ8NìÄ[Bö… ,ÊL¡”%,… pe+È „„ös—)K§¹Ë=&„,MXömÂ^„²‡Xò*ËÒý i¯B‰­¿$û§#½^Ï¿×õ¾.=Ð9¿ÿ÷ÿ;´‘ÑÑÑ ôwå—CÉðžÑÒ9LF’ Þyû-…;€ýpƒ;LSf«?ɇâÿõŒqå‹OÉ6”Î`>píyñ•·dd¤ÚrÓáËê9t‰#>€v´c箜±i~:;½ª8ƒœßEsÀ4æ4 ¦¡F³UKòž$kJ·05ž÷'›òŸº¹tpõG¾’×¾ç³÷L-É‘+êXd   åaÇö—Î`êÔ“|°Ñl-,Ü? î0==;ÉKG05N?fE^zÖI©y– Ðv.øëÏåÊ})vÛS¯%›êYÞç@`&Ø6¸5g½¸tSçÐ$ï,Ü¿ŽÒÀïj4[›’üc’®Ò-LÞª%óò ™þ¾žÒ)T°wt,/¹êÖ|øúïTšë¨'[V×Ó?Ïr;ÀŒ²w8 ûæç—÷ —.ajÝ·öä Þyû×K‡ÿ‘“5˜FÍÖÜ$·%9¶t “×Y¯ç£o~TŽÝ°ªt ìÞ›ç_vSnüü+Íuuܻܾ Û#8€™hΜ®Üñ³äçwï*ÂÔJò€»n½æŸK‡¿«^:ø—ÅrûŒqõy§Znh3ÛvìÉS_w]ååöîÎä˜F‡åv€lxxO°¦+Ý]¥S˜½I>Øh¶:K‡¿Ë‚;Lfë1I^\ºƒ©qÎÞ”?yè¦ÒTðë{væ umnÿæÏ+ÍÍ›“sHGzæ 0¦mÛwä¡Ç,LÍ{3Å©IÎ/ü.µ`h4[«’|=ÉÒÒ-LޙǮÌû_÷Ÿ2·Û‹þíâ®_nËSο.?ü—­•æÌ­eË@=.ñ˜]êsûòÉoü¶tSc4É™wÝzÍgJ‡÷rƒ;Öh¶êIþ[,·Ï«–ÌËU/iZnh#ßýñoóŸ_þ¿+/·/šWËÑ«-·ÌFc»‡²iMoé ¦F=ɇÍÖÂÒ!À½,¸@y/Kò°ÒL^g½ž÷¿æ!Y±ÔA@»øÊw~™?}åµùùo¶Wš[º –ÍõtxÚ0+e wO–-ì.ÂÔ84É;JG÷rŸÔh¶NLòáxélFxûKOσŽ?¬tãô©¯ü4ϸðÚ1\inåÂZŽXYO½v€Âh {÷Žf튞Üùë=+ÃäÓ·öäïÞyû7J‡Àlg™ i4[ósïr{gé&ï…OØœÇ>xcé ÆéÚOÿ0ϼøÙ¾kO¥¹F-ë—×c·€$Ù¶m{þèØE¥3˜:ïj4[n5€Â,¸@9—'Y_:‚É{ðq«òâ'ŸT:€qúŸ7?/¼üæ ïÙ[iîÐ%õ¬]êñ¿kÛàÖœ¾¥¿tS£7ɇÍ–‹ê  'pP@£Ùzd’sKw0y«—Íϕ癹ÝÎ7ÚÁß}â;yéÕ·fïèX¥¹µKë9d±{ÛøÃ:F¶åÈÆ‚ÒLS“œ_:f³ŽÒ0Û4š­þ$×çÞ7¿ics:ëùÈ%Èa%¥S‡ÿö±;òêw~6£cÕ–Û_VÏê~ËíÜ¿±±±,éíÈowÖ²k¸Ú/1-Ù·öäï¼ý'¥C`6rƒ;|ïH2P:‚É{ëKNÏQG¬,À8¼÷£ßÌù﮾ܾny=‹,·°»víÎ)Gô¤³ÓçÇ žäCfkaé˜,¸ÀAÔh¶ž”äÉ¥;˜¼ÖÊ77”Î`Þñ_Ë%ï¿-wÛsÄŠzV-´œÀø mËÓ_:ƒ©±6÷^`d¥`¶h4[I>–¤§t “óÐäÒ<(Þ˜î®úð—s凾Ty¹ýÈ•õ¬è³Ü@u{†wg`ÅÂÜõë]¥S˜¼cúÖžüýÁ;oÿFé˜MleÀAÐh¶jIÞ—dqé&ç rÅyg¦{NgéöãMøBÞòá/WZn¯%Ù¸ªžå½–Û˜¸î±íY·j~é ¦Æ;ÍÖa¥#`6±àÇÙIU:‚É™ÓYÏ{_õ,[¼ t ûqñûnËÛÿák•fjµ{—Û—.°ÜÀäìÝ;šÃ—¥o~Wé&¯/ÉÍ–[Ðà ±àX£ÙZ—äªÒLÞ•­S³eýŠÒìÇùïþlÞûÑoVš©×’M«êYb¹€)²sçq~:ê>cΧ%yué˜-,¸ÀÔh¶:’| ‰ßžksÏxôù“‡l*À>Œ%¯xÛ§òkï¨4W¯%›êY<ßâSkpp(}ÀâÒL×6š­–Ž€ÙÀ‚;X/Krzé&gËÚþ¼ò'§æù&À´5:6–¿|Ë­ùÈõß©4×QO¶¬®gÑ<‡?;‡îÉ G.,Áäu&ù@£Ùê.3]G阩ÍÖ1Iþ.þß¶µ¹Ýùð%Ȫe}¥S¸{GÇÒºâ–üã-߯4×QO¶ Ô³°Çr;ÖÜŽ½혓­ÛGJ§09Ë“t ÞyûM¥C`&sƒ;÷½±ý·IºJ·09oÉY¿fié îÇÈÈhιì¦ü¯Oþ Ò\g=9ju=}–Û8FöîÍÆõ,èé,Âä½²Ñl\:f2 îp`\˜ä˜ÒLιÿesyÆ¥3¸{FFsönÌuŸýQ¥¹ÎŽä¨F=½s-·pðìØ¹+gn^zÍçÐ6WOòF³ÕS:f* î0ÅÍÖéI^QºƒÉ9aãÒ¼ø)'–Îà~ìÞ›g^t}nüü+Íuu$G¯®gA·¥"¾ÁÁ¡<äØþÒLÞ†$—–Ž€™ÊÉL¡F³µ ÉW“¬+ÝÂÄõÎëÊÇßú¸¬Yå` `:Ú¹{$ϼèú|öë?«47§39juGæÍ9@a0.µÜ=Ü“;î*ÂäŒ%iÞuë5Ÿ*3Ü`j]Ëímï]¯8Ór;À4µmçž<õµ¯¼ÜÞÝ™ݰÜÀt0–Þ‘ô÷úpÚæjIþ澋ð€)dÁ¦H£ÙzT’ç•î`r^ñÔcÓ<á°ÒüCÛ‡ó”ó¯Ëîøy¥¹¹]÷.·÷t 0¨h×îáœzļÔkµÒ)LÎáIÞT:fŸ` 4š­%I¾‘dUé&îÁÇ­Êû_÷ÈÌéê,Àï¹ghwžrþuùÆ~]iî_—Û»ù0 Í™¿07õîÒLÞÃîºõš›JGÀLáw˜ïˆåö¶¶táÜ\Þzåv€ièîÁ]ù³W}¬òr{ÏœäËíLcÃÛsÔÚÞÒLÞm4[}¥#`¦°à“Ôh¶þ<É“Jw0qõzòžW6³j™ó€éæž¡ÝyòkþO¾õ£j·ZÎíJŽ^Ý‘9–Û˜ÖƲbþHú{ç”arÖ$¹ªtÌÜ`ÍÖê$ï,ÝÁä\ð¬ãsÒ1‡”Îà÷ nÎSο.wüpËí Ëí´‡ÝÃÃ9åÈyé¨×J§09Ïn4[.3w˜ F³UKòþ$ý¥[˜¸GŸvHžþ¸cKgð{¶íØ“§œ]¾ñƒ_Wšëî¼w¹½Ûr;mdhp(>Æ£çà}fkqéhwÜ`➟䑥#˜¸ÕËæçõ眞Ή¦“í»öäi¯»._ûÞ¯*ÍYn íÞ>˜£ë+Áä¬JrMéhw¥ 5š­Ã’üc’9¥[˜˜z=ùðÅÏá%¥SøwvîÉY\Ÿ/~ë•ææÜ·ÜÞÓu€Âà X87Ùº»ž»÷–NaâŽé[{ò×ï¼ýÛ¥C ]¹®*j4[µ$d~é&îMçž’c7 ”ÎàßÙ5<’g\x}>ÿ^i®«#9zµåvÚßîá=9y}O:êµÒ)LÎ{ÍÖ²ÒЮ,¸@u‘äa¥#˜¸'>ôðüÙ#¶”ÎàßÞ³7qñ ùÜ7~Vi®«#9ºQOßZ`†Ú–‡»¸t“³,É;ï»@¨È‚;TÐh¶’\Yºƒ‰[·º/¯{Ω©»ñ`ÚØ32šg_zC>õÕŸVšëìHŽZ]ϼ9Îz˜YvmÛšcï+Áä÷¶±þ$}ß…zÀ8Yp€qh4[Ë’¼­t÷´G®Ïc›KgpŸ½£cyáå7çãŸûQ¥¹[nŸk?€™ohh[rLé &ç“<£t´ î0>×$YZ:‚‰9lÕ‚¼ò'§æ™'À´0:6–ó®º%×~ú‡•æ:êÉ–zz-·0‹ìÜ6˜cï+Áä¼µÑlR:Ú…wØF³õ¸$^ºƒ‰©×“·½¬™E}=¥SH26–¼ô-ŸÌGoùA¥¹z-ÙxÝ·+ÍÔjɦUõô[n€$ÉΡ{ò€u Kg0qó“¼§Ñlù’û`Áþ€F³µ É{Kw0qo{éXÞW:€$¿ï¶ü͵wTš©Õ’«êY<ßÞü{‹çîβEÝ¥3˜¸‡'9«tLgÜà{}’µ¥#˜˜>asš'øU7€éà ÿÏçó^ ¶C IDATÞ~³ÒL-Ɇ•õ,±ÜÿÁððžXw:;|^ncoi4[ËKGÀteÁ~O£Ù:=É‹Jw01G¯[œ>é„Ò$¹üo¿˜wýϯWž;re=KXÖ€û³mÛö4î/ÁÄ-Nò–Ò0]u”€é¤ÑlÍMr]’¥¥[¨nNg=ºøY¹´·t À¬wõG¾’«?ò•ÊsG®¬gy¯åvØŸÑ‘áÌ›7/¿.ÂÄÝ·öä/ Þyû÷J‡Àtãwø]$ÙP:‚‰¹âE§æˆC½›PÚ{?ú\õá/Už[¿Ür;Œ×ØØXéÍü¹î8mcïn4[np€ßcÁîÓh¶˜äå¥;˜˜'<ä°<þ¡KgÌzãwsÉûoÏØXµ¹µKëY¹Ðr;T±sç¥¯twH’KKGÀtã”’4š­®$_Hrléª[½l~>ö–ÇeÉ¢ù¥Sfµë>û£œû¦›3²w´Ò\£¿–µKÝË5ÒÙ›Û¾uOé &f,ÉiwÝzÍm¥C`ºpR÷ze,··¥z=yÇËd¹ °O}õ§yá›ÿ©òrûÊ…–Û`²æfgV.ž[:ƒ‰©%y_£ÙšS:¦ §…Ìzfks’×–î`b^óŒæø-Ò³ÚW¾óËœ}éÞ³·ÒÜÒµ¬[îqLÖÈÈHpèœtvÔJ§01[rïÅ|@,¸0Ë5š­Ž$ÿ5‰7¡ÛЙǮÌ3wLé €Yí;wþ6O¿ðúlßµ§Ò\ÿ¼Z6¬¬Çú LmÛ¶§yté &îüF³µ©tLܘíZIN.Au½óºrÙ‹ÎÈœ®ÎÒ)³Ö>”§¼öºÜ3´»Ò\ßÜZ6®ª§f»¦ÔðŽÁl`¶ú‹$)AuÖ,ÌKžzRé €YkÇ®‘œuÁõùο­47§39juGº\$ ÜÐàÖœ¼Ñ/b·©Þ$ïl4[µÒ!PŠwfF³µ<Éå¥;¨®³^ÏÛ^zfzçw—N˜•öŒŒæ9—Þ¯|ç—•æ:;î]nŸÛu€Â€ÿ §¶3+Ï-ÁÄ<.ÉŸ–Ž€R,¸0½9I骻ìÜ“²iÝŠÒ³ÒèØX^pùÍùÔWZi®£ž5Pϼ9( øƒFFFò€C礳ÃEàmêífËn³’wf•F³õ$O/ÝAu|úš<á›KgÌZ/ë§rÝgTi¦^K6Ô³`®…(aÛ¶íimGºM­È½øÀ¬ÓQ:–F³ÕäÚ$KK·PMowÞþÃÓ7ßÏç”pñûnËßþŸoUš©%Ù4POÿ<ËíPÒèÈpæÍ›—_—N¡ºö­=ùSƒwÞþÃÒ!p0¹Á€ÙäåI6”Ž º·¼ø´¬\Ú[:`Vºæï¾’÷~ô›•çŽXYÏâù–Û ´±±±Ò?šùsÝ…Ú¦þºÑlõ”Ž€ƒÉ‚;³B£ÙZŸäüÒTwÖZŸ?:e]é €Yé×Þ‘+>ô¥Ês‡/«gy¯åv˜.vîÜ3·,,ÁĬKòºÒp09Y`Æk4[µ$OòˆÒ-T³jé¼\ÿÖǧá¼Ò)³Î?Þòýœwå­«4·fI=k{ÓÑpGo>ÿí{JgPÝÞ$'Üuë5_-ƒÜ˜ žËímé­ça¹ €?ÿãüåÕŸ¬¼Ü>°¨f¹¦±ùµYÙß]:ƒê:’¼¯Ñlu–€ƒÁ‚;3Z£ÙZ”ä-¥;¨î…OØœS°¦tÀ¬sÛ7–s.»9##£•æVôÕrø2ž`:Û32’ãëNg‡SÛÐñI^\:§ŒÌt—&YY:‚jŽ\³0ç>ñøÒ³Î7~ðë<ëâOd×ðH¥¹% jY¿Üc'hCCÛsæÑý¥3˜˜KÍÖá¥#à@sÒÀŒÕh¶NJrn骩ד«^|FzçûY<€ƒéwmÍY¯ûx¶íØSinaO-VÖSs$´=;³á¥3¨®'É{Í–o`Ìhܘ‘ÍVg’w'ñ¥®Í¼ú¬ãrì†U¥3f•_ývgžvÁÇó›­»*ÍÍï®eÓ@=u§pÐVÆÆÆ²fÑhzº;J§PÝÃ’œU:$ îÌT/Lr\éªyà†¥yÆãŽ-0«lßµ'O¿ðã¹ëC•æº;“-õtzÚmiç®Ý9sËÂÒLÌf«¿t(Ž˜qÍV#É%¥;¨¦³^Ï/:=s»;K§Ì#{Gó¼7Ü”oþà7•æ:ëÉ–ÕõÌq”mmûÐÖ}Xoé ª[–äÒÒp Xp`&º:É‚ÒTóú矘#Ö.+0«¼âmŸÎ­_¾«ÒL­–l¨gޜڪ¦ öfþÜŽÒTwN£Ù:¾tܘQÍÖc’üiéªyðq«òÄGl.0«¼ùƒ_Ê?ÜøÝÊsVÖ³°Çr;Ì»víΙ[–ΠºZ’w6š-;€Ì8þ¹0c4š­yIÞQºƒjæuwäõçž–®N7,úø·ó¶ÿþ•Ês‡-«géËí0Ó nÍqë,¹·¡“’<§tL5 îÌ$¯Krh骹âE§fͪþÒ³Æ ŸÿqÎ×g36Vmnõ¢ZV/²Ü3ÕâžáôÎë*Auol4[KKGÀT²àÀŒÐh¶ŽJòÒÒTóø3Í77”Θ5¾úÝ_å…—ßœ‘½£•æ–.¨å°e+ÀL¶{÷pÎØ´ tÕ-NòÆÒ0•\³@Ûk4[õ$·&9£t ã×ßÛÞþø¬XÒ[:`VøÑÏóø—ý¯üfë®Js {jÙ²ºžº§J0+ìªõæ‹ß½§tÕz×­×ÜV:¦‚«6˜ žËímçêóN³Üpüfë®<íu¯¼Ü>oN-›,·ÀlÒ×µ+ý ºJgPÝ;ÍVGé˜ ÜhkfkY’ËKwPÍ3}DzòºÒ³ÂÎÝ#yÆ…×çΟ Vš›Ó™lY]O§§I0« ïÉ)¤æE×vs\’sJGÀTp$ @»{s’Å¥#¿ÕËæç¥O;±tÀ¬°wt,ç\vS¾ö½_Ušë¨'[êéî<@aÀ´648˜7,*Au—6š­¥#`²,¸жÍÖƒ“<£tÕ\}Þééï›W:`VxÕ;>›¾ð“J3µZ²iU=ó»]׳ÙüúÎ,î›S:ƒjæÞ‹ ­Yp -5š­9IÞUºƒjZO<*§»¦tÀ¬põG¾’\ÿÊsG®¨gÑ<Ëí0ÛíÙ3’SŽ˜—š¯íæ¬F³ufé˜ î´«ó’l,Áø¹faÎyâq¥3f…¿¿ñ»¹êÃ_ª<·vi=Ëzm¯÷Ê©›úKgPÝ;ÍVWé˜( î´F³5äµ¥;¨æŠ–óºKgÌx·|鮼òíŸÎØXµ¹U‹jiô[n~ל±Y¾È³Þ6³%I«tL”wÚÑeI”Ž`üZO<*ÇmZ]:`ÆûÆ~ç¿ñ¦ŒŒŒVš[² –×ylüG###9a]OjÞ‡m76š-êhKN*h+fë´$g•î`ü]9?ÏûÓ”ΘñîúÅPžqáõÙ¾kO¥¹¾¹µlXY]àþ åŒ-ý¥3¨fA’«JGÀDXp m4š­Ž$ה+^tzúÌ-0£ývhwžvÁÇó«ßî¬4×3'Ù?¸kk¥¹®ŽdË@G:;P0£ìÝ»7Ç­íN½æ Ù6óöF³Õ]:ª°à@[h4[‹’¼¡tã·¢n^ôç,0£%/¸üæ|éÛ¿¬4×QO¶¬®gn× f¤¡¡myÐQý¥3¨fC’¿,UXp ]\dYéÆïŠÖéé_8¯tÀŒvÉûoÏõ·ÝYynÃÊzt»u˜€=Ci,ë)]A5¯m4[‡–Ž€ñ²àÀ´×h¶6'yQéÆïÉ_—ŸxXé €íÃ×;ïûÿ¾Qyî°¥õ,žo¹˜˜½{GsT£+uß+ÚHO’«KGÀxYp`Zk4[µ$×$é(ÝÂøô÷vçeO;±tÀŒö™¯ýK^ó®Ïfl¬ÚÜÊ…µ¬î·„LζmÛsæQý¥3¨æñfëÑ¥#`<,¸0Ý=>É•Ž`ü®xÑ)Y¾dAé €ëŸº5Ï{ãM­4·h^-ë–y4L½»‡²fEOé ªy[£ÙòG`ÚsŠ À´uß—ª«Jw0~ò CóðSחΘ±¶nÛg^ô‰lݶ»Ò\Ïœdãªzj.o¦Èèèh6t¥î‹F;9<É+KGÀþXp`:{Y’µ¥#Ÿù=]yõ³NNÍáÀ1²w4g¿þÆüð_¶Všë¬'›:Òé©0ŶmÛž3Žê/A5Õh¶Ö•Ž€}q” À´Ôh¶Ö$yUéÆïòœœå}¥3f¬W½ã3ùÜ7~Vi¦VK6 ÔÓÓu€¢€Y¯¾g[–/ê.Áøu'y[£Ùr{Ó–w¦«7'é)Áø<â¤ÕyÌ™G–Θ±Þý?¿ž¿ûÄw*Ï­_^ÏÂ; À3²woNX×?öÝV•äÑ¥#àþXp`Úi4[Nòg¥;Ÿî9yÝsNIGÝÇ €á·Ý™Ë>ð…Ês«ûkYÑgÃ8ð‡râ†E¥3¨æªF³å÷¾˜–l¢0­4š­Î$×”î`üÞøü“rè@é €éÿþóoÒºâ–ì«4·x~-k—z <½»Ò7ß¾t92ɹ¥#àq² Àtó¼$G—Ž`|N?fEÿÐ¥3f¤_Þ½#ϺøÙ¾kO¥¹ùݵlXY»Û€ƒi÷𞜾±·tÕ\Øh¶–”Ž€ßgÁ€i£Ñl-MrIéƧ³^Ï¥Ï?5]¥Sfœ]Ã#yÖ%ŸÈÏ~½½ÒÜœŽdó@=ž nÍ1‡õ•Î`ü%¹°tü>Ç›L'—$é/Áø\töñY¿fié €é¼+oÍ׿÷ëJ3õÚ½ËíÝ( `VöîÍÜ9.Jk#ç4š­-¥#àß³àÀ´Ðh¶ŽKò¼ÒŒÏqG.Í“éû-Àpùß~1ûÌ+Ϲ²žsk `üvìÜ•3·,,Áøu$¹ªÑlùB À´aÁ€âîû’tM_–Ú@½ž¼é§¦{Ž«À¦ÚÿûOßÏÛÿþ«•ç]RÏҎ׀éaçöÁ¬XP:ƒñ{D’G•Ž€eÁ€éàÏ“œQ:‚ñyõYÇeÓº¥3fœ/Üñ‹¼üšOel¬ÚÜòÞZYl¹˜>ÆÆÆ²~y-¾«´‘«ÍVWéH,¸PX£ÙZäÍ¥;ŸM‡.ÊY=¦tÀŒó“_ åì×ßá={+ÍõÍ­eý {€égÛöyÐQý¥3¿ IÎ)‰wÊ{U’Õ¥#ŸË^pjæÍõÂ6ÀTÚ¶cOžyÑ'ò›­»*ÍÍíJ6 ÔSw!"0MíÝ5”ÕKæ–Î`ü.l4[KJG€wŠi4[ë’¼¬tãsöã6䛽‹0•FÇÆòüËnÊwüÛJsõdó@=]( ` ŒŽŽæ˜C»Sóbn»èOraé°à@IoJ2§tû×ßÛüÙKgÌ8¯{Ïçrë—ïª<·qU=󿨦¿¡¡m9uSé ÆïœF³µ¹t³›wŠh4[§%ùÓÒŒÏeçžœ%‹æ—ΘQþæÚ;òkï¨<·nY=ýó,·í£{lG÷¹ÿ®Mt$¹²t³›wºF³U‹/Cmã¡È#O__:`FùÔWš‹Þ{[幕 kYµÈr;Ð^öŒŒää#\ªÖFþS£ÙzTéf/ î”ð„$§”Ž`ÿ:ëõ¼öÙ'¥£î#ÀTùÉ/†rî›nÎÈÞÑJs}=µ¬[æœhOCƒƒyàú…¥3¿«ÍVWéf'§ Tf«;Ée¥;Ÿ¿zú±YèÒÒ3ÆÎÝ#yö%7䞡ݕææt&WÕSsy;ÐÆ÷ìÉü¹¥3ŸIÎ)ÀìdÁ€ƒíÜ$‡—Ž`ÿèÍÓ}Té €å¥W2ßúÑÝ•fjµdÓªzæØÚÜ®]»sÆf·¸·‘ ÍÖ’ÒÌ>Ü8hÍV’×–î`|Þxî)™?¯»tÀŒñÎÿñµüïOýså¹õËëéëêv`fØ>4˜MkzKg0>ýI.(ÀìcÁ€ƒé5¹÷ËÓÜ“¾.§=àÐÒ3Æ­_¾+—ÿ·/Vž[µ¨–}–Û€™d,‡ô¥«ÓêZ›8·Ñlm*ÀìâSE£Ù:<É‹Jw°óº;ò’§_:`Ƹógƒyá›ÿ){GÇ*Í-ì©åð¥å3ÏŽ;Óþ¹Už[¿¢žÝh€Ùmhh{NÝÔ_:ƒñyT£Ùú£ÒÌ\ܘrfëÐ$ç•î`ÿ.|Îñ9tÀÀdÝøùçÊ}¹òÜêEµ,ïµÜ$sk;Ó;¯«tãsY£Ùò…€‚;Âë“t—Ž`ß¶¬íϾ¹t@ÛûçŸnMëÊ[2:6VinѼZÖ.õ¨à_ ïÉé›zKg0>'$yBéf&§¦L©F³uB’§–î`ÿ^î)™ÛíÍw€ÉضsOž}é Ú>\i®»3Ù°²žš»î~ǶÁÁ¬_=¿tãó†F³eñ€)gÁ€)sßOO]Qºƒý;û±süæÕ¥3ÚÞ‹¯¼%ßÿÉ=•fêµdÓ@=](  ­eýòŽÔ½ÜÖ'yNéf îL¥?NÒ,Á¾-œ?'çþÙJg´½·|øËùÄmwVž;bE= º-jÜŸmÛ¶ç´Í‹Jg0>4š­¥#˜Y,¸0%îûÉ©7—î`ÿ.}Þ‰YÚï»%ÀdÜpû¹ú#_©<·º¿–e½–Ûö§klG-è*Áþ­Hr^éf îL•ç$ÙP:‚};îˆÅyÌ™G–Îhk߿랴®¼%£cc•æÍ«eífÆcÏž‘œº¡·tãóŠF³µ¬t3‡ST&­Ñlõ%¹¨tûwÁÙ'§«³£t@ÛÚ¾kOξôÆlÛ±§Ò\wg²qe=5—·ŒÛÐàÖl8Ä/”·Þ$¯)ÀÌaÁ€©ðÊ$ÞÄæžöÈõ9~óêÒmíåoýT¾×=•fjµdãªzÜ;PÝaKjé¨{[¸ œÛh¶+ÀÌ`Á€Ii4[I^Rºƒ}ëžÓ‘=é¸Òmí×Þ‘ÿý©®,¸°_f«3É%¥;Ø·‹Î>1+–ô–Îh;×~ú‡ù›kÿoå¹C×Ò?ÏÕí%íÜ6˜Æ²žÒìÛœ$—Ž }Xp`<ÎJrdéî߆5 óø‡l,Ðv~ø/[óòk>™±±js‹æÕ²f‰Ç,¥åè5Ý¥3Ø¿³ÍÖÑ¥#hN^اF³ÕäÂÒìÛ%Ï=9sý6@%»†GòÜ7Ü”m;öTš›Ó™lXY»Û¦‡¡Á¡sx_é ö­–ä¥#hÜØŸç&YS:‚û÷_šksêü‰ªzõ;?›oÿèîJ3µ$WÖÓÕq`š˜˜U½£éìð*ò4÷˜F³Õ,ÀôgÁ€ûÕh¶æ'9¿t÷¯³^Ï_>õøÒmç¿ßðÝüÃß­]¥3ÚÆ÷~rO.zïm•çúçÕ²ºßr;@;Ê1‡õ•Î`ߎNò§¥#˜ž,¸ð;ÍÖš$ç”îàþ=æ´CrÒ1‡”ÎhÃ{öæoº9;wTšëêHŽ\éQ @;ZÕ7šÎ/,Os¸Å€?Ä?~ßë’Ì)ÁV¯'ù”–Îh+—¼ÿö|ëGwWž;re=]~D -mß±3§nê/Á¾mIòÄÒL?Üø7fëÈ$Ï,ÝÁý{îŸlΑk—•Îh7|þÇùÀÇî¨<·º¿–þynúhg]£;² §³tûva£Ùòz9¿Ã‚;ÿÞEI|i˜¦ævwäÙrté €¶ñË»wäeW2ccÕætײv‰G(ínxÏžœ¾iaé ömc’'•Ž`zq: @’¤Ñlm‰/ ÓÚ«Ÿ~\V.í-ÐÆÆ’Ö•·äîÁ]•æ:êɆUõÔ\Þ0#ìØ¶5«—ö”Î`ß.h4[®ÚàßXpà_½&‰ÇvÓÔŠþ¹yÂÃ6–Îhïø_Ëg¾ö/•çÖ-«§§ëPÄØØXŽ=´»tûvd’'—Ž`ú°à@ÍÖÆ$^ºƒûwásNLïü¹¥3ÚÂW¾óË\ù¡/Už[Ö[Ëò>w@Ì4ƒƒC9æ°¾ÒìÛëÜâÀ¿²à@’¼:noŸ¶Ž^·8<}}é €¶°mçžüÿìÝy”f}çëoU¯’z‘Z»TÚ/ò‚ÁŒÂj³zØ‚ÙNR†BàN˜™;™™d†a’3 É„“…d²\r“Ìn0 Á ^ðŠ—î–ZK«ëþÑž«t$a—ÕÝou×óœ“Ç'?ON$õûþê­ŸýÏŸÌääTKsý=ÉŽ5®M«õCSéî²ÑÆv&yyéÚƒ“Z€W«7v&¹¼tÇ÷ËWœžî®Ò ÂÛû³¹åα–f*INZWM·[€Ekノœ{ÊòÒüxï¬Õ=¥#(ÏQ-ïˆ?ÚÖsŸXËÏÜ\:`AøÓÿýüŧ¾ÛòÜ–•Õ ö{Å`±ë™šÈÀ’îÒß¶$¯,@y:X­ÞðƒA«V“·\öØTÜ­<¬ïß1šw¾ÿó-Ï /©d㈀NpðСœwÊpé ~¼_®Õ½¥#(Ë‚;@g{{’®ÒÛk.89'o_S: íMNNåÊ_ûDÆ'µ4×Ý•œ´®ëícßøƒÙ¸²¿tÇ·%É«JGP–w€U«7ü@ÐÆúz»òÚ—œQ:`AøÕ~9߸éÞ–çv¯­¦×7Ót”f³™3¶.)Á÷Õê¾Ò”cÁ s½-IOéŽí—^~f6¬*Ðö>ýÕÛó;þÍ–çÖ/¯dd™·Û:ÑØèhvn\V:ƒãÛœäÕ¥#(Ç‚;@ªÕµ$¯)ÝÁ±­YÞŸ—>ûÔÒmïÞ&ò¦w*SÍfKsËú*Ù¶Ê @'Ûµ¶;Ÿ{ngï¨Õý¥#(Ãé-@gz[’ÞÒÛ;_sv†üŒðp~þ×?{îŸhi¦ZINZWMÕ@GÏéÛ|³z«%yméʰàÐajõƆ$¯+ÝÁ±íÙº"Ï{ò®Òmïwþâ›ùäµ·¶<·}u5K=ý@’ CÍT=ãÞÎÞ^«7–”Ž`þYp蕃‡·4×Ó•ìZëê€3:6–3¶ •Îàø~©Vo8XÄü&°xýL’¥#8ÚÆÕËò¼§x½àxÞõá¯ä[7ß×òÜÎ5ÕôtÍAgÃòfªßÖ¦NNòâÒÌ î‹P­ÞX–ä-¥;8¶_¾âqYÚßS: -]{Ã]yÿŸ]ßòÜš¡JVX<`vŒïËÙ»‡Kgp|o¯Õ) î‹Ók’¬*ÁÑvoγÎÝ^: -M˜Ì›ß}uO5[šëëN¶¯våÀìî=˜în;Ômêì$Ï,ÀÜpÚ °ÈÔêžx½½m½ã§›ÞžîÒméßýî5ùþ£-ÏíZ[M·fÙÄþ9÷ä¥38¾·—`n8îX|^–dséŽvÖ®‘ÔÏÞV: -]}ÝmùÐÇohynÃòJ–/õšs£·¹/KûºJgplO¯ÕO,Àì³à°ˆÔêJ’_,ÝÁ±ýâ+›î.ôüKŽÈ/üÆgÒl¶6·¤7ÙºÊy sçÀÁC9÷”áÒŸWÜ!§¾‹Ës“œ^:‚£wÆÚœwÖ–Òméïý|îüÑÞ–f*INZ[MÕãí̱Ãûdzb §tÇöÂZ½qZéf—w€ÅÅëímê.;+•ŠÛV€é¯>ó½ü¯O·å¹M#• ô;o`îM>œsv–Îàø~©t³Ë‚;À"Q«7ÎIò´Òí¹O¬åìÓj¥3ÚÎÝ÷íË;Þû¹–çú*Ù4⊀ù³o|4ëFúKgpl?Y«7¶—Ž`ö8ýX<¼ÞÞ¦/=³t@[zËo|:Œhi¦ZIv¯«Æ—å0ŸšÍfÎÚ¶´tÇÖ•ä­¥#˜=ÜZ½±;É…¥;8ÚÅOß–Ów¯/Ðvþðÿ¹!ŸúÊm-Ïm]UÍÒÞ9€‡1>6š«–”ÎàØ®¨ÕëJG0;,¸,oIâͪ6S­&W^tFé €¶óƒ;Fóï?ð¥–熗T²a¹c0Êh6›9c‹÷6Õ—äÍ¥#˜Ü¸‡>}úS¥;8Ú+Ÿ»;»¶®.ÐV¦šÍ¼ù¿^½ûµ4×UMv¯s­@Yc££Ù´Æ’{›º²Vo¬(À‰s °ð]•éO¡ÒFªÕäµ/>½t@ÛyßG¯Ï—¿uWËs;VWÓ×=AÐ’fNÛdÁ½M $ù™Òœ8 î X­ÞJòÆÒíÊ OÍ– > ðÏýÓîÏ»?r]Ës#Ë*Y3T™ƒ"hÝØèh6¯YZ:ƒc{S­ÞXV:€cÁ`a{}’áÒÌÔÛ]Í+Î?­t@[™j6ó–_ÿt:ÜÒ\w5Ù¹Æuí¤™Ó6õ•ŽàØV&yméNŒa€ªVoô&yséŽöæŸ<=Ö •Îh+ÿýcßÈ׿sOËsÛVWÓÛ=ApFGDze­WÜÛÔ/<´WÀeÁ`áº<ɆÒÌÔ×Û•—>ëäÒmåæ>˜ÿòáëZž[¾´’µC•9(€ÕÌ©5¯¸·©Z’——Žàѳà°Õêj’·–îàhW]rZÖ¬,ÐVÞúžÏdÿÁÉ–fºªÉÎ5®1h_c££Ù¶Î+îmêmµz£«tŽ“a€…éùIN)ÁL½ÝÕ\âõv€>ø7ßÊ5ß¼³å¹-+«é ˜E§lôŠ{›ÚäÂÒ<:ܦ_,ÀÑ~öâ=Y·ÊëíÿÇí÷Œç?þ/·<7´¤’ Ë+sP³ktt4;Ö/+Á±½½Vo8`X€,¸,0µzã¼$ç•î`¦îj5/{¶Gõþ¹·ýæg3>q¨¥™j%ÙµÆõ ÇIzK'plg%yNéZç„`áy[éŽvåE§fÚ¡ÒmãOÿáÛ¹úºÛZžÛ¼²š%öX@FGG³s£WÜÛÔÛKÐ: î H­Þ85É Jw0SwµšKŸsré €¶qÏýù·¿{MËs}•l\î›ÃXxv¯ë)À±=µVo<©t­±à°°¼µtG{ý‹ONmÝòÒmãïý\?ÐÒL¥’ìZ[IÅ~; ÐèèXv×Jgpl?_:€ÖXpX jõF-Éå¥;˜©ZM.Þ)¥3ÚÆ_öæ|ü ßoy®¶¢’e}¶ÛX¸v®í.À±½¤Vol+À#gÁ`áxSßgÕf^÷‚S²yýŠÒmá±ùå÷¾å¹¥½É¦W,l££c9i“WÜÛP5I£tœÓb€ Vo,OòÓ¥;˜©ZM^~¾×Ûþýß¿{˜hyn×Újªo`رÆ+îmêµµzc¸tŒw€…áI|Ä·Í\qÁIÙºq¤t@[øÄµ·æÏ?uSËsWT2Øo»€Åatt,§l,ÁÑ’¼¦tŒw€6W«7z“ü\éfªV“ŸºàÔÒma|ß¡üÒo}6Ífksý=É–•®*X\¶®î*À±]U«7<±°85h—$Y_:‚™^ñÜ]ÙV[Y: -üÊï]“;îÝÛòÜ®µÕT=ÞÀ"36:–S·xŽ mNraéžw€6V«7*I®*ÝÁLÕjòªçï)Ð>ýùÈßÝØòܺáJ†—Øn`qòemëÍ¥xxþhoOLòøÒÌté3wdçæU¥3ŠÛp2¿ø›ŸI³ÙÚ\_w²m•+ ¯±±ñœ¶Õ+îm艵zãÜÒüxNÚ›×ÛÛÐ/8­t@[øO¼6?¸c´å¹kªérCÀ"·i¤šŠ//kG^qhsŽÚT­Þ¨%¹¸t3½ì'¶ç¤m«KgwÝwç÷þ×?¶<·f°’ËÜî°øyŽm]T«7¶–Žàø,¸´¯ŸIÒU:‚™^óÂ=¥Š;49•_xϧsxªÙÒ\OW²}µ« :Gm…y·¡j’FéŽÏ)2@ªÕK“¼¾t3]Tß–Sv¬-PܯÿÑWó[hynÇšjº=é@Û›S6{Ž ½¶Vo •ŽàØ,¸´§Ë“Œ”Ž`¦×½ä´Ò Å}ëæûòÞ~½å¹••¬ðjgÛjŸönCƒI^S:€c³àÐfjõF%ÉU¥;˜éEOÙ’=;½Þt¶f3yÛo~&““S-ÍuU“«]IЙFGDzcý²ÒíªZ½Ñ]:€£9Mh?ÏH²§t3ý´×Ûò‡û­|íÛ÷´<·ee5½®‹è`»7ô–Nàh[’¼¸tG³àÐ~ÞT:€™ÎÒ¦œ¾{}é €¢î¹"¿öÁk[žè«dýòÊÀÂ16:–«–”Îàh?_:€£Yph#µzcg’ Jw0Ó•ž^: ¸ó;_ÌèÞƒ-Ïí\S‰õvhæŒ-ÜÛйµz㉥#˜É‚;@{ù¹Ä}_;yÚYësæÉJgõ™¯Þž¿úÌw[ž[¿¼’~Ç]$ãc£Y½¼¯tG{séf²àÐ&jõÆP’+Jw0Ó/<­t@QÎ;Þû¹4›­Íõv'[Vº†€ÿ£Ùlæ¬íËJgp´‹kõÆ–Òád }\‘d°tGœ¶}EžpƦÒE½ç¿–ïß1ÚòÜöÕÕt»…€ìÏòžÒÌTMòs¥#8ÂÑ2@¨Õ]I¥;˜éÍ/;#]]þ¨:×wo{0ïû³ë[ž[±´’U•9(€…íðáÃ9{×Pé ŽöºZ½áaJ€6ak =\d{éŽØ¸zYžzö¶ÒE½ã½ŸÍÁC‡[š©V’k\?Àñ>0že}]¥3˜i(É«KG0Í 3@{¸ªt3½åÒ3Òß×]: ˜?ûÄMùüõw´<·i¤š~ß´ÇuèÐdÎ9y¸tG{S­ÞðÉ€6`Á °Z½qz’g”îàˆÁ¥=yΓv”Î(æÁñù•ß»¦å¹¥½ImEeŠ`qé:<‘Þë{mfk’—ŽÀ‚;@;ðz{›yË¥gdh ¿t@1ÿá÷¿œ{˜hynÇšj*öÛàaí?p0O8É+îmèÍ¥°àPT­ÞX•äòÒÑÛ]Í žº³t@1×ÞpWþèÿý§–çÖU2¼Äv;sG¶n)PÄí÷Œç¿þÏëZžZRÉÚ!ñðhìÝ7‘Çì*ÁL]I^_: “Yp(çM¥˜éçŸR: ˜_~ßç³oÿdK3•J²såv8k›ñˆ{Ûym­Þè-Щ,¸P«7žä ¥;8âÙçlÌžëJgñw_üAþþK·´<·qy%K{ÝÀÀ‰ß›S7–Î`¦uI^\: SYp(£Q:€™^ÿâ=¥ŠØ·2ï|ÿç[žëïI6¯tͳa˪®Ò íÊÒÊÉ3À<«Õ«“\\ºƒ#ÎÚ½*?mSé €"Þõ¡¯ä‡÷îmynÇêjªo€Y1::–—•Î`¦z­Þðb"@Üæß«’ô–Žàˆ«^vzªnc€ô­›ïËïÿÕ?¶<·j ’Ëœ§ÀlÚµ®§tG{cé€NdÁ`Õêj’Ÿ.ÝÁÛÖä)ÝZ:`Þ5›É/ýÖg3yxª¥¹®j²}µë˜mc£ãÙ¼zié fze­Þ,Ðiœ@̯ŸH²£tGüü¥g¦·§«tÀ¼ûÐÇoÈWÿéî–綬¬¦·{‚ ã5³gséfLryé€NcÁ`~½¡tG¬ìË3Ÿ¸½tÀ¼ûуûókpmËsËú*Y?\™ƒ" IÆÇF³v…%÷6se­Þp 0,¸Ì“Z½±!É‹JwpÄ[.==KûJgÌ»_ýƒ/çÁñ-ÏíX]IÅu.Ì™f³™Çl[Z:ƒ™NOr^é€NbÁ`þ¼&IWé¦õõvå‚§ì*0ï®ÿνù“¿ÿvËs«+Zb»æÚ‰½YÖoŤÍ\Y: “Xp˜µz£;ÉëKwpÄÏ^tjV­XV:`Þ½ó¿}>SÍfK3]ÕdÛ*W 0&''óø]Ã¥3˜éâZ½±¶t@§p 0?ž—¤V:‚iÕjrÑ3N*0ï>ú‰ïä+7ÞÝòܦÕôvÏApL=ÙŸî.ߤÖFz’¼¦t@§°à0?ÞP:€#^ùÜÝÙ´~yé €yµwÿ¡üÇÿñå–çú{’ +\¨À|šØ gíðŠ{›ùéZ½ÑU: Xp˜cµzck¦_p§M\ú¯·ç×ÿçWs÷}ûZžÛ¾ºšªýv˜w«¦J'0Óæ$ç—ŽèÜæÞë’¸lO=s]Nݱ¶tÀ¼úÞíæùÍ–çV,­dd™£-(allov×Jg0Ó•¥:w€9T«7z“¼¦tG¼îÅ{J'Ì»ó;_Ì¡ÉÖ^}«T¦_oÊÙ¹¶§t3=·Voì(°Ø9™˜[/Jâ¹ð6±ií@žô˜M¥3æÕ?|é–|òÚ[[žÛ°¼’%½ssí²Z½±¢tÀbä¤`–Õê3’<©tÓvoÎãO«•Θ7ù»óïÞÛòÜæ•ÕôtÍA0+ÆÆöfwm tGô'yUé€ÅÈ‚;ÀìûéÒѸø´tuùãè £{æ?ÿáµ-Ï-éM6 Wæ ˜M;×ö”N`¦7Öê ‹)³Ìo¬³¨Vo $yEé¦-[Ò“§Ÿ³­tÀ¼yׇ¾’=¸¿å¹««©Øo€¶766–5ËûJgpÄ®$?Q:`±±à0».M2X:‚i?wÑž ô—Θß¾åþüáßÞÐòÜÊe•,_j»‚f³™Çl[V:ƒ™®,°ØXp˜%µz£’ä¥;˜V­&/¨ï(0oÞùß¾ÉÃS-ÍT+ɶծ `!9´o–öu•ÎàˆÖêM¥#§Ö³çì$g•Ž`ÚEOÛžÍëW”Θó¹›ó¹¯ÿ°å¹+*é `ΚœÌÙ»‡KgpD5É«JG,&ÜfÏJpÄËŸ{Ré€yqààáüÊ®iy®·;©­pM Q_ö§«Z)ÁWÔê -³Äo¨³ Vo %ùÉÒL;k×HÎ:eCé €yñÛýzn»šV{š IDAT{¼å¹m«ªérK ÒÄþyÌŽ¡Ò±-ÉÓJG,Ž®fÇK“,-Á´+/:-•ŠO)‹ßïÝ›÷ÿÙõ-Ï -©dõ óXÈÖ –.à_xué€Å‚;À츢tÓF†úòÔÇm-0/~õ|9&[žÛ¶Êr;,tccãÙ¹qYé Ž¸¨Vo,/°Xp8Aµzã¤$O*ÝÁ´«^zZ–.é-0ç¾qÓ½ùË«¿ÛòÜêÁJû-¸Àb°k]_éŽèOrié€ÅÀ‚;À‰{Ué¦uW«yÞy;JgÌ‹÷k2Õl¶4S©$[Vº€Åb|l4«—[ro#¯.°8Å8µz£+É+Kw0íÏÛ•õ«‡Jg̹¿ÿÒ-ùÂ7îhynÃòJú{æ (¢ÙlæÌmËJgpÄÙµzãŒÒ w€óì$JG0í¥ÏÜU:`Ξjæ?üþ—ZžëîJ6¸€Å¦yp"=]•Òáw€ä$àÄ\Q:€iç±6§íZW:`Î}äã7æ¦[hynóH5Ýn`Ñ9pð`ÎÚ5\:ƒ#^Q«7úJG,d޲¥Z½1’äE¥;˜öúZ:`ÎíÝ(ïþÈu-Ïõ÷$뇽ä‹ÕÊ¥ÍÒ 1’ä…¥#2 îÞeIzKGŒ õåÜ37—Θs¿ý§_ϽL´<·uU5ûí°hgËÚ¥¥38â5¥2 îÞ«J0íÊ OÍ’þžÒsêÎíÍïþÅ7[žì¯dÕ€ívXìNÞØ_:#ž]«76•ŽX¨,¸< µzãô$+ÝÁ´çœ»­tÀœûO¼6&[žÛ¾Úr;t‚{³¬¯«tÓ*ñx&À£fÁàѹ¢tÓ.xÒ¦lÝ8R:`N}ëæûò±OÞÔòܪJû-¸@'˜œœÌcw —Îàˆ+jõ†M€GÁož-ªÕ=I^^ºƒi/ÎI¥æÜ¯|àšžj¶4S©$[W¹€N²´û`*>ëÞ.¶%yZ逅ÈÉ6@ë.H²ºtÉú•KsεÒsê“×ÞšÏ|íö–çÖWÒß3A@ÛÚ»w"'o,Á¯.°YphÝ¥˜våE§¦·§»tÀœ™j6óïÿK-ÏuW“Í#® m]m—¢\T«7–—ŽXhœn´ Vo¬Íô îV­&Ïz¶ÒsêÿßoçŸ~pËs›Fªé  íeÅ`oé ¦õ'¹´tÀBcÁ 5/Oâj° \Xß–k‡KgÌ™‰“yׇ¿Òò\O²~yeŠ€… Ùlæ¬í¥38âÕ¥ îP­Þ¨$¹¢tÓ^öÌ]¥æÔûþìúÜ}ß¾–ç¶®¬¦j¿:Zujº´‹³kõÆ¥# îÜÙIö”Ž Ù¶~ Û³±tÀœ¹û¾}ùo»¾å¹ÁþJV º¼€N·ÿœ¹}¨tGxÅ Ü9¯··‰7¾dOzº»JgÌ™w}ø+Ù·²å¹m«,·ÓÖ ;'h#¯¨Õ}¥# î@­ÞèOrié’îj5ÏxÂÖÒsæŸ~pþäï¿ÝòÜÊJ†–¸¸¦ŽŽeê%¥3˜6’ä…¥# îÌ‹“,/Aré³·gíÊÁÒsæW~ïšžj¶4S©$[W:òf:mÓÒÒ ñšÒ …Ón€GæŠÒL»è»J'Ì™Ï|õö\}Ým-Ï­®dIï Ú¡ãéëé*Á´g×êM¥# î£VoÔ’<«tÉI›‡ó˜“חΘÍæôëíÍÖoOW5Ù4â¸8Ú¡C“yÜ®¡ÒL«$yU逅À‰7ÀÃ{e¦ÿ‚Iao¼pOºªþè§~â;ùÖÍ÷µ<·i¤±Ç3Ôw¸tG\Q«7,¿< ¿Qüµz£’äŠÒ$½ÝÕ<íì-¥3æÄ¡É©ü—}¥å¹ÞîdÃro3Ç7>¾7;7.+Á´mIžV: ÝYpøñÎK²³tÉO¿++—ûa Xœ>ø·ßÊí÷Œ·<·y¤šªývàaì\×W:#^Y: ÝYpøñü…²M¼øi>g,NûöOæ·þäë-Ïõ÷$k‡l·oßøX—ö”Î`Ú…µzcIé€vfÁà8jõF_’‹Kwœµk$§ïZ_:`N|à/¿™{˜hynóÊj*öÛ€G`jj*Û9X:ƒiƒI^P: Yp8¾ç$YQ:‚äu/:Õe-°(î=˜÷ìú–ç–ö&«˜\oå@ª0ÚÅå¥Ú™w€ã»¬tI_Wžú¸-¥3æÄû>úõŒî=ØòÜ–•Õ¸ŽZ±oßþœ¶Í+îmâüZ½±²t@»²àp µzc0É Kw¼þ…'gxpIé €Ywïù½¿úÇ–çú+Y9`½hÝÆ]¥˜Öä’ÒíÊ‚;À±½(‰­ê6ðü'o/0'ÞóÇ_˾ý“-Ïm]i¹xtöŽgxYwé ¦]^: ]Yp8¶ËJœ}òªœ²cmé €Ywû=ãùðÇolynxI%Ë—Zp©©©Ù.}öö¬\¾¬tÀ¬{ׇ®Íäᩖ綬t× ÌŽë{K'0mO’3JG´ îÿL­ÞØšä¼Ò$/zêöÒ ³î¿÷£üíç¾ßòܪÁJ–õYpflj½éëé*Á´——h7ÜfúÉÒ$ëW.ÍcOÝX:`Öý§^›©f³¥™J’-#Žó€ÙsèÐdÎÚ9X:ƒi—Öê Ÿ6øgœˆÌtYé’׿èäôtû{;°¸|ù[wå“_¹µå¹5C•,ñ­áÀ,[±´t٘䩥#Ú‰w€‡ÔêÓ“œ^ºƒäßR:`ÖýÚ¿œoO¥’l^é(˜}c£cY7Ò_:ƒi——h'NÅޏ´tÉSÏ\—í›V–ΘUW_w[®ùæ-Ï­®¤¯{‚’œ¶eYé¦]\«7|Úà!Ü’ÔêJ’ËJw¼üy'•N˜u¿öÁk[ž©V’M#Žñ€949‘®j¥tÉp’óKG´ 'ãÓž”dKéˆN××Û•'Y+0«þös7ç7ÝÛòÜÆ•ôtÍAÀCöï?=[Kg0íòÒí‚;À4¯··W>wg†—”Θ5SÍfÞõ᯴<×]M6®p„̽+|¾M<¿Vo,/ÐœŽ¯Voô$yié’ç?y{é€Yõ±OÞ”ïÜò@ËsµÕt;ÁæÁÞññ /ë.AÒ›äâÒíÀñ8@òÌ$«JGtºmëræIëKgÌšÉÉ©¼ûÃ×µ<×Ó•¬_^™ƒ"€£MMMåÌíC¥3˜vyé€v`Á ¹¬tÉë^tJººü±,ù»së]c-Ïm©Æ1 0Ÿ–tJÅçíÛA½VoÔJG”æˆèhµzci’—”î ©?nsé€Y³ÿàd~ã¿Öò\_w²nØm20¿öîÝ—ëJgT’\Z: 4 î@§{A’e¥#:ݳÏÙ˜ÍëW”Θ5ð×7äîûöµ<·i¤šªýv €ë{K'0íòÒ¥Yp:Ýe¥H.}Ö®Ò ³fÿÁɼÿc×·<×׬²Ý”q`boúzºJgœY«7ö”Ž(É‚;бjõÆH’ç•îètKûºò„36•Θ5ø·7äÞ&ZžÛ4RMÅ~;PÈ¡C“9kç`é ¦yÅèhÜNvQ’žÒîÕ/8)ƒËúJgÌŠçýûFËs}Ýɯ·…­XZº€‡\^«7ìwËo€@'»¬tÉóž´­tÀ¬ùðÇoÌÝ÷íky®6RMÕ~;PØØèXÖô—Î Ùœä¼Ò¥Xp:R­Þ¨%©—îèt»7ç´ëJgÌŠC“Syߟ]ßò\ow²Öëí@›8mË²Ò L»¼t@)ÜNõÒ$n {Ý OIÕÓdÀ"ñ‘ߘ;´·å¹Ú ¯·mdr"]+ÚÁ%µz£§t@ ÜNuqé€NW­&õÇm.0+&'§òÞ~½å¹Þ®dݰ c }ìß {¶–Î IòôÒ%Xp:N­ÞؘäÜÒîçmÉúÕC¥3fÅýý·óÃ{[½}ãˆ×Û€ö³qEWé¦yÄèHÜNô’Ò$—üÄÎÒ ³bòðT~ûQ¼ÞÞÓ•¬÷z;ІöŽg`Iwé ’—Ôê ÿ‡:Žw ]T: Ó-[Ò“ÇïÙX:`V|ô'·Ý5ÖòÜÆ^oÚÓÔÔTÎÜ6X:ƒdU’§”Ž˜o>Ùt”Z½±&ÉSKwtºW>wg–.é-pÂO5ó[ÚúëíÝ^o`–í;ØÌ¾ÉäÔôÿžj>ôŸÉáÃý³fÒUIú{’þžÊCÿ9ýß{ºJÿÐn†ú§J'0íâ$Ÿ,0Ÿ,¸æÅñíÅ=û [J'ÌŠ}ò¦üàŽÑ–çjË«érJÀ£Ôl&{4óàD2:Ñ̃û›™<üÈçœH’æŒV­Yzè¯d°?쯤ÛϯklloV÷åž”NétÖêÆmW¿§…ÿ/XØ,¸æ¢ÒnÍòþœyòúÒ'lªÙÌoýÉ×Zžë®&ë—{½€Gnª™Œíoft"yp¢™±ýÍžåǵ§š½0¹oï‘å÷%½Ó‹îƒ-½/ë­¤âÇÚÑÌž-Ëò©ë-¸¶.É“’|¦tÀ|±àtŒZ½±"É3Jwtº+žRzº}¯°ðýåÕßÍ÷n°å¹+¼ÞÀÃÛ(¹g¬™û÷63v ™fóágæÂÄÁdâ`3wNtU“K+Y=TÉÈRËî‹]õPé¦] î@q„t’Æ{Š{úÙ›J'œ°f3yÏ{½€Ù5y8¹óÁf®¿m*×~ÿp~𣩌î/·Ü~,‡§’{Ç›¹á‡S¹æ{‡sÓÝSh£@fÕøÞ}Ù¼fié ’‹jõ†}O cXô:ÉÅ¥:ÝŽC9eûÚÒ'ì¯?û½Ütë-ÏmX^I·«Hþ™©frßÞfîmæ¾}íµÌþp&§¦òï|°™¾îdõ`%k‡ªYÒ[ºŒÙtÒÆ%¹åî}¥3:ÝÆ$OHò…Ò!óÁ‚;ÐjõÆP’g—îèt¯º`wªU/” ߯ÿϯ¶<ÓUM6¬°ÝÀ´'š¹{´™739UºæÄ˜Ln»¿™Ûî?œ5C•l]YM¯í´Åar"•JÔ‡/©‹cÁèþ tŠ ’ø|paOyL­tÀ û›ÏÝœoßrËs^o`ßÁé¥ö{Æš909»¿öÀ’žœ}êÚœ²u$C}\Ò“Áe½\Ú“¥½\Ú›¥ýݹ÷‰Ür×Xn¹s,·Þ9–Ü9–[ïË?Ú;k-w6sïØál\QImE5]~^Ð&öÈÉ›sÃ-c¥S:Ýŵzãn»ú=>j,zÜNqQé€N÷Ø“VeÇæU¥3NØ{þèѽ޾q¹Û|€NÔl&?ÚÛÌm÷73¾ööRW÷çœ=ëò„ÓÖåœ=ërê¶•ézߪ¾}ãpÎÙ³î¨~ààáÜrçX¾ö{òÕïÎW¿}wn¸ù¾žztÍSÍäÖûš¹ëÁÃÙ²ªš5C•øÎ÷…kËêžÜpK銎·9ÉÙI¾\:`®Yp½Z½±,Éù¥;:ÝËŸ³«tÀ û»/þ ߺù¾–çÖWÒÝ5A´­©fr׃ÍÜþÀTö:ñ_¯¶fàÿ_fžõÙ¾q8•YÜïëíÊ®Í˳kóò\òÓwüûöOæ7Ý›ëþéî\wãÝùì×nÏøDkÿ2'ß¹k*?| ’í«+^bÍ}!:¸_º»+™œôxxaÇ‚;ÐümXôjõÆEI>Zº£Ó}ñ—dãÚáÒ'äü«þ"ßøî½-ÍT+Éã·u¥Ç‚;@G8t8¹ã©üðÁf&ŸØ¯U[;˜ Ÿ¾3/yÚŽì¬-ŸÀ°ÿàdþáK·æÏ?uS>qí­™œœjùרU•0«5T›NIK$­’ô¤é )ܬH´#(éjÓ9¼îš ˜ŽpZþ¸«KÜu"í} å–B…€‚18îè@ïì‹íËæUë ×­Ñ5.T P¸D[–´cÓ<]´¡M_ÿÉ.Ýòµ?j*žt}|Ò–ž:jki“Oõå”ÜsÝÈȨj*Bêž2Åë®wŒCë ÙVIÕ¦CxYQد³V¶šŽpZ>÷½'fµéíPƧ¤½¶ÆfWl?÷Ìf½þÚ3µå¬6Yêo>½úšUZ¿¬A¯úðÝêœp}¬#iÏ [á OEú"å%G«ç•iç“ý¦ƒxÝõ’>`:d GײëM𺛶/VyiØt €YÛ{xP¿úã‘´÷Õ–Y*e  kâIi_·­G%Ó.·û,KWž¿@w}òÝöWhëo•ÛŸoý úñ'®ÖÒöÔ3 GÚ}ÌÖT"KÁ0kŸéVD¢ËM‡€L¡à  E¢~I/2Ãë.Ý4Ït€Órë÷—í¤?¡/RíÑÖÛ‘:=|0©®!Gé¼+ ‡üºùòåÚùÅtë{.Öš%õË™O"åºããWéÂu©ï?•”v·5‹·âÈ¢ÑÑqµÖ›Žé:Ó S(¸(THâ]¢AÕåa­[Þb:À¬ïÓ;÷§½¯¢ØR9·S€¼Ô3â葃I쵕´g¾¯ª<¬·¾l~ÿÕ—é?Þxžæ7Wd.dž*/ éëÜ¡›/O=tz8æèÙž4¾ø0by„‚{¸ÞtÈ”€é!\¡hØ?^¾TáO3 }éŽ?+žHÿ„:ÓÛ ÿ Çèq4Kotx¤±\¯{ñjÝxÉR•qŽüT~Ÿ>ò†óT_U¬ÿõí?¹>îø£²"G¼ÇÎU>{R–%¦í›µ&íXÒ¹óÓ{M€¹Æ«*'íð‰‚»qŸÓf:À¬ MéÿþbwÚûJB–jJ9ùù"—öÚêM¯¥[UÖÛ_¾^7_¶\€/Cé “eIo}Ùz=sh@?yð€ëãöuÛ* ùTÆ]ÒrÒøDLKZË´§sÔt¯»NÒGM‡€¹Æ«+…h“¤fÓ!¼¬­±L«7™Ž0k_ÿÉ.NÄÓÞÇôvÈ [:Ðkë‘CÉ´Êí€O¯}ñj=ð¥õÊ«VRnŸ%Ë’>ñ¶ µ´½Úõ1Ž#=}ÜV<™Å`HË‚†é®72WX ÓÛ {ååKå÷óòÓT<©¯üè©´÷…R}9wÈu=#Ž>˜ÔÑGNƒÛ¯8oî¿õz½ïUUYÎ\@(- êÿë%*/u/IO&¤g{ì,¦B:“ã ø9bØY‘hÇÓ!`®Ñ>PP"ÑKÒ5¦sxÝ…ëÛLG˜µÛïÙ«ÞÁ‰´÷µTûdqNrV¯JKç×›Ž0+Ž#}áO¤½/à“š*h·@®êuô§CIõμ(ÝZ_¦Ï¼s«îüÄÕ:{ESÓyÛÅg·éí/?+åcöRpÏU-UÓ ½Èt˜kÜš«Lðº—ïX̤2·~úÐ<>œö¾æ*K~ޏ@ÎI$¥gºlí>n+>éíeÅA½û¿­û¿p½®‰.’“à×ñÒµÚvN»ëúรqJî¹(61¦ ŸßÃ6G¢L£PP8Ü Ð\i:€×m^Ýb:À¬Ýú½ô§·û,©¥ŠÃíkúÇNNmï™Y1ÚgYú‡ËÎÐo¾t£Þ|Ã…˜L->ËÒ-o>?å×ü`¯#*î¹'OhÅürÓ1¼Î’t¹é0—8â `D¢5’Î3Ã˶”ké|.ùé¡'Žëñ½=iïk¨°ôg `V¶´ç„­]ÇlMÍpjû–³"ºû³×ê–7¯ºªâÌÄ´kJôš¯r]›tÔ=LÅ=µTq1H`((€‚BÁ@!¹T§ ºiÇYÜš ä©Ï}ïñYí‹Ts¨rÅÀ¸£G%g\„®«*Ö—ÿu›¾ñ¡Kµ´½:Ãép*o¼nj*Š\×÷Ù²é¸çœÉظ~ú"†íˆD;B¦CÀ\á¨;€Br•é^wÞšVÓfe×~ýúÑδ÷Õ•Y* f  -I[Ú×më©£¶&3Ûsõ…‹ô«[¯×öMó23VVÔÛ^¾Þu}2!¤ážk¦¦âZÞ^f:†×•KŠšs…‚;€‚‰v%]f:‡—µÖ—ꌅõ¦cÌÊ­ß\Î,ÎGj˜N¦ M8zôpR]C3{cWSQ¤[ßs±>û®­ª.g8ÒuÓ¥gh~s…ëú‘~[ñdaFZj˜  `PpP(ΓTi:„—ݼc‰ü>žV@þéìÕ]¿9ö¾ªKea î`ŠíHÏöØz²ÓV,>³=—nž¯{?w®<AfÃaÖ‚ŸÞóg»®'méè€ÅD˜‰Dl\~ÇI »*íà›  ÐDP(¸Ѱó×µ˜Ž0+_üá“J$Ó?1©æ|!˜26éèÑCIœÙÔöŠÒ>ýŽ-úâ¿\¢ºªâ §ÃéºüÜZ·¬Áuýİ3«;±!s&§â:£­Ìt ÌDíŸ IDAT¯›/i¥é0(¸(Wšàe UEZ±¨Ñt €´ ŒLê¶»ŸI{_iØRU w0¡oÔѶ&f8µ}ë†6Ýû¹ëôâ-‹eñV./X–ô?^yŽëz<)õÓpÏ5‘º é`H(€AÁ@Þ‹D;–JZj:‡—ýÃ¥K øMÇHÛ×~ü”Æc‰´÷1½Ì8Òïèéã¶fr#®²â >Þq¾þjª-Í|8Ì©«štÁºV×õîa î¹&99!W‘˜FÁ@A à 0½Ý° ×GLGH[l*¡¯Ýµ+í}EA©®Œ“µM¶#íî²u¨oÍvIç¯iÑÝŸ½N/ݾŒ©íyìeÛ—¹®õ9Š'³§›œÒ²¶2Ó1¼nS$ÚÑ`:œ. î WT]Öê%¦c¤í;¿Ü£þáXÚûZ«|”# ‹&ÒGlõŽœzbwq8 ¼á\}ë×)Ò@Ñ6ßmß8O¥¡i×Gê™Áϲ«½.h:‚×Y’.7Nwy-í¨’té^vÓöÅ ¦c¤%i;úŸL{_Ð/5VÒn€l‰9zìpR£“§.2Ÿ½¢IwæZ½âŠòqerA‡üº&ºÈuýÄ0÷\“ŒÇøý3a¡òwùîRI~Ó!¼lËY­¦#¤í®ß<«Î#iïk®òÉÇ9ZÈŠîaGOtÚŠ'OýØ×¼hµ¾ûÑ+4¯¹"óÁU/Ù¶ÔumlÒ™ÑÅÈžXlR‹[KMÇðºí‘hGØt8Üä»+Mð²Òâ Î\Úl:@Úþ÷N{eIÍLo€Œs$ìµµç„-çÝå`À§ÿõÖ õþWo”Ÿ+’ Ò™‹ëµ¤½Êu½›)î9g~=ÝjÃÊ$EM‡€ÓAÁ@ÞŠD;’.7ÃË^¾m¡Š‹‚¦c¤å‘ÝÝzlOOÚûÊ-¹— dT–v³Õ9pêÒr]U±n¿å Ýp‰û„oä?Ë’^rÉ2×õîG6÷œâ$&dq½‰iW™§ƒ‚;€|¶YRµé^vñÙí¦#¤í˳˜Þ.I-Uœ™€LŠÅ¥'Ž$50vê¶òÊ…µºë“×hÃòÆ,$ƒi×n]ì:¡?‘”úgð3ƒì™ˆMjQK©é^wU$ÚÁÁ,y‹‚;€|Æ•†…ýZ»¬Ét €´tõég¿=˜ö¾ÊbK¥aÎ @¦ Ž;zìpRãS§~ì•ç/Ð>v•ZëË2 9¡¾ºX[7´¹®wSpÏ5 ¦#xÝý >G'KîÈã1-h*1Ãë(¸È[Üä+¦· ø´îŒfÓ1Òòýûöj`d2í}Í•>Ñ€¹÷l­ÎS—’[ëËôÃ_¥ËÏ[…TÈUÁ€OWž¿Ðu½Ÿ‚{ÎYÔTd:‚×mŒD;L‡€Ù à _q…¡A/ŽÎWEoB@~ùÊžJ{ß'5VRo€¹¶¯ÛÖ±ÁS’Ï^Ѩ»>yV.¬ÍB*äºí›æ¹® Œ9rè¸çËž2Áë,IW˜³AÁ@Þ‰D;*$EMçð²Ë6»¿aÈE<~LÏH{_C¹¥GÒ`Î8’öž°Õ5tê&òK¶-Õw>r¹êªŠ3 yaóêf•¦]KØÒpŒ†{.ŸP{#¿¿†1D@^â°<€|´CÒôïVqŸOëW4›Ž–¯ÜùçYík©â0:ÌÇ‘ötÙ:1œº„ì³,}à5›ôñŽ  ú³”ù ò+º>âºÞ7JÁ=×,i¦ànØöH´#l:¤‹#óòÑ•¦xÙ•ç·©º¢Ät €;t|X÷þñHÚûªK-‡2<Èq¤gºlõŒ¤. ‡‚~}ù}ÛôêkVɲ²yeÛ9í®kýcÜsM@S¦#x]©¤-¦C@º(¸È+‘h‡_Òå¦sxÙçÎ3 -_ùñS²ôOp·TѤ€¹à8Òî.[½§˜®] èkØ®KR˜‹Înw½ø!—ÆéSç”±± µ50Åݰ«L€tQpo6Jª3ÂËÖ,k2`ÆF'âºýž=iï+IÕ%Ü`.ìë¶ÕwŠr{IQ@ßø·º`mk–R!_ÕViÃòF×u¦¸çž¥-Ü »*íà@€¼BÁ@¾Ùn:€—m\Q¯æú Ó1fì¶»ŸÑèx<í}-U>€¹p°×Ö‰áÔ…ã²â ¾ùo—iÓªæ,¥B¾K5å¿ÿS ûBVÂt¯k—´ÚtHGèä î½8ºÀt€sé«?Þ•ö¾€Oj(g¨œ®cƒŽ:R—+JCú¿¹\g¯pŸÈ ü½mç¹® ÇÅ“Y ƒSWuyÈt ¯»ÊtHwy#í¨’´Ñt/;ky“é3vÏéÐñá´÷5UZòsôNKψ£g{씩.ë¶ÿ¸Bk—Ög) ÅâH•æ5»ß¾Œ)î¹ÅÑò¶RÓ!¼n‡éÑÈ'‰¿[Æ4×–hÉü:Ó1fìË?zjVûš«8§cpÜÑž©Ëí¥!ÝvËZµ¨6K©PH,KÚ¾±Ýu}pœ‚{®©*6Àó6G¢îW…@Žá(=€|²Ýt/{É% å÷ñ´òÃ3‡ôÐÇÒÞWWf)È@ ðˆÑ˜£§ÛrRô‹Ã!¿¾öZ>¿&{ÁPp.9gžëÚð÷\366¦PÞ‰AI[L‡€™â@^ˆD;,q«£Î;³Åt€ûòþœ²Lᦥʚû0౸ôÔ1[ÉÃÛ}–¥[ß}‘Î^ј½`(H–7(ôO»6™8ùóˆÜ‘L&µ¼½Ìt ¯c¸(€¼AÁ@¾X$i¾é^ ø´z @~™ÔïÛŸö¾²°¥Šb î0I[zú¸­x2õãþç?¯mÝ'o3 úµvi½ëúpŒ)¹ŠÛæFÁ@Þ à _ðË k.˜§Ò’°é3òÍŸ=­ØT"í}Lo€ÙÛsÂÖØdêBñ»^±A/ݾ,K‰àW5¹® OPpÏ5‰©˜,¿˜´$íX`:Ìwù‚‚»A—œÓf:ÀŒ$’¶þÏOžN{_Ð/Õ•s†fãPŸ­¾ÑÔeâW^µRo¾am–Á+6®t/¸QpÏ9±Ø¤4•˜ŽáuÛL€™ à çE¢AI™Îáek—¹¿!È%?}ð€ºúÆÒÞ×\iÉG¿ÒÖ;âèHê"ñU,Ô_»‰É͘sgÑ(ŸËÖÄ”Of9Ni~c‘é^ÇQy‚;€|pޤrÓ!¼jÃuji¨0`F¾ü£§ÒÞcYRS‡Ë ]£“Žöœ°S>fíÒz}òmQ×2p:ÊJ‚Z¹°Öu}˜)î9'd%LGðº‹#ÑŽ€ép*±¸rРk·,0`F}¦[ÚÝö¾úrK!@›JJO³e§è7Ö”èËÿºMaÞt!ƒÎYé~Wú! î9gttL5!Ó1¼¬JÒÓ!àT(¸ÈÜ Ú°Üý @.ùúOvÍj_s%S ¶s²Ü>™bs8ä×WÞ·] 5%Ù O:ge£ëÚðDƒ`Æ–·•šŽàut±ä< îrZ$ÚQ-éÓ9¼ª±ºHKç×›ŽpJƒ#“ºëiï+ [*/¢àéØ×mk$–z2ö'Þr¡Î\R—¥Dð²TÜG'%í,†ÁŒT™NàyÜä< îrÝEâo•1/¹d±ü~¾ü ÷Ý~ÏMN%ÓÞ×ÄôvHËÑGÝéËíÿtãZ]]”¥D𺺪b-l­t]>ÅÅȾ±±1…‚ôQ Ú‰v¸ÿÒ@àY@®ãŠAƒÎ[Ól:ÀŒ|ëç»ÓÞã÷IõåÜ`¦ÆèM={ÛÆyzÇÍge)pRª)îÃÜsM2™ÔŠörÓ1¼Ì/i«é w9+í°$í0ëBŸV/q+xü˜ž=:”ö¾†rKܼffbJÚÝ•ºÜ¾l^µ>ýŽ-òY\LŒìڸʽß0:™Å ˜±¦*¿é^ÇÐQ9C÷rÙbIóL‡ðª+ÏkWyiØt €SúæOŸžÕ¾¦J 0 [Úu,©dŠ~{uyX_}ÿv•³ ø‹õË\×&¦˜àž‹S1q-ŒQÜä4 îr/¤ Ú¾±Ýt€Sê˜Ð/~(í}E–JÜE€Sq$í>nk"îþ˜€ß§/üË%jk,ÏZ.àùÚ›Ê L_…‹Å•òâ ˜‹MjaS©é^¶(íXd:¸¡à —m3ÀËÖ¤¸º W|ç—Ï(‘Hÿ,uSåv˜‰Ã}¶ÇSOÀþ·×oÖæÕÍYJ¼PÀïÓÂÖJ×õ‰8SÜsÑüưé^G7 @΢à 'E¢AI™ÎáUë–Ô(ÒXe:@JŽ#}û»ÓÞðKueÜàTúÇéO] ~Å+tóe˳”p·¤Í½ç01•Å ˜± •âÖȆí¦€ îrÕFIÜ»Ìk·.4à”~õðuv¦½¯±Â’~;¤‹K{ºRß1ëÜ3›õ¡×lÊR" µÅ) îãSLpÏE££ãª­™ŽáeG¢Ó!`:Üä*®4èìÜ:ä¾oþìéYíkªàÐ8¤b;Òîã¶)úííMåúü{/Q À{,ä†TÜÇ™àž³Îh+5ÁË*$c:L‡W˜rwCê*‹´lA½é)ëÓ}I{_U‰¥bƒ@JÏöØtŸxùõ¥ÿ±MÕåá,¦R[Ò^íº6Á÷œUYÄ÷Æ0:Zrw9'í¨‘t¶é^õÒK)àçéä¶oý|·’vú'@›*­ ¤€ÂqbØQ×Pê÷[·¼é|­XP“¥DÀÌ,l©”Ïšþ}ÿD\rèQ礱±1…ƒ~Ó1¼Œ‚;€œDƒ@.ºHü}2æÜ3›MGH)i;úÎ/ŸI{_Ð/Õ–Rp7c“ŽöwÛ)sÓ¥g膋—d)0sá_mMåÓ®9Ž‹g9f$™´µ¢½Ìt /Û‰vT™)€\Ä•†ø|ÒŠEõ¦c¤ô‹ßTwÿxÚûš*-¹ rÏKØÒÓÇm¥ºYÖêÅuúÐk7g/¦%mî=Ýñ)F¸çª†*&¸äÓÉa¤S(¸È)‘h‡% îÆlZÙ¨ÚªRÓ1RúæÏvÏj_c‡ÄÀÍž.;å„ëʲ°¾øÞ‹QDEîZœ²àžÅ HKr*ÆP³èjÈ9ÍkKšg:„W]¾¹Ít€”ÖƒK{_u©¥¢`@èpÔ?–zºõ§ß±E‘Æò,%f‡ îù)›T¤¾Øt /Ûñ—¡¤3(¸È5[Lð²µËMGHé›?{Z¶“þ éæJÎÑÀt†&ìµS>æ-/]§‹600 ¹/UÁ}‚ î9mA#wƒæKZd:<w¹&j:€W•„ýZ6¿Þt Wñ„­ïÞ³7í}áÀÉ î€¿5•vO]n¿`]«ÞöòõYJœž%mÕ®k±8ÜsYY(õß"dÜvÓàù(¸È¹ÕÍÓ9¼êªóç©(0ÀÕ]<«þáXÚûš*}¢ÞË‘´»ËV<éþ˜–ºR}æ[å÷ñ® ù¡¬$¨òÒдk [šÅMá%ccã úù[cw9…‚;€\²PR«é^µe=_zÛ¾ñÓÝiï±$5Vprþ^g¿£á ÷¶o àÓçß{±j*в˜ 8}©~f ÏYÉdRK#e¦cxÙ…‘h}R9ƒ?HrIÔt/[µ¸ÞtW{èá§»ÒÞWSf)ÄMëàoŒÄîKÝôýà«7iݲ†,%æNuyØu-Õ `^sMÐt/«–´Útø/Üä’-¦xÕ¼¦RÍk©1ÀÕ7~úô¬n#Þ\Éôvx¾¤-=Óe+Õ[¬mY¤W\±"k™€¹”r‚{r5%LGð:†“ÈÜä„H´Ã/’Œyqt,Îõ€51™Ð÷ïÛ—ö¾¢ TUÂAx¾ýݶbq÷õE‘J}ôÍçsy«º‚ îùjtt\UeLq7ˆî€œAÁ@®˜/©Ýt¯Ú¸²ÉtWwîܯ‘±©´÷5Urž¯gÄQ÷ˆûë@À§Ï¼ó"•Q0EþJ5Á‚{®s´´µÔt/»ð/CJÀ8ŽîÈ\hˆÏ'-_Xo:€«oþlwÚ{,Kj¬à|ü—X\Ú×m§|Ì{ÿÛÙZµ¨6K‰€Ì¨.w/¸'Rÿ Ô”Qi4¨NÒ Ó!@¢à wl1À«6¯jTmW¿€Ü´û`¿žØ×“ö¾ÚRKA@ré™.[ÉåÞ ÖµêÕ/Z•½P@†T§œàî~ä†ÄTL3 LÚb:HÜä&¸rùævÓ\Ý~Ï9³8÷Ìôvø«#ý¶Fbîo®j*Šô©·Eå£UŠP]v]K$³³‹Mª­¾Ät /£Ã 'Pp`\$Ú1OÒ|Ó9¼jí²Ó¦•HÚúÁ}ûÒÞ HU%”2@’†'îO}åðÿ÷– ÔPC¡…¡&å÷,Á¬-htÿ"㢑hÖGÁ@.àÊ?CJÂ~-›_o:À´îýãõ ÅÒÞ×Pnq+k”°¥gºì”¹ùòåÚ¶q^–™W]Î÷|WJýw Õ i™é@Á@. ànÈÕÌS80`Z·Ý½gVû+8ô ’´¿ÛÖdÂ}}I{•Þ÷ªÙ dAÊ îvê» 7Œ+àøŽAt¹dz€\°Åt¯Š®k5`Z½ƒºï‘#iï+/²TÊ@ È3=#ŽzFÜ˼Á€OŸ}×E*3 …¥:UÁ îy!™LjY¤Ôt /£àÀ8 D;Ú$-4ëV-®7`Z?¸oŸ‰ôoGÝXae ä—©äÉéí©üË+ÏÑòù5YJdO0àSYqpÚµDRb†{~h®žþ{ˆ¬Ø‰vp €QܘƆ,h.Ó¼V€ÜtÛÝ{ÒÞ㳤úrνÀ³Ý¶R]3¼å¬ˆþûÕ+³ȲªSÜ“LqÏ >'n:‚—5KZl:o£àÀ4 è²8ß rÐã{{´çð@ÚûêÊ,ù9ê ÀãzGõŽºÏ¨®­,Ò'ß•Æ(`å.Ü%)É÷¼066®ê2¦¸D§ €Qê`ÚӼ꜕¦#Lk6ÓÛ%©¡‚roK$¥ýÝ)F·Kúø[.T]Uq–f¤ê°sô ,”šŽàeÜEÁ€1‘hG‹¸>Ÿ´rQƒé/0OêG¿~6í}á€TUÂ)jÞöl­xÒ}ýÚ­‹µíœöì ±íwäšRêE#Ñ~[Ã3“¸ÒÏóV5©º²Ät €øÅïiht2í}LoàqýcŽºGÜK½uUÅúàk7g1`Nª‚;GòÇÔä„,¾a¦´IZ`:ï¢àÀ¤-¦xÕeç¶™Ž0­ÛîÞ3«} îà] [Ú×m§|̇ßp®ªËÃYJ˜e;)&¸#oLNN©½Ž1¼€1ñ`/‚ Y»´Át€8Þ;¦;šö¾ÊbKEÁ €_o›àA¶ãþ»ÁïDþiª šŽàe[LàMÜd]$ÚÑ(i¹é^ ø´¸½Ît €¿11™ÐO8ö¾âTQÌYiÞãHÚßzBõ¿¾j£Zê˜z oJ2Á½ ¬¤é^ÆSFPp`¦xÕ%ç´ª¸ˆ«Z@n¹ëˆ§½¯±œCܼ©kÈÑØ¤{÷¼5-zùŽ3²˜È-vŠ‚;—Ê矱±q…ƒ~Ó1¼jQ$ÚÑj:ïáè?Î5À«¢k[LGxÛïÞ3«} œ’à=ñ¤t¨×v]/ô±º@o™àaŽ“¢àÎïFÞ±m[KZKLÇð2¦¸È: îLØl:€W­\Tg:Àß8Ü5¢?<Õ•ö¾êK¡@@Ž;Ôg+áÞo×?ßt–ڛʳÈA©&¸#?5UMGð2 ‚;€¬ŠD;Â’Ö›ÎáE¡€OKÚkMÇøß½wìSÕÜ42½€N:êrµ¸­J¯ºze¹‰~{á ú’¦#xwYGÁ@¶­—2‹.ÚТ’b¾ô w8Žô½{÷¦½/à“jÊ(¸ðžýÝ©[»ÿöºÍ ¨nÓs4!+äï›!Ë"ÑŽFÓ!x ñdÛfÓ¼jËÚÓþƃOSg÷hÚûêË-ù8# Àcº‡ÄÜ î—;_¬mÍb" w9n#Ü9ž·lÛÖâ–RÓ1¼l“é¼%`:Ï¡ànÈÊÅu¦#üÛïÞ3«}œà- [:Ðk»®‡C~½ÿÕt½¦³{TÚ}BìîÖÓú5Oªµ¡\ [+´|~¶nhSqØ›õ°xrúߎ(ä·æê v2³6KºÓtÞáÍW0L¢àn@ÀçÓ’öZÓ1ž31™Ð/~w0í}Å!©¬ˆÓѼåHŸ­xÒ}ýÍ7¬U¤¡,{`ŒãH?{è€>}ÛczêÙ¾¬?²»û¹ÿ»¼4¤·¿|½þñÊ ø}ÙŒiÔX,®É©éaÞù2¤ßýBdWQÈ*ž²dM$ÚÑ&‰û¡°e}“JK¦c<ç¿=¤ñX"í}õåÖà-ãSÒ±!Çu½­±\¯¿nuÁ”ß>y\WÿózÝ-÷N[nÿ{#cSúЗ~§«ßþ£=¾PôL¸®\4ŸÏÆÇÆôó=4äìH´ƒÊ²†3²‰éí†\´ë @n¹cç¾Yí«/ç$&oy¶Ç–ãÞo×_³IE!:‡…lpdR¯ùÈ=ºñ½?Ñc{zÒÞÿäþ^½ø?ÖCOÏ@ºÜÓ;s] ú³s.™´µ¨…»UR"‰«©d wÙDÁÝU‹ê)R5 IDATLGxÎÀȤv>z4í}eE–Šƒ9ªwÔÑà¸{»}ËYmÛ8/‹‰m»öëò·Þ¡Ÿÿöài}œ‰É„^wË=:rbdNrå²ÞA÷ î! îy¯µ–ƒCÑý5Üd/r ø|Z2‚;Èw=ð¬ ;í} Lo€¬q)ž”Ƨ¤‘˜óÜ?£1G£“ŽÆþòÏø”£ñ)ibJŠÅ¥Yüy.G:Ôëþäøô¡×n–Å[¥‚õÓèšwühÎJéƒ#“zÕ¿ß­ñXbN>^®êp/¸¹ÙAÞ ûyÓaÐ&ÓxOÙ²"í(’´Þt/ºpm“ÊJ¦c<çŽû÷Ïj_]­ 8]‰¤4wþRHwOžüoñäÉrz"é(aKÉÓèŒø,)è—BK!ÿÉÑÉ[ ¤’¥"†.pJ'†MÄÝ×_sÍ*-l­Ì^ dMد÷}þ!}â­ÎùÇΩ&¸ý[Èwccã ,%îw·@Æ0Ü@ÖPp-ë%q¸Ú€­ZLGxαÞ1=¼ëDÚûªJ,…8¢ 3b;ÒÄÔÉBÜÄ”4ñ—BûDÜQ"™Ï?™&_P8ùëÿï÷,º—†ÿúïÒ¥€?óùȶ#îw¿â¬±¦D/]—ÅDÈ–'÷õêíŸúµvìŸÑãC“w<++²ðIcSÒñA[±GÜ~ϽîÚÕZÚ^=G©sKOŠ‚{ˆ×›y/™LjaS©ötŽšŽâE‹#ÑŽºÎŸî5@áãt€lá >CV/®7à9wîÜ/ÛIÂV}9ÖÀÍTR™p4s4ö‡õ…<9㻵V[š_ë;åë Ÿ%ÑìÓÓÓÞÝ'i;úüŸÔ‡_î,’ç¶Þ÷Ÿ…`||B¿¥D2Ço]U˜è€È ^íȆ6I-¦CxÑÅgµšŽðœ;îß?íIõS©/çä3ï‰Å¥cƒŽþ|ÔÖï÷'õL—­ÞQo•Û§‹K'†=uÌÖï$µ¯ÛÖà¸#j-€BOž| àæÌ%uºìÜYL„L™œJê¿ønÝúý'fTn÷ýe*û‚ºS—ÛÿK8 5¤xOý½{öj*žâjŠ<Å÷—H$4¿©Ät ¯:'íà7 @Æ1Á@6påž!g.®7à9wìÜŸö¿ïäwð‚ÑÉ“SÚûǤ±Is•mŸe©ª<üÜ?•eaù}–lÛ‘í8JÚŽûä¿mÇ9ùßmG±©¤z'Ô78¡¤ùü‰¤Ô5ä¨kÈQÐò‚¨ºrKE2£Ç—…--i´TNÿ›©öéÄðô%ö±X\¿ªK¬-œáySñ¤FƦ¦] øÄïO‰Ô†µïè˜é^T&i¥¤'LPØ(¸È îø|ÒÒùu¦cH’ÙÝ­#'FÒÞWWfÉÇÉgl*!u;ê¶‹gþóU–…µ(R©E­•ZÐZ©öÆrÕTýµÐ^ViIP¾ÓhþØŽ£áIõ Œ«gpB=êœPWߘž94 Ý‡ÔÝ?>‡ÿ«þ:íöØ srRi…¥¦JŸÂœ ä‘É„t|Èý"±óÖ´èü*"{ÕT<©×Ýr¯~5ƒr»eIí5>Eª­Y³‹CRm™¥¾Ñé¶î{¸³  î½C1×µ ¯ JIÐã··2k“(¸È0ž¶dw6¯jTEY‘é’¤;îß7«}õ)n¥ùÊq¤ñ““ÇÆebÖy¤±\«ÕjQk¥¶Vja¤J [+U]ÎÀgû[>ËRme‘j+‹t†Ëcú‡cÚ}p@»ök÷¡~í>8 gõk<–8íÏ?™Žô;êìOª¶ÌRs•¥ÊbžO¹ïpŸ-'Å ƒw¿bÓ§ó\¶¼èäÔö’ÐéÓkKSÜ9¢÷¿zãiŽ\Ñ;0áºòó TH&Æ'ä÷YY¹{^`³¤/š °QpQ‘hG‘¤u¦sxÑ% ç kß’¶£»8ö¾ _”‰¸tbÈV÷°£©äÜ}܀ߧU‹juöŠFµ¼Q–7ª±¦dî>AÔTéÜ3›uî™ÍÏý·¤íèÏû{õÀcÇôàÇôǧN(65û»#©wÔQ﨣Ұ¥æJK ܛƧ¤Ãî%Í›æiݲ†,&Â\K$l½á£÷êîßJù8Ÿ%µ×úÔZ5û©í¯ºÔýí;2¨ÎîQEÊææ“Ö3è^pú³O$4¿©Dû™ŽâE›LPø(¸È´õ’‚¦CxÑÊ…u¦#H’xì¨zSœ`vS_>w'óÀÇ‘úFr4417“K‹‚Ú|f³6ü¥Ì¾fiŠBùÚÏï³´fI½Ö,©×›nX£©xRìîÖƒÓƒÓ£ÏtÏz:ãØ¤£}ÝŽöIM–š«| çÿ— P@÷Ù®k–%½ë²˜s-‘°õÆýJ¿ø]êr{È/­ŠøædjûóýRYØÒèäô¯¥vþ©S7]êvïüÒ7”¢àÎë¿‚ÓV¦ànÆ‘hGMçÎO÷› pñ´ Ó6›àU ÛªMG$ÝqÿþYí«/§Ý ÙŽÔ=ì¨sÀV,~ú¯©¶TÛ6¶kǦyÚ¼ºY!ŒŸ ýÚ¼ºY›W7ëÿp–FÇãº÷‡u篟Õ}Q"á^t“HJŽŽ$ÕXi©­†¢;À¼ñ©“wqsÝÖ%ZÚÎùß|å8ÒÛ>µS?{è`ÊÇýÒªˆ_%¡Ìä¨.•F'§_{êÙ¾Ì|RzÜ î!?Ç Mqhn."Ƭœ#éç¦C(\®iÜ XÐ\¦ÆÚrÓ149•ÔÏw0í}EA©¼ˆÏòOÒ–Ž9:6`k*yzkùümß4O;6ÍÓªEuž¿«EYIP×Déšè" Nê¿;¤ýúY=ðØÑ´'»;’º†Nª©ÒR[µO0§:ÜŸÇŸþù¦õYLƒ¹öõŸì:å…ßA¿´:ƒåvIª,¶tDÓÿ¬í=<˜¹Oœe©î çkD='61.ŸeÉv(º°YÜd‡idL$Úa‰‚»Ûω˜Ž Iºû‡5:žþèb¦·È7ñ¤tlÐÖñAG³,þœ3—ÔéÚ­‹µ}ã<µ52ÈÄMeYX7^²T7^²T}C1ýô¡ºsç~ýþÏ]i}Ç‘Ž::1”Ts•¥Hµâ «&Rψ{1ó.=C^ä­]úõï_þ}ÊÇœ,·û2Zn—¤’ûûì½G2ûɳ¨'UÁ¦\Á‰Çjo,ÑÁ®1ÓQ¼h“é OÛ2©MR‹é^´vi½é’¤;îß7«}õå¾9N™1™:lr”æñçT–…uÝE‹õÒíË´|~ÍÜô€ÚÊ"Ý|ÙrÝ|ÙríëÔ×îÚ¥ïÞ³Gã±ÄŒ?†íHGu %ÕRe©µÚ§OE€,8:`Ëmðp àÓ›nX“Ý@˜3ã±„Þø?ïÕTÜý¶>¿´ªÕ—²|>WB)àÓ´cö ÅÔ7SmeQÆsdZç‰×µ2¤Hm˜‚»#Ñ_çÎOŸÆ%ÞàŽ‚;€Lbz»!KÚ«MGÐÈØ”î{¤3í}¥a+ã“ëàt%méÈ€­c³/¶Ÿ¿¦E/Û±L;6ÍW˜¶ÍœX©Ò‡_®Þ}óÝ~ï}íÇ»tðøðŒ÷'méH¿£ãƒIÍ«ó©©Ò÷dJ")u ¹¿¸nëb5Õ–f1æÒû¿ðöw¹®üÒêVŸJÃÙ{µQ²4›þgnï‘ÕV6g-K&8Ž´çÈ ëzQWv…¨<ÿ¯ËÈW•’δËt…‰‚;€L¢àn@8ä×üV&üó~òà”“êÜÔ—sÂ@îr©kØÑá>[³ø§¦ÚRݸm©^rÉRµ7•Ï}@H’ÊKCzÕÕ«ôÊ«VêþG:õÕ?¥ûÓ¸è*aKû»m²´¨ÁRyÏM€¹w,Å`,Kzýugf7æÌ;÷ë¶»÷¤|Ìòæì–Û%©$$Ħ_Û{xP›VåwÁ½{`\#cSÓ®ý'ÿAáI&¦ÿž#+6‹‚;€ ¡à “(¸°em³Â!þ¼óîØ¹Vû(¸ÈUýcŽôÚš˜EbI{•Þxý½èÂE |sÓòY–.ÚЦ‹6´i_ç þÿï<ª;wî—3éû£“Ž?⨩ÒÒüZŸ”¢s$iKÇm×õ›ækq¤*‹‰0WÖ{>ó@ÊÇ´×Xª,Îþ{ß’%iúB‡ºf~×›\µ7Åôö“ÿÛQˆÆÇ'TVÐèDÂt/Ú$é˦C(L4 dD$Ú”´Æt/:÷ÌFÓÔÝ?®ß=y<í}•Ŗ¹cF'èq441ÃVôó¬[Ö 7ß°F—ll—Ï¢TcÒâH•þó[õO7®Õ'¾õ'ýôÁ3ÞÛ5ä¨w4©ùµ>5Uò}œ¾ÃŽ)îóÆë™Þžâ [oúØ}ˆ»>¦¢ØR[™ ÃA÷µþáÉìɽ‡\׊CY ‚¬[Ô\ªÇŸ2Ë~ c8M SVH ›áE+ÔšŽ ;ý¬’vúEP¦·È%SIé`­î‘ôÿž]¸®Uo¾q­6­j½öܲ´½Z_xïÅúóþ>}â[èž?žÑ¾DRÚ×mëİ¥E –ÊÂ|c³ã8ÒÑ÷éí›W7kݲ†,&Â\ùø7Öã{{\×>iY“ÏØëÃ`Š»ÑôMd/H†ì=Ìw¯ª«àVK†¬ˆD;*;w~š« Ì9 î2å,Ó¼ja¤ÚtݹsÚ{,Kª+ã„3€ÜpbØÑ[ ÷îÙ X–tÅy ôÆÖhõ¢ºÌ…ÜXµ¨V_}ÿv=úL·>þÍGô›GÎhßHÌÑãGµ×ø©±Ä3 ]=£Ž&îëoº›¥ç£'÷õêó?x"åc–4ùŒÞµ,èwåRܤ*¸g1².äKãæ’%éIw› ðPp)Ü XÐ\¦†ÚrÓ1€ÇužÑûÜ'Ö¹©*¶`àÃbñ“SºÇÓ›Ú~þšýë«6jåBî²™oÖ-kзÿý2=ðø1½ïÖ‡´¯Ó½õ_G:Ôgk`ÜÒÒFŸŠ‚Y (ýî¯3V.¬Õ…ë"YLƒ¹à8Ò¾ø[9)^B6WYª-5{i\Ê îñìɽG\טà^Øb± ù,Kvª_BdÊ&Qp>Ó¬õ¦xÑös8ÐÌûɃSžÔwSËôv9ŽttÀÑŸ%Ó*·/i¯Òÿùà}û×SnÏsç¯iÑ/?s­Þûg«x†£U‡'=z8©Ãi3Ó?æh|Êýyãן)‹·Fyçǿٯ?î:áº^¶´ Î|M+"BßÐDö‚d@ÿpL}CÓ—ôý>)ÄØ‚'©/6ë6™ 0™å àD¢IÜ3Í€µKëMGÐO:0«}ܘ26éèñ#¶ôÚ²gØS®«*ÖGß|¾~ùŸ×jë†6Šh"ðéׯÑ}Ÿ¿^—;F{’¶´÷„­§ÛJ$3›ÿޏ¿Øhk,×åç-ÈbÌ…‰É„>ü•?¸®û,éŒ&Ÿ|9ðzѲäzç´Ññ¸â ;»æÐ¾#îwáaz»7Dê¦#xCPdw™p†$.‹4`I{µéÀãºúÆôØ3=iï«,¶RÞ*2Áv¤ƒ}¶;lktrfÍö¢P@oyé:ýæK7ê¦KÏPÀÏé¶BÔZ_¦/þË%úƇ.Õ¼æŠíéuô§ÃI ¤q€·ŒO9špžxÃugòÚ"Ýúý't¼wÌu=Rm©8”Å@§ê½÷ÀðôÐóÁžÃ© îY c*йÁ¦H´£Ùt…‡WÅ2á,Ó¼(òk~kéÀã~öÐAÙNúž:¦·Ȳñ)éñ#¶:ÿ{w%Ç]Ÿûÿ©ÞgïÙg¤‘f$kdí’-/²3–ÁÆ6fu @ $@‚²’à†%dϲHnH~¹ 9cÀ/’Ù²,ËZ,K–,¤Ñh4ûÖ=Ý]÷‘ãùÖL÷ÌTUW½_çøs¾]ÎÝÓ]ÝõÔç;hk¾ïZo¸å =ô7oÖ¯¾m»ª+âKšþpËö}÷ÏïÑ/¿õêy³9éÐÙ‚^¼T¾ÓOKçüˆù¬£)]¡7¿ªÛÅ4X g/Žë/þí€q=“:üUÏŠ:l=”™)ßíhž?3d\c‚{8Øù¬×Âì*¯A ¶žñÀ-ÛÚ•LļŽBîÞ=§J:®‘‚;]µõôé¼&æ9µ}ysµþá½ZŸûÕjoªZâtð›d"ª¾õj}í_§5éysfÐÖásåé¹¾/_úGÍço»sR\ï-;Ÿúâ^e²æRøª¦ˆ">ûºëÐoW¾P¾;Ñ<† îa711­ªÛz„®€EGÁÀR`‚»nÜÒêurÃSzâp_ÑÇÕVX¢ÇÀ ù‚ô\_AÏ_(h>ÝË’Þõººÿ/îÑÎkV,}@øÚæ5Mº÷3oÐ;îÞ0¯ÇNØzúL^S ’Hº8fo|ŠF,½õÕëÜ „Û{¨O_øãzm…¥¦ŸµÛ%9%Ê•ñÝyÏŸ6Ü+˜à¶V·Wz"¬(¸Xt\2°¨:zvEŶ3žØ°ªÑë äî{ôÅ’¦½1½€Ƨmí+hzf~ï^™Öîúm_ײ´ÁPV*’1}ò½7ê•׬Я|æ!]šr|üTVzúL^ëÚ"ª¯âó¬oÄü]é¶ë;Ù%¦Ìä ¶>ö7:>fu³O?ûbÊt‚ûØDV}—&f]‹XR*îr x¦¹Ž'Û#Ü,:&¸Xlk%q;¤VwÔ{„ܽœ,é¸& î–ØÙa[zçWnÅ"úå·^­û>óFÊí0ÚyÍ Ýÿç÷èÕ;:ç|l¾ :WPï`yÆ 76mk9£‡Ÿ>WôqUIKñ% Ôz‡l>WÐ|º9¯ØºLßþÜ›Ôs5»dbášÒú¿ŸºK?õš s>v"cë™Þ¼¦g\ðÔùóIÉën^­úš¤‹i°P_øî3®w6E ä~g—çw;íTp/ã'%©«ä9÷w‹Š‚;€Å´FR×!Â&™ˆjUwàû÷žVv&_ôqLo°˜ ¶tìBA§æn¶G#–~ý§®Ñ?~âNµ4TºaEô©÷ݨ?øÀÍsî0=#=Ó›×D¦L›d€9 OÚŽ73½ý®õî…Á‚l[ö¯æéí• ©© ¾çšv¤Šd̽ ‹d*“Soÿì7X–”âÆúбóÜEꑵ=»j½ 8(¸XLÛ½F;¯nW"^~_2@pÜûÈÉ’Žkª^ä Bk&/ì-¨tî¢ðòæj}ù÷îÖÞ²Mшÿ H(O?ñê+õåO¿FÍõŽËæ.¿vǦ)¹@1¿¿o\ݨ«®lq1 ê;ŸÖ±ÓCÆõކò¨a9ít”JFÝ ²HNôŽ'ÏWÄ­²ž¨ÒLLL©¢ _˱Õë‚£<ά” ¶šñÀ ›Z½ŽBl*“Óûz‹>®"Á6áÇDÆÖÓ§óó*÷\Ý¡û>ûF]»ßU±ô®Yߪ¯ÿÉëµzyããr…Ë%÷¡IJî$3yipÜüÞþS¯YOñ¶ŒØ¶ô¹yÚ¸žŠKÍe0½] Þ÷ƒÇŒk• ƒÀGl­ng§.аh(¸XLLp÷À• ^G!ö½'Ïh*“+ú¸rض€ÿ MÚz¦· ù¼ ýÌë7éï?v»Ò5É¥|ßòæj}å^«ÍW49>®`K‡Ï4LÉãâ˜-Ó»zue\oèYãj,Ìîguàù‹ÆõŽúHÙܰPph¸—cÁýÉ#ŒkUÉ2yR°èZëâ^G+ î w‹¢£g—%NR<±²Ýyò ÀRºwÏ©’Žk¤à`Æm>WP¾àü¸X4¢?øÀÍúØ{v(åÒÜ×X—Ò¿~ú5Ú±©Ýñqö÷Kî£S”Ü úÇÌïç÷ÜÚ­ÊTù‰ÃÌiz{"&µÔ–ÏwÜ|À&¸;ÜkR.¯¤bœS{ä*¯~ŰXVK¢ií²šÊ¸–µÔz„Tv&¯ï=qºèãRq©š)j oÄÖÑóÙstêk’úçOÝ©Ÿxõ•î ª+ãúÇߡۮït|\Á–+h5SôqLo°½C¶Ž÷Ï1¶]R÷Ê´þãOß0çÔlÀ-ÉDTó[¯œ³Ô˜/H‡Î4™u)`Ñõ™ÏUV/¯Ó–5Í.¦ÁBýù—×b©­®¼¾ã /Ïd"ªH™5‚Ÿ:jžÞ^•´ÄNá•ÉΨµžþˆJÚìuÁÀÇ8€Årµ×Âhû•M^G!vïî“%×DÁ@‰N]*èÔÀÜåö[¯Y¡¯ýÑëµ²­Æ…TÀüÅ¢ýÑ/ýˆÞó†MŽ›ÉKÏžÍkºøûÈ>pqÌ<"ûM;×0U¸Œ95¨û÷šw.[V)»µi‚{E2ænEðÄasÁ½†Ò¡·²…‚»GèXevŠÀǘàîµ+뽎B*—/è;ùM’1¶PšýõšËbÿåݯۤ/~ôvUWÆ]H/bYúÈ»wèg^ï\rÏæ.—ܳ9—‚Åè”íxƒÒoYã^,ØÿùÃÆµhDZVfÓÛó÷Š–cÁýÉ#æ‚{-¿=„^º2êu„°¢à`QPp°`=»,qr≕Ë꼎BjÏsÏ}\#ÓÛɶ¥çú :?2b ð1 IDATw¹ý×ß~>öžŠFx¯¿Y–ôÑŸÙ¡»m­ãã¦g.—Üsso\ð‰~‡éí×nhe‡™22>9£¯>pܸÞ^g)VfýÙ™¼y­¦2á^EÉëÀóÆõÚ ¾„]TÜ)ê:dw‹¡SRƒ×!¦ª"®å-Ü€7îÝsª¤ã(¸(†mKGû ºèPû/Ÿ|ïúÀm“ÅÛ Ê„eI¿ÿ›u÷+V9>n2+=_=÷ŸÀc[p8oyãN¦·—“¯>p\“Ó³d-KZ–.¿ÚU6g~}¶5Vº˜dី¤¬¡±ŸŒ]þá6==Í÷ColîèÙÅ–j¬üδøwÞy çª6E£¼÷l[ßzìTÑÇÅ£LP0¶¤c º4îÜêF,}æWnÑ;îÞàN0`E#–>û«;µóšŽž´ur€1îàwC¶q×X,¢»_±ÚÝ@(™mKÿpïãzcµ¥D¨³Ü[Ê«àþäá Æµ~{€¤™™œZÓI¯c„QB_Ð,ÍH‹a»×Âèš+›½ŽB걃}º42]ôqÕ–¸Ä `¾Ž_˜{r{"Õß~øUzÓPQÆâ±ˆþú7_©ë7µ9>îܰ­ £Œq?ëw8wyå5+T_CѲ\ì;zAGO ×ÛëÊóÛmvöô’ʯàþÄá>ãZmª<Ÿ,¾Žæ ¯#„ÃR,w‹a›×Âhmg½×@HÝ÷è©’Žkªæ3€ù9q±0g‘·*×—~çÝv}§K©€¥S‘Œéï?újménr|Üñþ‚F§)¹€å Òà„ù=šòÊË?~Ó<½½"!Õ•é„ðlÎümm¬r1ÉÂØ¶´ïh¿q½–N3¾¯¾Šz¤G(¸X0ÞÁ,†M^£Îö:¯#€ºï颉F¤Ú2-pש‚Î;xÓ5Iý˧ïÒ[Ú]J,½êÊË7m¬l«1>ƶ¥#ç Ê8L_xc`Ì–m8…©©Jè•×®t7J64–Ñ×>i\o¯+ߺ•Ó÷–úòi…¿Ø7ªá©Y×¢©*Áï¸,)x!¬(¸X°ò=ãà =»j%ñMÜe©dTmi¯c€:vzHg.Œ}\ºÒR„ëËæpfÐVïs¹½¾&©/ú5ÚÚÝìR*À= µ)}ñ#·«*7>f&¹ä^`;øÊÅ1óóݯX¥d"êb,Ä—ï?¦ìL~Öµˆ%µÔ–ï—Ûììÿµ$•×÷'_0®Õ¤,Yåûa‘Íd2^G«m=»øà° Ü,ÔF¯„QÏÖvÅ¢¼…÷}çñâ§·KRCW—8;;dëÅKÎÓõª+ãú§OÜ©u] .¥Üweg½>÷k·8³Æ3¶ž¿À4Jð‹™¼42e.¸ß³³ÛÅ4Xˆ‚më¿yÔ¸Þ\c)VÆ—ê39óë´µ¡ÒÅ$ ó¤cÁÝÅ ð½éLVµ ¯c„Q¥$>ü,HŸrð‰Í^£k70™xã»OPp°øúFlp.ëV¦búÒïÜ¡Íkš\Jxç¶ë;õko¿Æñ1Çl]eŒ;øÁ¥qóûñòæj]»±ÕÅ4XˆGž9¯“çFŒëmuåýÝ6›3¯µÔW¸dž®&e)Î¦Ä 'lïw.·'âQ}ñ#·ëšõ”ÿðæmzíÍ«óÂÅ‚¦f\ 0º4a.¸ßuS—"NÛrÀW¾tïãZuÒRMª|ŸË|áò?³©¯I*Q&_ÜGÆ3:vzȸ^ÎÏ–F}My¼¶ˆ‚;€¡à`¡(¸{ sY×@}ï‰3ÊŠŸËôv&[Ïõ9—Ûc±ˆþöïÒM[—¹” ðË’þø—~D›¯0ïZ/HÇú ²äžÉ¤áIóñ7t¹ rapRßzô”q½Ü§·ÏäÍk­UîY }7ÞW%-ÅhÃᇤ¢œ,{„N€á#ÀBq2â²d"ªŽ¶´×1@Ý¿÷Å’Žk(Ÿëä\”ÍI‡ÎŒS$%)bYúó_Û©[¯Yá^0ÀG*’1}þ#·©)]a|ÌØ´­ÓƒÎ7Š–Îà„m¼Ñ¨±.¥íì@S6þåÛÏoêŽF¤æšò.¸græ’oK½ù\Ãož§á©Y×,…£à^.Ü÷é7®ÕPp‡ƒÜLÖëaÅw%£à $=»"â$Äu;6·(y„Ìý?½]’ª¸¸ à²éé¹>çr{{S•þîc·«2Åo €“w½n£n¾j¹q}zFêtþ{,Üè´­\~öµD<ª×t¸%ûêÇkéJKAÄŸÍ›oÈhmôÁݶ¥'_0®×¦\ ƒ²395­ªd@þ˜Ë Ý2%£à T’ª½67llõ:¡ûŸ(­à^OÁ€¤‚-=_PΡo[•Šëï?öê²™ x)bYúÓö¨¾&i|Lï­éC@]7—…äªåªJÅ]LƒRMNçtߣ§Œë͵Áù^ë4Á½¥Þÿçág.Œ©ïÒĬkKªNç¹ÂÒXÙêÿ×yµuôìjô:€òDÁ@©6y Œ®ì¬÷:™‘ñŒãà&Õ)K côÂÅ‚Æ3æXIJôºUV5¸˜ (o­ •úÈ»¯7®léÄE¦¸ÀRr*¸ßqC—{A° ß~ìEMNÏÞüŽXRc@nÜÎ.ÿ3›†Ú”â1ÿWÈv8k\«IY²‚ñTa µ¤¹ñÈ#LqPÿŸð+ îèZ–ö:™ÿ|²W9ÓUpA)X˜þ1[}#æò—$}üçnЭ׬p)÷¼²[׬7ïü:4aëÒ„óß 4ã[Ã4ìˆeé¶ëWº%ûêÇkÕ–¢iVeóæµrÙEiÏóÆµºJ~ƒÀÜ*è·{…‚;€’ä4 €6{ l"©£µÎë d¾³÷tIÇÕW-reg2këøçd~üö+õŽ»7¸”–ˆeé“ï»Q‡q¥/ôT ã‹nh¼vý¦65Ô¦Ü ƒ’]™ÖƒOõ×[j‚SšÎæÌ'­þ/¸Û¶ôÈ3çŒëé àlÙù¬×Š!ªJBÁ@©8ùpÙÆU ªHq;)pO¾`;^ì7IĤêdpŠŠ—/HGÎ;k7®nÔ'Þ{ƒ{¡€Ú¸ºÑñ&‘LN:3XüN,gC;d¼ú†N“`!þãá”7œ°Æ£R:@SÁ§gÌkå0ÁýØé! Oͺ±¤šTpž+,ÉÉi%ãQ¯c„Ü”„‚;€¢uôìŠKZçuް¹nC³×@Èì=Ô§‘ñLÑÇ5Tqa»ç/4å0¯¦*¡¿ù­W)•ˆ¹ ¨_}Ûv59Œ-=;d+›w1\® N› v¥‹i°_}à¸q­©Æ’Ã&)eg2c~Í®^îÿäw8k\««Ös…¥cÛ¶:[÷ïM=»ø+P4 îJ±V£Ä]¶¾³Þë dîß{º¤ã(¸ávnØÖÀ¸ÃèvIŸùå­l«q)lµU ýö»®7®l©—)î°h†'Íç9íµêj¯u1 JuºoLûŽö×[j‚õ½vÒáæÓî•þï"ì9pÞ¸V IûXz­iêNh”Ôâu凂;€Rlò:@uòCpY)÷ˆ¬mÜg"cëä€s‘ö}÷lÑm×wº”‡7í\£k7´×ûFles.€š0ÜoÙÞáb,„ÓôöT\ªIë{ídÖüº]»"íb’âåò=zðœq=]éb”½ªd°þ¶ËÈF¯(?Ü”‚‚»–µ0͸çä¹½pv¤èãÒ•–"\+Bɶ¥clÙÃÛwljׯÿÔ5î…B²¤ßù¹Æõ‚-õ1ÅÃÃ÷ÛW¸˜ ñµ‡^0®5lz{¾ e 7º¥1u´ú»‹ðì‰KŸœ™u-¡°ŒâXîúôwE£à ›½6‰XDíÍLpî)ez»$5Tqa«ÓƒMdÌ…¯æú ýÅoܪX”ËSÀRØ|E“^½Ã¼;SÜ`á&2æ÷Òx,¢6·»%yá숎2®·Ôë|ÕizûšuŠúü.õÝÌÓÛë*-ù;=üfjjZ//0L@Ñ‚uFÀ-œt¸ìÚ ÍŠÇ¢^Ç!BÁ@1F§m4g¢Kù¯Ts}…‹©€ðùà[¯6®1ÅnhÒ¼¶cS»*S1÷ d÷=zʸV´T‘p-Š+&³æµîõî)Ñ#÷t¿A 8¹|^­é¤×1ˆ îŠFÁ@Q:zvUIZíuްÙ~e“×@ˆŒMdµ÷ð…¢«NZJÐçB'_Žõ9—f?ðcÛtý¦6—áµqu£î¸¡Ë¸ÎwX˜¡ ó }·lïp1 â¾G_4®5V¯0í4Á}m§¿ îÙ™¼öî3®×UïùÂÒkoHy!Œ6vôìâ@Q(¸(Ö‰žÜÖ½"íu"<Õ«\®ø ¯ UK€ï(hzƼ¾ùŠ&ýâ]å^ äæšâ~†)îP’|áò®5&ÜËCߥ í®ß¸ÞXíb—8Mp_ëó.¾£ýÊdó³®%bReÀ¦íÃéê¨×Â(-i™×!” Éëa´¢­Öë Dþs_oIÇÕW1›¡I[çGÌE¯D<ªÏüÊ-ŠÅ¸$¸eêÝyc—qýˆ­îc€Ðž²eN{Ú›ªÔ½Âß“°qÙ·¦·W$¤ÊDð¾×NfÌçëÝ+ý]pßsàœq­®"xÏÜ‘b÷A¯lô:€ò¯‰ŠEÁÝË[(¸÷<¼ÿlÑÇÄ"Ru’‹Ë@˜äòÒóœ[²zǵ¾/ÍA4×÷þQsÑ 0»¡ ó{çÎí+dñu¨,Ü÷è)ãZcoÚΤLnöµD<ª•>¶çTpOWïù‚;ì‚ÃdXJÜ…‚;€bQpwYMe\­AÜ øÒ±ÓCê»4QôqéJ‹B2'.”5”e$é†Ííz÷ë¹~ xa}Wƒîºi•qýü#Ü XÓæ‚û-Û;\L‚R eôèÁóÆõÆêà}©Êš_·k:êø÷¿óøÔŒž>vѸNÁ¥šššV„±¼@ç @Q(¸(Ö•^›7µÊâĸäÁ§ŠŸÞ.qa›áI[ÇÌe™êЏþäƒ=”½ç æþÈTV™bŠ;Ì×TVš6 üF,½bë2w¡$ßÙ{ZùÂ쟉˜T“ Þ¹ëdÖ¼Ö½²Þ½ %Ø{¨O¹üì7å¥âR2ær F>_P[cÊëaÄðŠBÁÀ¼uô쪴Òëa³mm£×@ˆ<´¿·¤ã(¸áQ°¥ýÎÓŸ?þs7¨£…)/m_תu] Æõ¾ î0_CÓÛ·¯oUMUÂÅ4(Õ}ž2®qz»$M:Lp_»"íb’âí9pθÆoX¨¶ú¤×ÂhcGÏ.þxÌwŸB'.»¢Ãß_*@pÌä züÙ¾¢«ˆ_žž z‡lM&˜JÒí;:õ£¯\ë^ ³²,éíw®3®ŒÛšÉ»ÊذCÁý–í.&A©&§szð)ó ÝUÁ¬B8Mp_Ûéï îN÷ºŠ`>_pOº’Ú¤ªÅ`UEà@1¸"áŽÖ¯#€xüPŸ¦2¹¢K´àå¦f¤ÞAóôöÚª„~ÿ^!‹·ÀÞ´³[•©Ø¬k¶-]eŠ;ÌÅ–4:åPp¿š‚{9x`ße²³ßÙ‹·0í4Á½{… îCczá’q îX¨äì§ÈXz½ |PpP îXÖLÁ¸ã!‡ivNê¹° „Ɖþ‚ }Øß|çujJW¸€£êʸÞгƸÞ7b¾apÙÄ´­œáí²¶*¡ «Ý „’Ü÷è‹Æµ†j+7hæ Ò´aç¥X,¢ÎvÿvyÆ<½½2a)u1 ©wØ– K‰‚;€y£à Ü]ÖÞX©Æt•×1@H<´ÿlÑÇX î¤;/50fkxÒÜn¿z]‹ÞzÇ•.&0o»sqmzFŽ×ixʼ¶cs»¢¾ùÝL® ûŸ8m\o¬æs85cþŒ¿bybQÿÖÆö0ÜÓ•.A`MMM+ æß¾Ïmò:€òáß3~DÁÝe7njõ:‰á)99Xôq5–||MÀ"ɤ.š'=G,K¿ûþ› âèK Ìm^Ó¤­ÝÍÆõq îàddÊü>yã–v“ T<¯±‰ì¬k+¸»’MÎþ_Y’´ve½{AJà\pæów µ7¦¼ŽFtÏÌ—ƒ“ —mºÂß_*@p<üôYìâ nA-x©Ó— ÊæÍëï~ýFm\Ýè^ Eqšâ>0n«„SÛ–F î7l^æb”ꛜ4®ÕWY êþÉŒùµëç‚ûù ½pvĸ^Ë.rX$­é„×Âh×” îæ¥£gW½$óx,‰UË뼎B⡧Ζt[ƒÁ7ž±unØ\Žik¬Ò/ÿäv(Ö]7­R<6û¥á\Þy:1„ÙxÆVÞ°‰M}MRëºü[Æe¶-}÷‰3Æõ¦êà–¥&¸w¯L»¤H{ž1Oo¯IY2œÒE««Œz!Œš:zvù÷ €¯ð‘`¾º½F-µ^G!ñÐÓÅÜc©:Ü2€ËN 8_ÿ×ÏîPuEÜ¥4JQ[•Ð-Wwׯ)¸ÀlF&Ík;6·+bñ}ÈïŽ÷ëüÀĬk–uy‚{PMf&¸¯ðïÍ0Üë*\ ‚ÀKD9ö4óBÁÀ|­õ:@ØD"ÒòV î`é=5¨þA‡æ†AºÒRp«$ihÒÖð¤ù¢ÿÎkVè®W¹˜@©î¾yµqm`Ü–M¿^fØa‡‹·,s1 JõàS½ÆµÚO/ØÒôÌìk±hD«–ù³‹`ÛÒn‡‚{º’_!°x yà –wóÐÓ4K€‚»ËV/«UueÒë Ú_üôv‰ Ë@ÐÙržÞžLDõÉ÷Þ(—åá¶ëV*nhñåòÎ%N#Û–F îí.¦A©œ îAžÞ>å0½}ÕòZÅ|Úì?u~Äqâ~mEpŸ3¸orrZñ(¯)Pp0/þ<[àGÜ]væ¯#€ à`6ý£¶&2æbÌϾq³V¶Õ¸˜ÀBÔT%tËöÆõ1 îðƒÆ¦m oMé u¯¨w7Š–ÉæõØÁ>ãzºÒÅ0.›Ìš×Öúøµë4½½6e)ÂÏXD¶mkYS…×1ˆ‚;€y¡à`¾(¸»lcWƒ×@dgòÚ{È|Áߤ"!¥âK€/léÅKãzCmJï¿g«‹‰,†×޼ʸviÜ–MÇþÛÈ”yí†ÍíìbSöîÓt67ëZ<*U'ƒû$N:Lp_Ûéß‚û#wn²ÇRh­Ox!Œ(¸˜ îæÔѳËw×u¶×z„Àã‡ú4•™ý‚¿.,ÁvnØ–¡ $Iúà[¯Vu%w¹åæ¶ë:•ˆGg]ˤá)îð_FÞoØÒîb”êÁ§zkAÿN;‘1¯u¯H»¤ÛÖ‡‚{]€'îÃ;µ³ŸcIQp0/ÜÌG»¤*¯C„Mk#ÿ“€¥÷Ðþ³%Wð2f3yéÌ yz{W{­~òŽu.&°Xª+ãÚ¹½Ã¸>0FÁ¤Ë»ÙŒ:ÜoܼÌÅ4(ÕCO™¿ïý;íxÆa‚ûJNp?zjHCc³7ó£©&À÷áDÄüÝK¦¾£gWƒ×!øwóÁôv´4V{„ÀCíL,Kª«àÂ2Tg Ê;\ãÿÐ;¯U<Æ%& \½öæÕƵKã¶l:î ±i[ÃûaKC¥V/¯s7ŠÖ?8©#§ëéªà~§ÍædÜ)•ˆéо~÷0ßP[aÉ îSåff¼ŽVLq0'~}0Ü]ÖZŸR]M…×1@À Oéè©¡¢«IYŠòë2HÓ3Òùs»õª+[t׫\L`±½òº•JÄ£³®å Î_ ,F¦Ìk7ni§h[tØ­¬*i)1ûGa ŒM›?Ë7¯iŢ_è÷8g\Ks“=–ÈÔô´qþMwsâÝÀ|PpwÙöõÍ^G!ðÐþ³*”0¦5è[¹avf°à8½ù·ßu…. ÌUWĵs{‡q}dÒÅ0àS£Sæ¢7/s1 JõÐ~óneõ•.ñ€ÓÍjÛÖú³‹ËôØÁ>ãz:àϼcÛ¶:šR^Ç# îæDÁÀ|PpwÙúδ×@8]ðwÂ…e ˜29©Ì\†¹}G§®ÛØæb"KåG®Zn\v(u@Ørž€}ý&·ü®`Ûzè)ó÷tÀoÚ›6¯míögÁýÀñMLÏ̺‹^žº,•–tÂëaDÁÀœ(¸˜ î.ëj¯õ:‡Ÿ6oÿm‹HÕ).,AÔë0½=bYúÐ;®u7€%sƒÃôáÑ)Ûq'ºÉŒ­|aöµ†Ú”V-«s7ŠvèÄ% ŽÎÞòŽXRmE°¿ÓŽ;Ü á× î{žv¸!!àϼWŠz!Œ(¸˜wŽ:zvÅ$]áuްYÖTíupGN ªp²èãÒ•–¸´ O6']5aÞ´sºW°ó$kV¤Õ”®˜u­`KcîÂËiúõöu-²øBä{î7—¥ë*-EüNe¥œátMR+Ûü9loÏ3æðë>qÞ‹G 4XJÝ=»øãàˆ‚;€¹tIŠy"lZ«¼ŽÎi»v'AßÊ«³Ã }VË’~þ-[Ý `IY–tÃævãúHñ÷À@`Œ:L¿¾z}«‹IPª÷õ×êþvÜá&µ­Ý;¼Ac:›Ó“GúëLpÇR³ y¯#„Q¤&¯Cð7 îæ²Öëa‰H­5^Ç÷Ð~ó'Üà™ÉKç‡ÍE˜»_±Zk:˜ÞcÁ}Š îÂkÌá=ðšõ-.&A)Ƨfôä‘ Æõ ÜÇnÐØº¶ÙÅ$ó÷ä‘~egf/'bREÂå@ÌtÆ—7„@·×øws¡àî²ÕËjU‘Š{X._p¼ào’Š_þ@°œs˜Þ.I¿ð–mî…àš¶˜ î£S¶ãûÕL^šš™}-±´e? ˆ(d IDATø<¯\¾0ëZ2eé±ióÚ6ŸÜ9pθÆôv¸a&—SºŠ¼<°Æëü‚;€¹PpwÙUkÙ,­gžÐät®èã기 N® s˜Þ~Ûu+µaUƒ‹‰¸åŠåi5¥+f]+ØÒ¸ÃX*§é×V5ª2s1 JñàSæÝÊê«‚ýÖ¶¥‰Œù5¼­ÛŸ÷ÝN÷€O܇´Ö§¼ŽFLpàˆ‚;€¹PpwÙ•+뼎îуçK:®–‚;8ç‡m\J’>ðcLo‚ʲ¤6›§¸L¹|bÔ¡à¾}}‹‹IPª÷™ îA/KOdÍ;°,kªRsýì7¶yil"«Ç.×ëþœÁ?j¸ÉÜ8âÀ\(¸»le[­×@À=öliw&¸ÁR°¥³ÃævûÍÛ–ëª+)rÝätNg.Œ©ïÒ„¦³yegòÊÌ\þÏìLAÙ™¼"Kõ5)Õ×&ÕP›R}Íåÿ¬®LÈ⣡¬Ý¸e™¾þð ³®LÙZ!ž`á2æpsÏöu­îAIN÷éÔùQãzÐ îãÓæµ­ký9½ý±C}*س·ò+âR’f\R•dN°(¸pÄi£Žž]•’Vx#lÚ›ª¼Ž,_°õäá E—ŒI©øà™‹c¶ryóú®gz{¼x~T{õéäùQîÓ™ c:Ý7¦áÒÇtÇbuµÕjýª†Ëÿt]þÏeMÕßË„Ó÷Ñ)[¶DÅ@hض4Æ÷²öà~óôöš”¥XÀû«N¯ß­Ýþ,¸?ràœqéípS,â°µ–JwGÏ.«÷ÁÏšß¼„wNV{ ŒZª½ŽìàñOÍ}ÓÛà97l¾†|í†6]¿Ñ\|…ÿMdµç™sz詳zp¯N÷-úÿ\® ã½Ã:Þ;ü’)à5U m[Û¬Û;tËöZÓ‘¦ðîS«—ש¹¾B‡^~£CÁ–¦³REƒ`à‰¬­‚áô¨¹¾B-5îBÑÜg.¸×WºÄ#ãóÚ6ŸNpßíPpúÄ}øK!Ÿó:BÕHj‘Tü$¡@Á€“.¯„M"QK#w°t;x¾¤ã˜œËè´­‰Œ¹àþþÝB!¹Ìäòx~@=Õ«‡öŸÕþçú•7µô–ØØDVï?«‡÷ŸÕÇ?ÿ¸:Zk´s{‡n½f…nÚºLI.Qú…eI›®hÒ>yfÖõ‰¬­ŠoÂaÌaS“íëZ97ò¹\® =Ï8”¥«‚ýæ r<¿ß²¦ÉÅ4ó30<¥£§ëÜh7e2YYÖåÝ<àªnQp`À¯Gœty l6]Ñ X4àû¢O=ZjÁ Ë@ œw˜Þ¾²­F·^»ÂÅ4(ÕL® oì>©{9©ÝÎil"ëu¤Yõ^Ó—î=¢/Ý{D•©˜^ßs…Þ~çzmöaÑ*ŒÖuÖ î“þ|IÀ’6Ÿm_×âb”bÿ±~Oξ[Y,"Õ$ƒýܾ֩¦#­š*ÿmÉâôûDUÒR<êb„^.—Sº:¡¡1N€]Ö-i·×!øwNº¼6[×4zXÁ¶µ÷p_ÑÇ%bR*¾x"›“ÆÍ˜wÞ½AF”úÚ¥‘iýÓ7èï¿qX‡ÆÍúÐätNÿü­çôÏßzN›×4émw®Óë{®P4žY×Õ`\›ÌØ’x?cN÷õ­.&A)|ê¬q-]i~ÿXƼ¶u­?o*ÜsÀaâ~…‹A€ïk«ORpw߯ð/ îœty lÖtÔzØ¡—Œíœ0½–¾QÛ¸íz*Ó[^µÖÝ@˜·ç^Ò¾ö¬¾òŸÇ•Éæ½Ž³`è7>·[ŸøüãzËmkõ oÞ¦æzÚLns*¸OdÍeO’l^š6|UŠÅ"Ú®#¾÷àS½Æµteð¿ÓŽ;Ü ±m­?w ØíPp¯ Ásÿ©¯¦Jén¯ð/Þ•8éô:@Øt´T{˜ÓößN(¸ÁaÛRßpÁ¸þ¦kTWt1æR°m=°¯WŸÿÿŸÕÃûÍ“IKH©¸¥T\ŠE$Ë’"ßÿçòÿm©`ÛÊ奙‚.ÿg^Êåmer‹“a|jF_üÚ!ýó·žÓ»_·QïûÑ­ª­J,οsZÓQ§hÄR¾ðòbÜTV*Ø—_dcSærð¦ÕJ&¢.¦A±†Æ2:ðüEãz}Uð?Èœv ØÚí¿4zûÇõâùÑY×,ñ;¼Q•Šx!Œ(¸0¢àÀI—צ­‰‚;X:•Zpgr—Æm9 þ~ÇÝÜ GS™œ¾|ÿ1}ák‡ôÂÙ‘ÿû,I5–ÒReÒR*v¹Ø›W_oöÏ‚-MfmMd¤ÉŒ­‰¬4ž¹\†/ÅT&§?ûòýýGôþݪw½n£*’\Î\j‰xT«;êôüéáY×'³¶ª“œ 6§rð5ë[]L‚Rì~ú¬q‡¢Š„ôÓ‰Ü;lXÕèn yxäóôöꔥ(=cx f™oÇ’éîèÙeõ>øY¶Žð2?…PªŽž]Õ’üwoÀµ4PpKö¥Çõ}\"&UÄ— Oœ1_3¾nc›6¬jp1 fcÛÒ·;¥ýõ£:70± W*.ÕWZJWZª«´[ä¢PÄ’ª“–.ýÿŸôDÆÖФ48aklÊV±M…щ¬~ïÿ<¡/|íYýÎÏÞ »_±Zýê%µ®³Á\pÏHlì èF§ÍkW¯kq/JòàS½Æµúܰ=–1Ÿm­ïjðå{˜ îéJƒ? _¤-ªPŒ*I’¼À(¸0éô:@ØÔTÆÕ˜®ò:¨C/\ÒèD¶èãØŽÉ¬­Ñ)sùå§_»ÑÅ4˜Í™ cúÈ_=¢ï>q¦¤ã£)ýýB{}¥¥”G7(U%-U%¥ŽzK¹‚4 ¿ûèíZ»²~‰S†GGkµ*S1MN¿ü"›“ ¶(›¬Ñ)ógÐöõ­.&A)t(¸×WÿÃ+““f U¦bº¢#ín yØóŒ¹àÎMöðZ}uÉ*_+½ÀŸBpŸ"€uy l–5W{ÔÑ5<–)ú8.,ÁÑ?j.nݸe™–5U¹˜&Ül[ú§ûŽªç½_.ªÜ^™Ö´Dtݪ¨:Ë»ÜþƒªS–6-hsGD5óœDºoL¯ÿ•¯é{OžYâtá±,u´˜ñ˜n€ pš~ÍwËdózìYóneõ•.†ñȸÃëwËšfE}v‡Z¾`ë‘gÌÏY:Ïü­2᯿™`‚;€YQp`ÂɃ˚빀–Æ£ÔUrQ‚|Aº4a.¾Ü³s‹iÂm:›Ó/ýÉúПíÖØÄü¶½G¥µm]ÝU[Ø)Úu–¶®ˆh]{DñèÜŸšÑOÿηõ·ÿþ¬ìù ÇÚͲlŽÿ‘S&wùŸÙ$âQmº¢ÉÝ@(ÊÞÃ}Êdg_JUÉ€ž8ý§4¶®õßë÷ðÉKŸýühDªÁs‹G8ïõÜÌ* ³,.¯„McºÂë  œ&Ú9a‚; —&lå ³¯¥1ÝyÓ*w…ÔÙ‹ãzÏ'ï×Áó>¦½ÎRgSD±¬jª¶TWÕ‰‹ Œ9—K ¶­þ1=fH¿ûþ›‹†è¨%ÐÚhÄÃwAåXînR¶-}ñëÏêŸ\ùÂ܉hDêjŒ¨-m‰wáÿ™æþ\_Áñu,IÿþÀ %bQýá/Þ¬£?KÒÖ`.¸gó¶Ä«@9}UÚ¾®Õ½ (Zv&¯ýÏ]4®×†à;íTVÆšëRZÞRãn 9Ìä Ž7à×±é=| Ÿ/¨±.¡‹ÃÛ#`)¬tÌëü…‚;€ÙPpwÙºÎ:¯# €"L*ZT…y\€?zÌaËv'Ü`¸8fþM£)]¡Wl[æbšp™Îæô›¶Gÿö½ççõøæK«š#JD—8X™‰G¥Ë"za  óÃοÑýëýÇ”ŒGõ©÷ß$:îÅkk¬2®e™à € ¶4ž1¶lg‚»¯xþ¢²†m^’1)‚MŠF¦·oínöÝùÐÓÇú5eØ&•ª’> ŒÐjMSp÷@§(¸ø!Ü̦ËëaÓÕî¯;§ L)Z\lA \=ZjÁÝ<Ä@éw(¸¿ñ–+‹²³äR8{q\ïùÔý:x|`ÎÇÆ£Ò•m¥+ù=ÏIJ¤+š#ªJØ:Ñ_Ó/u_úæ%âQ}ì=;|Wêò»ÖF‡ îÜÐxÆ–éòOGkZv¶€÷s˜†éí’4:åPp_Ûìb’ùÙýô9ã7ÙÃOÒUT*=°Òëü‡_-̦Ëëa³¬Ù<(ÜWÁ°½øÝã‡ÌýMbQ©2Á÷J ÜMÏHSIï¹µÛÅ4á±ïh¿^óKÿ>¯r{uÒÒ¶•QÊíóÔVgiãòˆbs\áüÂמÕ_}åwBˆÓ÷LŽ ‚glʼÆôvÿÛëð]7,e釂ûµZ]L2?{ž1Ü9†ŸT$©Tz Óëü‡wc³á¤Áe-õÜýÅGÁ}qåi¸(CÏŸÖÀ°Ckà ,e è'Ì…—µ+ëµaU£‹iÂáÉ#ô“¿ýM]™žó±-5–¶¬ˆ(ÉpÀ¢¤+-mZÑ\›üÞß?¡=Ì%*¼\c]ʸ3(ÜÑè´ù\éšõþ+ãä ¶ž<|Á¸† î™ÜåZg‹F´}¿^ÓÓ9í;Úo\§à?‰Yt<Àw/CÁÀlº¼6Mi îX|¦ (M¡À„"åçq‡-ÛPp‚áÒ¸ù÷Œ»nê?-®§Žöëí½O¦¦Ñ÷Y’V7G´¶-"fT”¦:5wɽ`Ûúù?øžú.M¸¬ÌÅ¢5×W̺V°¥=3æ0ýš îþvøä%OÍ~ÎJ• —y`Ôáõ»¥»I•)ÝEùä‘ ÊN&’1)w9àÄÎ{ ŒÆ àe(¸˜M—צ¡Ž‚;ÜwåhßóD;'5©EÀu¹¼séåöë¹v¼˜ž>vQ?ùÑo‹Vÿ%•6uD´,Íow U“²´a™óM—F¦õÞOW34³ç­µÑ|½‚)î‚dzFÊú‹©DLë»Ü „¢8Ý̆éí’4âp®¿cS»‹IæÇig¦·Ãoff8ñõܼ w/Ñѳ+%©Íëa’ˆEÔÈw,&¸/®‚MÁ@ùqÚþÛ$bIÕI¾SånhÒ–é׌ö¦*mº¢ÉÕ ”»‘)[yäåꊸnØÜîn :|rP?ñÛ÷jd<ãø¸–ZKkZ¹ç†5-U&ÌŸa'Ï诿rÐÅDå)åÐ0£à (l[šÈ˜ßÔ¶­¥àîg{™§·×„dG2§‚ûŽMþ;×ßsàœqéíð«ºJî¼ðÀJ¯ð~Qðú¼6Ë[ª¼Ž€€b‚ûâb‚;€r³ïè…’Ž«¡à”½Áqóï;¯Y¡xŒËC q¼wX?þ[ßÐðØåöKÝ­ñ®êŽhDZßQÔáåý™Ù¯3ÆÜ U†RI&¸¾É¬m|OkoªRs}…»P”ÇŸ5ÜëBR–2¯íØÔæ^yÚ}à¬q-]Žç å§ŠßǼ@ÁÀKð &€Æv/.k­¯ô:*Ê÷EEÁ@9)ض(ú¸dŒ­Á ¸4aþãöëù x!Æ&²z÷'¾£¡9ÊíÍ5–ºÛ(·»­"!u5™/f²y}䯛5š%ãÜ ;C@¹qÚ€eËš&÷‚ $NÜkCpoB.oÞÀ²¤ë6ú«à~qhJÏŸ6®‡å¦”Ÿ¸ù¾O,~°ðÜü°.¯„Mc:ß²á ‹‚û¢ÊSpPFŽœÔÄôLÑÇÕra({“Y[ÙÜìk±hD·^»ÂÝ@R°mýâ? ÎŽ8>®©ÆÒZ&·{¦­ÎRµÃ´Åï>qF?mž"vLpãÓæ7´­ÝÍ.&A±zûÇuöâø¬k–ŽÉF¦Ì¯ßu J×$]L3·=Îת“–b”ˆáSqw§˜àà%(¸øa\ÝpYCš îX+ø?ฉ îÊÉSGûK:. e èF&Ík×ojSmU½0óÙÿû´¾³÷´ãcšª-]Ù?ÍyÇ’´¦Ùù øó/?íN˜2”rØÊ…ŸH…ÓF,[º™àîgNÓÛkR–Â0ÿË©à¾cs»‹IægÏ3æ‚{U øX>g¸sK‰ î^‚‚;€ÿÖѳ+"Éßx,‰¨1]åu T„OùEÅwådßÑ %W›Zä \çTx¹yÛr“Ëý{OëÿiŸãc«-]ÙF¹ÝªS–ÚëÌOÄ#Ïœ×3ϸ˜¨|$Üb l[šÈ˜Ï—6¯¡àîg?k.¸×…dãôÑ)óÚõ›ÚÜ 2O»&¸§ÙE>–Édùnç>&¸x ªo~P£$óh,ºîµŠEy+ÆÒ`‚ûâb‚;€r²ïHñÜ#–T•ä»$Pî† î7øp¢c9xáìˆ>ðGÿéø˜º Kë(·ûJgSD1sW[õ•gÜ SFRNw›ßH”¿‰¬-ÓÛYGKµ¸ë×ל&¸×† ,+Hã7h\¿Ñ_÷3ÆÔ{alÖ5Ë Çs†ò•ËçUS÷:Fؤ;zvÕz€Ъðƒ–y lÖw¥½Ž€‹„a>qñ@¹Ö‹}£EW²(fen"c+—Ÿ}­*×&’m|jFïþäw4>9c|L2&­k§Üî7±ˆ´ÌaŠû7vŸÔ‹ç‹ÿ¼ :Ç îüD ƧÍk[º›Ý ‚¢ Oéxï°q½6ü“±ÑÿÇÞGÙyßužÿ>wßkUUI*íRlY¶BlÇ[² ˜¥Á t÷f¡‡†9íé陦g8p†>p˜ž¡»gº`–žià™ B'(ŽxK¼ÉZ-•J»JR©öåVÝýyæŠc'º¿ŸªÊ·~Ïò{¿ÎÑqàW7þF÷ÖsŸåó|Íͬ{·uKw°jì_:¦no/f¡ A·©”ò{ÑâàÛØUð^Ô÷¶kKÑïaWÔ:ŠwañæÙ e#¡N‘¢B ôæ+굇î’D‚ËBkázžü÷ÿîërþš:HsDöoŽIRÓÿlªÄõ<ù>Êì@!Ðâ<(€ˆÓµ_s3`°½þö-åZ!mGXZpäÞ`µ·‹ˆ¼|BpXh««ð{íð{ÁaÁî€5 Áݰ­› ~€£Á½³¸° ,ŽžQ_ô×±¡íˆºyMàåÑûè7Y«ßûôqùò7.kfÏ@L l?+Ô´¸öùQ©7=°Tµ¦þûˆsÎ@èÜ ¸Ù«§Æ•k%KÂÒºZ¹7Xûûž'òòquÀ½+Ç~‚¯áNfÐààÛ¸x¯`ñX`°7ç÷ˆ° îEƒ;€°xóìĺ^W$  „Þü²úüÅc9ý»/».¿ógohfs·#ƒ%¶A·µ[}9´¼Ü©ƒW6ªÖ›Ê5òíÂÎõD–ê4¸‡Õk§Õ÷®lô¿¤Z®H¹ªipØ ­£×fej®}"?æpáMò9õ î¾€;€÷¢Áݰ¾nîØ84¸wwaÐr=9>:¹æ×¥")žº „Z¹æIÓm¿VÈ%åÀî>³…ØRµ!¿ò^Os:¨”udw?—Ù “é+¨Ï•þç—/œ&ø*5î¢k¹æ)¿ßwl.IW!mv ¬Zy¹!§/N+×KÜ«ž¨vOwn.®\ï%ÍM„¥¬Ã~B!æ(²±‘¶ú=€ààÌ€÷"ànwl$îÕ"à Î\š‘åª:˜¦bCˆºùöåˆ""òð!IĹ$´Z¿óŸÞ”±‰²r=•¹{sLx€bxlÒܼzEšª»C,T­µ”k16#Bn±¦^£½=ØÞ8sK\ÅÝ Ù”H2nx ÌWÔ×*¾wÈà$«óò uÀ½;ÇŽ4ÂÁsÕûÆØ0ÁÛ ð §!¼W°žYq±wl¬WØ:ªår‘ @ð={k]¯ãÑà@ø-,«/¤ÛdµŽž?ý›SÊuÇÙ¿9&) BTQÒ“W·„Î-Öä§nš(ÀªuÜDW¹ªÞ_úà¾M'ÁZ½ªù®î²ä†mÝ ­Ü¬¨G³åÊ7Nªß³î¬Áa€÷¡Qoø=‚¸ø6îÞ‹«íÚ\’d‚« Ø8W:ŠwaðæÙ‰u½®”éð Œ[¬©Ï]¬ƒLDS‚+CÀ@ÐMÏWåêøÂš_WÈ8Ü „\YÓæxÏî^IÄ9Gt'£Wçäß?ó–r=æˆìàï1Ìz5÷ ׿e¹ªvÛD×àg@ˆ-ÕoqÀÖý§¿=#oœQ‡p iG¶v³­Œ‚BZý>ž³~ à@D¸xwÃz©Gƒ4¸wŽKÀ@À½yfw @Ô•5—{÷p×¹>Y–ýÿ¾®\wDdß #›ÊHÈknê"à¾âÖô²r-I¡ €Ó5¸pûKAÕl¹Úc]ÜËUOT—)zs²c¨dv ;xéØ åZw.úï¢'÷{+p "ܼ+X·õZ §HÀ€{çÐà ÈZ®''ÎO®ùu™$ꀰk´Djí %•ŒË¶u›(d~ëO^•¥ªº±zk#yMë7Â¥V¯pq=OnÍ´¸;ÎJë*„QËY®·¿Îã8"öôž«õöÅå¾Z2.’MÈóõÚ#÷nܘ¯œ àŽˆñZ~O`#îD„€;€wÑànX©@À€{çÐà ÈÞ¾4-ËUEÂU£¨i²åšúœÅ=»z%‘àRÊ© ÓòÅ—.)׳I‘í}üýEIAs³Â¥ ' ¦é¹ª4[nÛµtÂð0ÐAKšý¥½Ûº%ŸIœkñêé›Êµ’íí""óõç÷‘û‚•]ª6ä­õÍ÷64î#zZ-î>ÖÆ €o8+à4¸ÖMƒ; HÄùªïÜÙ1Ídî@ø-UÕk÷íé77HýÛ¿xS»¾w0&ôGDK<¦n!¯Ö›R­¯ýf±(¹9µ¤\K%øe^åšzíƒ{7™köê©qåš aiÏY¬jî÷+æñÚ©qåÍr™äÊ luõ¿°a¸îÞEƒ»A‰XLJÜa î£:Ap|t}÷BºÃƒ0N×à~ß^î*GÏNȳ¯]U®u9V„¦l¤ ¸‹ˆÌ-j¸9­ ¸:L>¸ý¥ r=O^;­¸—²‡ñÉbÍÕ%ʾ®Œìî6;мtü†r}k„U£Ù”$OF3-Xwïð [_ï ànÐŽÍ‰ÇØcãpï—wvòüÔº^—OsÜ„ÝR€ûzü›?W··Ç‘í½œ¿ªD\ýÝ7kyÀ}\Óàž&à Ät7ÜGƒ{P]¸6¯ünŽÇì8ž]Rv¾w³8û+xå„:àÞ Ø°Àôyü€a4¸îDdøÐÓ1açÀ¨½[K~KÄ5k°6-îªÞhɹksk~].µ ^ž'RU<-=æ8r׎³…Ä7NÞ”]W®oîvh«Ž0]ùâì‚Ýw]ƒ{:Á¹fáÔrE*õökñ˜#÷ìê5;Ví›§o*×JGløfš]V¯}߇¶šdfkrúâ´r½‹€;B¬”'ànØÐð¡§Ùh à@DDúD„½1ƒ†ó~KÐàÞ9ÜÕ™Ë3Òl*žY®Q° íˆºZs%äÞÎð`Ǩ·áy"¿ógêööxLd¸‡¿·(KÆÕks‹Usƒи&àÎMÂJ×Þþí=’åõÆÛ·”k¥lôg-‘rUýù=tÿ°Áiîì'n(Mr)‘”f ºB–°a9)ø=ÿq†€ˆÈf¿°Í澜ß#ÀÜ;‡€;€ :q~j]¯+d8f®ÒPŸ¯Øµ¥Ëà$áñÂ[còúÛãÊõ-ÝŽ6ðKhÞßÙEËܧt î€*kî]:¸¯ßÜ X³£g'”k]YƒƒødnY½¯¿w[· +ûùò uã~7íí¹|šˆ¥†ü€ÿØúÙâ÷¶éï¶àˆ#àÞ1ÜÕ©óêG€ëäÓ€q•ºzm×–’¹ABÂóDþ÷?{C¹žˆ‰l¥½=òšs¦óe»î×'u îœkNº÷ƒ{ ¸Õô|U.ß\h»æ8vܰ=»¤þì>ñ@°ÚÛED^>~]¹ÖeAã>¢}a_p@À€ˆÐàn\_WÆï` Ü;‡€;€ :¹Þ÷4ÇŒ@ØUip_“g_»"'FÕÛÌ­=1Ipå,òt îóeÍ]#W®4äê¸:H˜âÉBj±ª ¸ïÛdp¬Å[#êöö|Ú.ÎjÜ`›ÁIîl|zI.ŒÍ+×»hpGÈéŽ!°aȲ à@Dhp7®»HÀfpïÙtåì•™5¿.›‰sv½JC½Fƒûwò<‘ûG•뉸ȖnÎ¥Ù@wƒÍ îg/ψ§8šK9âðë „š®HU±¿”ˆÇdÿÎ^³aÕŽjî% .µ—kž4Zí×2©„<| XÅÆ/¿©\+dn"EèÅ…¬€‚µ¡à v!ˆp7®«`ÁQ7!FÀ½cZ-ZÏ™+3Òhºk~íí@4Têš÷­4¸¿×gnÉé‹ÓÊõm=1nü±„¾ÁÝÞ€û™Kêæò)ƒƒ@•5ííwïì‘4§¬·ÎªîÅLôgg—ÔkܸÏîË'n(׺³6ˆç*î8ÁF"à€€;á±.ÆÑàS1¾ê;…wAtòüÔº^GÀ?Ï©)Iã1G†7Ìpñå3ʵT\d3ííÖÐ7¸×Í 0º@òì7)Ý}K÷n27Ö¤åzrìܤrÝŠ€û²úºäã÷œäÎOÑß•18I°ýù—Ï(×òiGŠl­¤Ê4zžHyYQ÷ao_TÜ iƒƒ@-VÕk÷õ›k²°T—ѫꛣ~ÃörÝÅCU$‘ˆÉcƒUhž@p­»Á  u]À’ ù«¯ž“FÓm»sD6p·–ªÁ]D”-¤QU^nÈѳÊuö„U¹ª¾¦sß^ aƒJ÷T´à2ûì²úsûøýÃ'YWN¨î]9ö!-©Ÿip,GÀGï†uÛpäÀ àÞY. î¢åzòöÅ™5¿.“IðDe MõyŠM4¸‹ç‰üÅ—Ï*×7mÈÑ–L¨×.]_07H¼râ†4[íoÉ$Wþ@ØÔ["µfûµt*.ØÖmv ¬ÚÑ]À=Ú×=[®È|Ep X÷…¥º¼xìºr½;gpÀ€¸CVÀÜËqê î†u¸Ãœ8÷Ž"ß (Î_›“j]‘ØÐ …ˆŽ†®Á½‹€ûgÆåÂØ¼r}¨‹í¡ÍršÐöèØœ¹Aàëoé‚iüž§MHøÀî>Ip—[ yž¾Á½ñ€û|ÅÕä{sr׎^³ÝÁ¾~AjŠÇJ%b"yÎ? biS(6Ô ßð{íhp7¬˜Oû=,ñUßI wqâüÔº^GÀˆ×i*®­wÓ„¶DäË߸¢\˧È7€B/—R¿ÿç¯Ùpáè˜r€;€°Òµ`?p7Y¹ ºx}^æËµ¶k‰˜H6ex Ãf—õííNÀ¾–eD¹Ö[p$`ãï›ÛÒÜeެ;{ÇN4¸VÈEüÈ£Á½£ZÜÄÉõÜy° ÚöönÚÛED¾úúUåííÐäÎ]57ˆÏ®Ž/Êå› ÊuîÂj¡¢^{äÞ!sƒ`MŽŽ¨ÛÛm¸9qvIpßfp’;;syFNŒªÏK –¢ÿ~Á>õFÃïlÔã÷üEÀwƒré¸dÒšgŸFÀ½³\ÕsÀ°SÖpçá@44šês›¸Ë¥óral^¹ÞW`[h»¬¦Áýòiª‘1_KÝÞ^Ì8Âà „QÓYª©÷•>|€€{P½uVp78ˆª•?íÄG>ú=[Ìt‡¨ÛÛ3I‘®,ûÛˆžz½)‰ŸmÃhp,Çi ý~`“mƒ¿G€eâÜ;Ê£Á@xžÈé‹Ók~]:!’ŒoÀ@Œ«Óà®õÕׯ)׊GRl ­sVÂWí4[®\W·šGÉ G¯+×zr€Z¨¨¯åìÛÞ-=Å´Ái°Ú÷ˆ¦uííì®Bp>·õFK>ûüyåúP‰(¢Ê“î…–†p,Ç^Ü Ú:@ÀfÅœhŸì1wAp~lN–«Í5¿®`Á#Ý[´4åÒ=¥ˆ×[®Â³¯]U®õæÙbENÓâ~þÚœÁIüÑlºòÒquÀ½›ß!¥ ¸?L{{`-UræÒŒr½ñãÙÙeõçöñû‡ Nrg÷Í+2·XS®”¢ý^ÁnÝ…”ß#؆€;`9î¸4ØÃÅ%˜£Á½£\ÜÀÉóSëz]!Í1"º€{6mw=ùâR]^=5®\ïÉ–ÓdSF-¸õkR^n´]‹ÇDŠì7©…Šzíá›Í ‚591:¥,šÊ¦DN7¹žÈœ.àþÀ6ƒÓÜÙá##ʵ޼#©„ÁaÊY»·}@À°\„w¬R¿ßØdS7w˜EÀ½³hpë¸wx¾Ñ¢ÈXž(ùú[×¥©¸ •àf¼+kyƒû3špZwÎ Œ\Od±¦ÞQzè^܃êèÙ åZ)âíí OT[½¥ŒÜ»78…ceyñ˜ú 0ƒ´·#âr¢–†õø=±Õ,6|è鸰3`T/†aqîEƒ;€ 8uaz]¯ËG<ؤ¥ ¸§í¸õµ«ÊµÞ<ÛA¼KÛà~5Ú÷ÉÙŠ<÷Æ5åú¦"¿+Âi±ê)o(È–~åTGGÔ÷bÄeg5íí‡î–X€î:ûô³ç”¿cÉ8ûÛˆ¾TœÏ¸aÅáCO'ý€¸vëö¾ ê.hΘ H'<¢À£Á@œ¹<³æ×$ã")ž¢ D†îüŒÅ¿ì-×Ó†v Üà½t î§/NËÜbÍà4f}öùóÒRlH1~W„×BE½ö0ííåyú÷bÄ;äf—Ô;÷?0lp=×óä/Ÿ=§\(ñD_ÂÞÃm?QÜ XŒ€;`·~¿°M1ϳÀaVœ;ˆ;Šw~Ÿ^’ùòÚwù4LJ@”èÎQ¤-¸¿52!3 Õ¶k1G¤;ǶïJÄD2Š.@×óäëGÇÌdˆç‰<óìˆr}SÉ ¬æ+ê}¤‡pª±‰E™škwB<&’‹ðñl­)²\W¯߇¶šæ^>vCÆ&ÊÊõ¡4D_œ¹zý€Øìvëó{ÛuÏ<6 î¥j5SF®Ì®ëuœ’¢Eßàž07HÀ<÷ºº½½;Gh·ëÑ4•Uóy ³ã£“2zuN¹>Xâ@8yžÈb•€{éÚÛ i'Ҥ׵·ß··_ú»³§Ñ;üu{{)ãH–ó°€#ä|@À°wÀn4¸VÈ)ê`€ ãª]Gy¬üµþ€;LJ@”èîö6¸¿öö¸r­Wd†½z5­þ_{óZ$ /þRN˧)D¸%@´-ÕØÅþ,á)¾h°‘¸#àØwà ԥÁ0î¥{ü7˜pöò̺^—Owx¾ÒÜÓv6¸»ž'§/L+×uMݰW—¦Ùv±&oiwa´TmÈç_¸ \§½@˜-TÕkz\º÷R&ºoœç‰ÌiîO(àþ¹¯—z£Õv-é/D÷}ÞËu ¸û Çïø‡€;`7î†åy. #àÞY. î|v–w"¢»¦nkƒûå R®4Ú®%ã"–æþq1G¤[ÓâþÜ× N³ñþãß¼-‹Kõ¶kŽ#²©Èþ€ðZª©¯á|øž!ƒ“`-jõ–œº¨¾I±á€û\EýÔb>%ºkÀì@ ž'røÈˆr½¿àHœô,Ñjµ¿ÑŠwÀbìbvë÷{ÛäsÔ¥Á¬uEƒ;?yžÈùksk~]:!\l"FÛàž²3É}òü”r­á`Þ¿^M»ÿs¯G'ྸT—ÿû3'”ë½yG’vÞ "–jêµûöÒûT'/LI³Ù>åIJ¤¿›¦ËêúCÚ*‰€ÈŸº8%o_R?Mn°‹}mØ£Ùhú=‚¸ ÆÞ¿p$oP:§ÁÆÑàÞY4¸ðÓå›óR©­ýBZ>ͱ!`[ûNèîôŽ@£Gp?}qZƧ— N³qþè §d¾¬NNbž'²\W_ÃÙ¿“l\P½52¡\‹r{»'ú€û'Ýil–;9|äœr-›)Eø}¾[³Õ’D‚ϼa|‰#àØ€»A[ûs~ pï,Ýã¿`£\™]×ërÜoDŽ.ÄÞlÙyCÛàÎ>ÐH'Dr)õgä¯_¸hpš1»X“?úüIåz1ãHOŽßáUixÊ'ÜlÝT.îv ¬£gí ¸/VT"vû³I¿G° wÀbìivë÷{› oÊû=,³µ²kƒÐàÀOë ¸ÓàDѴ/àîzžœ¼  ¸G8…ÎèÕœ¾ÿÃÏ”Z]‘@ ‰?üì )/7”ë;úønKêTÈ=»ÈÅ™.à^Êİ)M{ûG¿g«rÁÐ~é•˲¸To»æ8"%ö!`Ÿb&á÷¶á‹°wÀn4¸4Ø›õ{X(Nƒ{G¹ªú0€wïÐuØp¿:¾¨ ï&ã+ Ý€NoAýK51³,ùì9ƒÓtÖÔ\Eþô¯O+×»²ŽtÓÞ ä–jêë7÷ìæ’xPO/É©¥¶k1'Ú7kOkîŸxt§¹Aîàð‘åZoÞ‘dÜà0@@ä2|ð ëñ{þ!àØwƒú»#|‹9+FÀ½£<î|tæòÌš_ãˆH6ű!5ºS>M î'Ï«ÛÛ£ŒBç”2Ž4Ÿ•ßûôñÐþnýŸ‡ß’J­©\§½@ÐàNºööBÆÑÞÔfåš'ª¯æ˜ãÈÇÞnv …«ã‹òʉ›ÊõAÚÛa©\š¸¥a|‘c‹ XjøÐÓŽ°`T_w˜GÀ½³ZÜø¤ÑtåòÍ…5¿.›Òa„“.ìSi÷ý8¡ ¸8-‹UÚÖ«þź>Y–Ï~í¼Ái:ãÅc×åÿûâÛÊõîœ#¥,; ¯Lƒ{(Q܋އӵ·?t`Hú»ƒñdøg4O°I%Dzx ,•N·4Œl`1¶¸€½J"ƒY ê.¤ýŠEµÚÀ'®GÀ€?ÎÍ­«96G{;IºS>am™~?Néî4¸c•ú Žö{ówŸ9ªŒùrMþùÿñ‚öghoÖÊŸvò™¤l*š«vôì¤r­˜‰îw”.àþ‰ÇvœD­åzòiMÀ} ݆}àNR >ü†õ zšŒ+`)~ù{uù=€mº )¿G€…hpï,7D°DËÈåÙu½.G°ˆ$ÝÅF˾€û™Ë3Ê5îX ]‹ûå› òÅ/œæýùÕßEƧ—”ë½y'ÒáAöXÒ´·ïßÕKT@5›®œ8¯¸—"úU©‹,×ÕëŸxt§±Yt^8:&7§Ôûƒ]ÄÍ`¯$wÓb²Râ ÀBìqöâËß°BŽ€;Ì#àÞY4¸ðËÙ+êð¦NžÓ@$érZ¦¢Â4¢ê–LÏWÛ®Åc"™¤ájýEG²šÏÌoþÉ«25W17Ð:}áëä¯_¸ \ÇDvoâ21€h(×Ôkûwõškòö¥©ÕÛï·¦"©ˆ>‹^×Þ~p_¿lÝT08ÚᯨÛÛ»²úý% êâ12>à °g.{ñ,6ÊÜáZ):‹w~¹Bƒ;€wéNù4›v5¸OÌªÃÆéˆ£°qîU_>½5³,¿ô¯Ÿ“f€Ÿ”pcjIþçßYû3»úcÜü 2t î÷ìê38 ÖâèÈ„r-ÊO™ZR^ƒÒÞ>=_•#¯^Q®–¢ûþ«AØÒ=~Àls{p7,OÀ> Á½³¸ðËÙuÜcÍÅ@T9š„{­ÜàíF˜˜YV®¥xt<Öa èhoŽøæ©›òÛÿñus­Ay¹!¿øÛÏÊâR]ù3½yG†ºøÝKš÷{hp¬£gí ¸×š"åªúZã“í47ŒÆgŸ?¯¼i6[yâ `3Gì:æ¾ÐKpìEÀݰ|–€;Ì#àÞY®GÀ€yKՆܘ(¯ùu¹”#Ñ×\ÝYÐ¥¼"è–.à78"ÃqD¶÷é/¡þÑçOÊß¼xÑÐD«³TmÈÏýÆ—åØ¹IåÏ$ã"û¹< :\O¤RoíÆqDîÞI.¨tßWÅŒÁA š.«¯3îÝÖ-{‡» NÓžç‰>2¢\ßTt„Ëϰëp÷_耥8ƒØ‹€»aÜიîyÕX3Üøaäòìºn¸Í¥7`Ô·gì ¸ëÜ ‚H,9ÒWП[ýÿý rîêÚŸ°²–«Mù/~㈼þö-íÏíŒi·6ËuOTGJ»¶tI.ÃÎ@Í—kréÆ|Û5GD mp×ÜŸ|t§¹A4Ž›Ðîß –¢ùÞkáº-¿G°wÀRÜÐ7 e IDAT{p7,›!àóhpï,îü0re}á¹|ŠcB ª’š«;³ Usƒ€¶Á=Ávë÷Á˜è̺\mÊÏüú—åͳæ†j£ZoÊõ›Gä›§njn¨Ë‘Þ<¿¢E÷àš{v‘… ª£Sʵ|:š á–È|Epl§¹a49§\Ë¥)Fôæ`-šMî>àK°wÀ^%¿°I>›”„î¹ÁÀ‰Gñ ÖÓ˜ï×zî4¸Ñ¥op'àþŽMÕxâ1‘ý›ã¢;µ?>½$?ù/¿(ü…SâÇ©ÃòrCþëßüм|ü†öçr)‘]ý\£=K5õÆ÷ž]}'ÁZ;7©\+d bÐÌ’ú³ºuSAîÝÓopšö–«Mùë.(ׇº¸î ˆˆÔëM‰9ü>Öã÷üÁ™ À^4¸4ÐÍeøƒ«Î¢Á€F®Ì¬ëu9ÜÈJÄÕ¿ß3óÜß‘J‘”K‰ìÔ_Nm¶\ùWôMùÅÿõYY\ªšLäÅc×åc¿üWòÂ[×µ?—IŠÜ»UÔ€°Ò6¸ï&àTÇFÕ÷¨6„O•Õ×?ñèN Â%Ý¿}ù’”+¶kŽ#²©€!@ð$—ánjà ~ÀœÊìEÀÝ žRDo5Gà94¸ww~8»Ž÷DL$M°ˆ,Üß5¡ ¸sn ï_Á‘áž;–¾ôÊeyòŸ}^Þ™ØÐyÊ•†üêï½,?ýk_’SKÚŸÍ$EîŽs³€ÈZ®«¯ÛìßÕkp¬–ç‰ö»²ÁÞ¸–+2·¬þ¬>ùØNsÃh>2¢\ëË;ÚcÀ6Å;؆p,ÅÖ°wƒz‹)¿G€¥bÜ;ªEÀ€aÓóU™š«¬ùu¹4ǃ@”Åc"1G¤Ý©Š™…ªxž¢Ò]ƒ;!tÊŽ¾˜”k®6œ&"råæ‚ü½ÿá¯åþ»ägŸÜ/?öÑ]’éPºÜóD^:~]~åw_’±[‹wüùtb¥¹ÞDUÓi´Ú¯å3IÙÜ—7;Ve|zI&gÛãÆœh>‰lfÉO± Ñו‘ï4;P¯ÏËk§Ç•ëƒ]Ñ{_€÷#Oƒ»i|©–â”`/îu#x«9B!fË•LC\ÕÙ'Ø #ëhoÉq¯=y‰¸H½yûÿ¿Ñte©ÚB6i~(ÃMWÙX­ü:ÁqDöoŽÉȸ+3Kw>Gxôì„=;!ÿê¾)?õ±}ò³Oî—=Ã]ëúw_Ÿ,Ëç¾vA>óܨœ¿6·ª×¤+Íí™èoX¬¢ioß=ÜeÍÍ~as|tR¹VÈ8‘|ߦËêÏê>²Câ(,ûËgÏ)×Ò ‘îœÿ3A’Kp7ŒwÀRÜ{•üÀ&¥ª¸2Ñû›.«÷>öáí’ Àc‡Q®uçž ´‘$‡awÀRÜ{p7¨ÀQ|Bƒ{gÑàÀ´‹××p9Bs+`´& su|ÁÜ >r8÷%ã"¶ÆdlÆ“k3®øuê°;çȾÁ˜¤ùî`™JC½¶{+÷ ºx}^ÊËí߸d\"¤ö<‘é%õ“í47ŒÂälE¾úÚUåú`‰ým ˜ÿ÷¦Ø&ï÷üÁ©À^Ü ÊfÙÜÂ4¸ww&UjM¹5­~L¸J6ű `ƒLÒ‘öç*®Ü\4;Lq8"²­×‘Á®¸Üš÷d|Þ•ZÓÌ¿;ÙÙ“Í´¶°T¥®þ²ßµ…€{;gW{û|Å“f«ýZ:—Ç6;PŸynTZŠëŸ‰˜H_!zï Ð q~5L£Á°TÌï˜7|èiG¸•£:>!àÞYܘt鯂¸ÞÚC²k½Ð^&¥^»rÓ’w¿¾%_ º?¸+.¶Ä¤7¿qŸÎ|Ú‘]›bòàÎ8ávÖª6DùäŒ-ýyÉe¸6DÇ5÷bÚà †èÚÛ¿ïCÃ’÷¹²ÞóDeD¹¾©ä—šöb$.MË zš¿uÀBìÕvÊ çþÊFíyjiî(Uƒl„‹×ç×õº¬&ô :VÜÛ»lIÀ]‡³8ðƒ#"=yGzòŽÔš"ãó®L—=Y®¿¿ÿÞTBd èÈ@É‘Oj©4Ôßô{†» N‚µÐ5¸#Øà>]VNŸ|l§¹AÞ8sK.Œ©Ï; –¢÷žBÒÚ9)û=³¸v¢½Ý°lŠÍ-üAƒ{gÑàÀ¤Kë¸s,Ø “X Ó¶;[qõÖ¢´\Oâ?7D·‚,ÙÑ“}+-ÃÕ†'•ºH¥!R©¯„Þ+ Oš­•ŸÇD’q‘dÜùÖ?W‚í]YGºr­E!ôÎéäˆoŠ_T47íî27V­ÞhÉé‹ÓÊõBÄî‹UOêÍökñ˜#h»ÙÚ8|DÝÞžO;RHGë=:‹Ü€ BÀ°‰KÀNÜ K§ÙÜÂWù:Êõ8P`κÜy`ÇI'EªÛךMWnN-Éð@Áü`qî asDr)Grß~ÊÊ»ŸÝ–»òûL:\\Od©æÉbuåŸÍ–HÃi¶DšîÊÿýNÀý›R‰wo^È$)eW‹Ù”kW©kÜ·p¢3—g¤ÑtÛ®e’+ÛÆ(ѵ·?zßfé.¦ Ns»r¥!_|é¢r}ˆöv@Ë!àß0Ä%`'î†ehp‡Ohpï¬ î ºxc½wŽ[d’ŽTíÏW\¾¹ù€;ñ˜ß`5jM‘…Š'‹Õ•P{¹æÉjûPZîÊŸïÜ^¯üç˜#RÊ:Òu¤+'RHxV£Òæ¿wìî67Víø¹IåZ›Â§4÷'Ûin…/¾xQ–«í+æcŽÈ&GnÀœà,Dâ°wÃ24¸Ã'1΄w”Ë*ƒÖÓàžŒ‹$"Ö|@-£ybÕ› ò½Übnpæ ÀFj´D¦=™X\ ¶o×™[ödnÙ™^Ù—ìrdKWLèNÔt î»ip¤cš€{1­½ºÅª×ö)Kïø¡Gw›Eåð‘åZ_Á‘7àZ®×þ‰ØPÜ qX Ø©ä÷¶!à¿ÐàÞYܘ2»X“¹ÅÚš_G{;`—LÒQ<ýÊÍ³ÃøÀÑ”;¬¶YÞËõDf–<™Xðdvyõ-íÒh‰ŒÍxr}¶%ýG¶v;RˆXðx¿ZîÊSÚɤ²eSÞì@X•·t 0± þòxpÿ  öæ Ns»ÑksòæÙ åú ííÀy.wðXˆÄ%`'Ü ËP³ŸÐàÞY.WF²žöv‘lªÃƒ´¬¦Áý²÷l&!ñ˜#­6¥–­ZSäÚŒ+S‹ž4Wò<‘ÉEO&=)eÙÑçHW–óý€ˆH¥¡¾V³kK‰kcT^nÈ…±9åz!÷ÌóD&ËêÏèSï18M{ºööLR¤;÷Ø(.w?ÐàXˆ‡Êv"ànX&­¹Òl ‡÷Žjw±6ºî4¸VÉhN;Ž^U‡ˆ¢"sd@Ñ€éz„ÜÜ™'"7æ<9z¥%ãóÁ··…Š''Ç\½år>À´J]½¶g¸ËÜ Xµç§”OÄȧ‰G(¹4»ìIS±šˆÇäG?ºÛì@ߥÙtå3Ï*×Jz3€ Ôj±SæØ3ìDÀÝ D,&iÜá“8÷Žr ¸0äÒ:îÜ«dSês?®ÏI¹Ò08?6÷«ŸR^kr.€Zµ!râš+']étF)™ˆIwVº‹éŽýwÞZX âOkšèvovw›«vìÜ„r­Ð¹Íd L,ª·Ñ?0,½¥ŒÁin÷ìëWez¾ª\,qmXf«%<0Ä8õÁ?€È"q ؉€»A}]\Y†x cgq'6SÖßàÞáAZÌÉ¥Y®ß¤ñ<‘·/NËC†|˜ÌœÍ}êkÜõ¦ˆD,4 3–ëžœs•-»«±m°(÷ß= ÷ß5 wíè‘Þ®ŒtÒÒUHK6øvè©Ùtef¡*SóU™ž«ÈåñùƉ›ò“7ej®²¦g½)ræ¦+ýGö Ä$_ÿü@XUÚì÷¼cÏV܃èøè”r­˜‰ÎµÌ–+2£¹ é“Oì58M{‡Œ(׺sޤI‘«âyž$â1iðx“hp,Ä® `'îõweýshpï(WõüDè°uÜ5m΢©Y®·_;q~*úwmƒ»ÁA„Fµ!rjáö›KòÃí”÷ʇîM=«»þ“HÄd 7'½9ù¨l•ôä~ñ<‘ó׿ä•7äï^½"/¾u}Õ³L•=Y¬¶äÀÖ˜äØÿƒe*Šý‘=ÃÜƒèØˆ¦ÁÝßBóŽš.{¢zt!›”xh»Ù¾Ëøô’<ÿƘr}¨‹ï`-ré˜Ìp7‰wÀBÜ;•üÀ&}]TÁ?äÛ;«¥:+vùæÂš_“NpبvdBÚŸ³8y^Ý–[6éÜ=aÃà]µ¦Èɱ–ÔWnï.¦åÇ>º[>õýûäþ»¤“Mu‘}Û»eßönùù½GF¯ÎÉá”|æùQ©­bÀZSäÄ5WîÙ“R–mìQièÜ» N‚Õ˜œ­È©¥¶k1G$¡›t&ÕŸÍ'Û)YŸëÑ?ýÕQe™W".Ò›Î{˜I%d~‰»ª ¢Á°wÀNTŠÔ]$àÿÄH6t”KÀ€7¦–¤²ŽÚaÚÛ;4§O^ˆ~À}¨w«ãy"gnº«Ú6|âÑò“Û'ßÿà6I&b?œ¬„Ýÿ·ú½ò/þAùóÿ|Fþà³'¤¼Üо¦éŠœºîÊ]C1é+°/ˆè«7EZвÜM=Y)ä’fÂT®åÓNGoòS½)2·¬¾ŽøÔ{ Ns;Ïyæ+ç”ëE‡æ5JsÎ4¸v"qmPW)ðO,*g…‚€;.^Ÿ_×벜‚¬”O«Ïÿ\¸6/ËÕ¦ä2ѽ´¹_×ànpw}ΓrUŽw÷Ö.ù§?*24ÕízKyú~H~ê> ¿úû/˳¯]Õþ¼û­àþÞ˜ uqMÑF{{ø;§¸3Ù`“šööÞœþÐvù»ß}Ê×pû{mîÏËŸþúÊÿõ/žÞÒS ç'\¹9ÏvÑVÕ<Ô`×Ö’¹A°jÇF&”kÅLtŽau÷ÿ¾=÷ùšíá##ʵBÆÑÞ4  ½T‚ßÃhp,DÀ°wƒŠ< >rhpï(ܘ@ƒ;€µ*h)'ÏOœÄ¼Ážœ¨NÕ4!8vpEwz÷#Ü"ð?}L2©`=ñÂqD~üÐyî~RžxpÛþâ„+sËœÇFtU5 îÛ‹'ÁjxžÈñQõ¾h!"÷åºH¹¦þl~ò‰½§¹ÝâR]þö¥ËÊõ!ÚÛuI%ˆ]Fƒ;`!¶´€¸”æ±Dð‘#"1ZÜ;†w&¬;àNƒ;`-]8(ê÷D"&›zrm×\O¤Ñ2<€À™\ôd¡¢>·{׎ù“_ÿ¸¤SÁ½žÓו‘?ýµËßÿhΑ³7]©ÔÍ̘¦kpßNÀ=p®Œ/È|¹Öv-‹ÎMÚ“‹ê'„ìÛÞ-v÷œævŸá‚TëͶk1G¤¿È¹`=4¸›Fƒ;`!”J²©…¿Ü;†w&¬'àî8"é`Ž0¨ 9ã{üü¤¹A|2< ¾Î½Xå|`»k3êí@Ìqäßý³C’Ï?e™HÄäßüwß'ÿô|öçš®ÈÛ7[ÒTç-ÐÒ=eû÷ 96¢ÞJ{»ˆÈÄ‚ú{æ©Ç÷*Ÿ6dÊ3GÎ)×ú ŽPB ¬O2íXHp,Än `'î¥Ámü€Xu î6Z³åÊØDyͯË$Å÷‹æü“O«7£Wçdz¾jpóîíW®éZ›DßÌ’'Ëuõvà¿ùä}rpŸz4Ž#ò+ÿèAù­ò˜v߯R_ir÷Ø"bªMõ‡z îsìœ:à^Ìd-T<©µ/G‘§í17Lg/ÏÈñQõû0ØÅ‰`½’ š–÷{æpìDÀÝ Üá·xŒÏ`§´\*ol¬+7¥ÙZû±G6ÉE5Àfñ˜>äþʉ§1ïÁýƒÊµÅhgûÜ®½}x  ÿü§ï78MçüüÞ#¿ñÕþÌܲ'Wg8§èp=‘º"HœË$¤¯+kv Ü‘.X]ŒHƒûÄ¢ú{æ¡C2ìó‡5í홤HW6ïà‡]—¦ÑàXˆÄ`'î%hp‡ÏâÜ9Ü14¸Øho̯ëuÙT‡:ºL×KÇ¢p@p÷h0,µPñd±ªÞüòO}P²é„Á‰:ë¿ü±òÓ?t·ögÆfõ ö@˜TêµmƒEžh0ͦ+'/L)× š›3ÃÂõD¦4÷§ßkpšÛÕ-ùÌó£ÊõÁ‘1àýˆ‡36œý,ÄÞ `'î%ljá¯8GVãp°Á.]_gÀwÀzÝ9õvà¥ã× NbÞÖMì͵]s=‘¥çtÝœWÿî÷wgåïì§é<Çù­_zL¹w³òg¤÷.T<ׄý°¨iÜ·•Ì ‚U9>:©\+d¢qírRÓÞþ±·IwÑßXÆá##ʵ޼‰› ?‘2.é÷Ìc[ ؉€»AÜá7îCÀÀF»:¾¾j†wÀzñ˜HQzéØ ƒÓ˜÷€.à^áœ`›™%OZŠVÝl:!?÷ÃûÍ´zKùã_û¸$âêëQ—§\i´/RBC×à¾m¨`p¬Æ±sꀻnŸ5,š®þFª§žØkpšÛ]Ÿ,Ë o)×ioBÉáCO³ñ,Cê°wƒt'¸wŽKÀÀ»>Y^ók‰@)€èÊ©×^:í€û‡ïÑ5¸sN°®U÷Ù!Å|´³g¯üÒ§*×›®ÈÅIEâ‰jS½Fƒ{ðèîÙ ÓeOT— ¹¤üÀ‡·›è»|úÙQñó%ã+ îÞ/Ž3}À³'˺,3|èé˜ðØ£hp‡ß¸w î6Úõ‰¥5¿&•q8ô "Ý9õÆàåã×ÅU¥\"àÀî>I+îö©7EjšP€h¹S«îÚcpsžþ‡ß#Û‡ŠÊõÉEOʵè~ úª õÚöAõgæ-W›rîʬr½ÿìÄ‚z{ú#Ù¥Ü/5Áõ±×à4·ûÜ×.H½Ñ~#‰l*rþèŽ/}À3(˺ìCÀÝ0îð÷Îiµ8H°qÆn­³Áî"ïQH;’T÷Öê-yåÄM³TÈ&åÞ¡\×µmˆ]{û÷|`“ä-ÙqúŧîS6»žÈ9Ê\.ªWDD¶Óà(³‹5¹:ÞþæmÇÉ…¼Á]·?y÷Î^Ù¿³×à4·;|dD¹Ö_p„èÐ9‡—~°cgÀ·±ë؇€»a‰›Zø+FÀ½cZ<ÇÀº6±Î÷Ç}¾SON½]xîk'1Oך9»ä‰¢Ð@DÌ/«Ïá>zp³ÁIüµ}¨(?úÑÝÊõñ9O8Ý0©6ÔØmÜ儦½=Ÿv$ì—-u÷§ßcp’Ûº0-§/N+×K!ÿËÆ#áîî€eH]ö!ànX"®¨K ¡Á½s¸ØHcëkpO':<€ÐëÍ«Ï}õõk‘nš{üþaé)¶? î‰È-î@¤-TÕ¿ã9¸Åà$þû¥OT®5Ý•›~€°Ð6¸p’ãçÔwÅ.ZhÌW<©5Õë?ñ¸úFKEÝÞžM‰”²\3:*ÊÖÁ•ò{fpìòÃÆðIðœ/øŒ÷Î!à`#]_GÀ=XyÌ;¼W·&à>vkQ.\Ÿ38Y‰DLþÞ!u{æw ²÷üyåú`‰ÌÐi4¸û‚wÀ2ìÁö!ànX2Á¦þ¢Á½sZ-RlŒ©¹ŠTtUp é$Ç|n—ˆéŸãšÁiÌû¤¦=s±êIEÓ ¼t Ï;6%“²ï±7?÷#÷(×f–<¡Óaà‰([³ã1G6û*ÆíNŒªÜ !N*4]‘IÍ’OùÜÞþåW®ÈÂR½íš#"%ÎFÀÝÜ˺ìâÃÆpJp‡Ï¸w î6ÊØ:ÚÛED2öå´¬RoN}Nè¹×£pÿÐ]²csI¹>¹àœ€)Ëš†çÝ[º N‡îß*ùLûPË] ¹AWo®<¡¡-› Åö!PÕܼ²}¨hpÜÉñsšööŒ#Nˆ/YŽÏ«?‡?ò‘]RÊû—¹¼vkQ^:~C¹>Øâ¿x À<ÊñüÀ™PÀ2Üûv±l IDATp7Œwø€{çxÞÊ£0 ÓÆn-®ëu™$Ç|Ú˧I)žòÐlºòÒ±ëf2ì©Ç÷(ת ‘ù gy€¨©Ô5 î[í ¸‹ˆüØ÷îV®Í,©‰ ¨jîÉ#à,ÇFÕ÷bˆS ‹UO–jêåÏ|ânƒÓÜœS®¥â"=š';X?w?ÐàX†Ô%`Ÿ:†O,&’LÐà%b|ÝwwbØ×ÖÛய€ˆHo^fyîk'1o×–.¹ÿîåúØ,çx€¨Ñ=˜Âæ€û¡û‡¥m_véz"³Kllº÷mƒ܃äN îa¥koß3Ü%28Íwj¹žüå³ê€û@)ÜÍù@¹O÷ î€eH¼ö!ànP&I¸þ£Á½³ZÜlÜl][ãs¯_“¨Î}òñ½ÊµÙ%OÊš&Ná£kpß³µÛà$Á’NÅåÙ¡\牺ZS½¶€{`xžÈ‰óSÊõ°Ü[®È䢾½ÝÏù‹o]—›SKÊõÁ±0`£¸äü@À° {2€}¸¤jÄLŠpï(5`#ŒÑà`tçÔ·f–åÌå³öÔ{µçhÇf8ÏDEÓi´Ú¯²IéïΚ(`>ñèNåÚBÕÜÀzÔ5÷-›òæÖµ[‹2·Xk»–ˆ‰„õ²ùÄ¢'ª k2“O}ÿ>³}—g¾2¢\+eɦ XÆó<ž`[5À2Üûp7(Ÿå*3üGƒ{gq'6€p}÷tB¸@+éʪ7_}ýªÁiÌ+åSòs?rr}ªìÉrÝà@6LUÓÞ¾{¸Ëú}¦ß3¨\[ª©Ã›@ÔšêèP÷ 8>:©\ k{»ˆÈø¼úó÷ÃÙ%½¥ŒÁi¾ÓÌBU¾üÍ+Êõ¡RxÿÞ°HÅ0-¤·KX/î€}H\”K³oÿpï,—w6³P•¥jcͯK'9Þpg=yõ¶âù7®œÄÿø'î•t*®\›u N`£,kv¥voí27H@õwgeûP±íšç‰”«œ÷FpéÜ{sæÖ±sº€»ÁA:¨\õd©¦Þ>þì“wœævŸ}þ¼4›í÷eã1‘¾ç €–H½4Œ`¶²€}8Š1(¥¹p˜'àÞQ4¸è´±[kooYip€;éÍ©Ï ½yfBæk§1¯¿;+?ýCêðÑä‚'ZÜЫèÜ·pyp¿ºÅ}¡jp` ZîÊŸvúº2’Jr-6(NŒN)׊ép^«_Ð|·lí’‡l68Íwò<‘ÃGF”뛊ŽÄI„Ž,†q)¿`»3€}Ø»2ˆƒF îåÑà ÃÆ&×õº EV!›Ro/\Ï“Þ3;þɧJBq²Ö‘s·\á”nMƒûžaî""Ü= \[¤ÁUÓ´·oîÏ›Z-ד“çÕ÷B&|×*[®Èä¢zÛø3Ÿ¸[ÿg”‘+³ÊõÁRøþÎ0JÒàngC˰•ìÑŒA‹1?Ï®D î:mlb½ îïXž¼z{ñÜ× Nâ-ýyùÔ÷ïU®/V=›åœf5MÀ}×Vî""èÜ+lLõ¦ú³9ÔGÀ=(.ŽÍËRµý†8çÓÇ&=åÓ’‰˜üäÇö™è»<óu{{.åH1„7a” d î€e¸öaï ° 7Zt–K€»v‹w«7§>?ôücÒ²à†þÿö§>¨}|üÕW–jÑÿ{¢J·èÉœ$¸îÚÑ#¹Lû”i£%R×4e~Ñ6¸pŒc£“ʵ°­ÇçÕß+O>¶KzKƒÓ|§J­)Ÿÿúå:íí€9ñ8¿o†q6° wØ@ìÊ"tî°v®¢­ÖkÝ îIŽ÷¬NWÎÕ)¢™…ªœÐ„’¢b×–.ù…Ÿ¸W¹îy"çnybAÖˆ$Ýïn.ŒÕÁ É}{û•ëÕ@îÆ‹¡>n^ Šãš}ÉBîåª'eÍ?ó‰» Ns»¿}ù’”ÿöî;N’»°óþ·:M÷ä´;³« J«]å,PF$’’€ŒÁƒ ¶qÀøž³ßÙ¾çŒÏœm^ç{ì³Ïw¶À€ñ[Ɉ`@BaWasž™œº{¦cÕóÇHBÒvÕNWWWUO}ޯ׾ö·³óSOwÅïï[Kµó CZOÀðM‚€»ß¸CÀˆŽ®|d¼ÜwoÑàÀk®îdµ¬RÌzZÜýñqgœÏ¾ï mÛÒk;ž/Z:‡÷]û§5=¿ìãl‚sáÙƒúä½—:þó–Lrh%v î´·¿Ú¦¡NÛ±B™§—"|œîÃÜCaÏÑY•ÊÕšcm µ\›øTֲݧ$1Ý}ë6'ô_yhŸíX*!õ:,jà=Ü}Ç D w zØÙû(ÆË àî-Óâ"?ïŒÏæ]}]Ь€:¥“R»Ãüÿ5"-î’ôÉw_¢ Ïtü;ã „ÜVa×Þ.IíÜ_eóz‡w‡ 1”bÅþ¾a€{ìÜ7m;ÖÕbííÒÊ1 7^sºzÒ>ÎæÕ*US_yd¿íøP·A:¬)Üèᜈ˜ð”åt·ê41³äêëR-Ö‚ úPÀ=‘ˆéñ¦S6;/XÚ}”M))€°kÚ•hp­ÍÃöwÜ6¦%Û}pG:©Îö¤¿BM»LÙŽu¶XÀ=W´”+Úo ß{çgs²o?9¢ÉYûkCÝDÀ¿Ñç;^q b8º€&"WŒ0 ÁÝ[4¸ðÒäœË€{‚s=õëw¸?öô¨*•è4–oÛÒ«?ûÛÔvŠC39KO­j2Ë5! ¬ÜÓÜ_i¨¿]‰xíˆ@±BH áRrxªííá±sŸCÀ½ÍljxÀ©½ýô Ýºæ¢ >Îæd<¸×v¬'c(ÍškG«@Äp¢‡»Ÿ~b+‹ˆp÷”Iƒ;¹np'«À…î´!›\£²ù’žÜ3éï„vý%§é/ÿï;NÙð\©JûÆM=?jªè¶ ÜW/3´q]í`°eI%žX)UìïÇ ´û8ØY.V´÷èœíx+5¸WMiÊaAãýwîô©ÙÓóËzä û'. ÷´Îk ¬%yk¿ñ‚CôˆÎl|ãåFy±e-¢Á€—\7¸;@M†!õ¶Û_+zôÇö¡™µêº‹7êþæ«jyž[²ôÔѪFæ,U¡áTJÒNíIÖõflÇÌè<È-ÀiQ îáðü¡Um¶Á™””h¡DÒTÖ²]0•HÄtÏ­ÛüÐk|íѪØL0“:¹ kÓB‡“<™# b4¸{Šw^§Á€Ïú;¸¿ÖÕlÐÿú­;ձРlÕ”ŽL›züpUû'LåŠ\+‚Vuø¦ip?‰S«}•‚„HÉ!à><@À= vëjk­û“ã‹öÛ¿7^sº5›eI<¸×v|]—!n±øðùŒƒU b¸ÑÃÑ•Ÿ8“DÄcìî½Dƒ;/M̺ ¸sÍ€;} î{ŽÌjt*çãlÂãÊó†õ׿ýF ô¤Wõ÷MKšX´ôÌ1S;›šÊZ¢†SëøjžÎ5NwÜ&¥ŠýŽ•÷pصÚv¬3Ý:笹¢¥\Áþývÿ;|œÍÉžÜ3¡#ó¶ãC=­óZkEÞšŠÄ=œÝCƒ»·hpà¥IwÃ’ñ&L@$¤R§C£æ¿þxÄÇÙ„Ëe;Öëá?~—îºá¬º¾.[°´wÜÔ‡«Ú7±v/W›4I'qjpw sG•S«=—¿&EÇ÷vÿ&[N î«[3 ã ö¿­ºuíE|œÍÉœÚÛ;Ú Çc{MƱ“ßxň!àMãØ !@»·¸ðÒä\ý÷áv ês(=}ôÇÇý›H öfôÇ¿|³þüßÝ®áúÚaËUirq%ìþ£CU=}ÌÔ‘iSóK´»Íäôù"à~2§×Äi±à·’SÀ÷Àeó%Y¨9fÈyAe˜TMi*ëÐÞ~ÇvÅŒàþ[ò…²þệlLJº[ãup´ D gô@ôp†ã#š³A^tY‹L‹s&ÞÈ-•µTpHmØH%8ÏИ¾CÇgk_ãøÞ3£*•«JEüQ·]µEWŸ?¬ßù‹'ôWßÚíêßÈ-å‹ÒÈœ¥˜!ug u¥Wš6;R†Ò).Ø^púUY]rÇwÓlj§P¬Ø~7Ô¹ ÞÛu`Úv¬½ÍP«Ü&ŸÊZªÚlûñ˜Þý†süÐk|ó»‡m¯†´¾«E^h`²È[ûˆî@ôp†ã#ƒ—!ÀB oÑàÀ+ã³yW_—âª.€u¥ %âR¥zòØr±¢=7®ë/=Íÿ‰…LWGJÿñã×ém7ž¥ßú³j×~û ש˜–4¿di~Izéž|ÌX €u¤^ ½·­üžà‰Œ@]⟙ürÉ¿‰´ˆL›ý&.#LJ5ŽS$)‘ˆ©¿'íïdp§€{W ýxÆí7|w\½Uƒ½gs²Ük;6йrL 8tãùŽWˆn…ÑCÒÕG7"ܽEÀ€W&g—]}]ŠØdHêk74•­}ã‘'Žp…×]0¬o~áízzï¤þâ›/è¾wH•Jã5Ǧ%å –ré•÷éÛR:i¨-¹ò{:¡—ÿw*¾ÒÖ à'œîÙ¥²i‡w»cÀo¥ª}hp¸¿§‡ÀÎ}S¶cm­ñóÉ-å ö÷ýÞûÆ>ÎædûÏëÇ»'lLJ»[ãuÖ2‹–ßkCÀˆŽ®€ˆá"Ÿ·L–aðÈ„ëwÎó4®¿Ã>àþèëßÿÌÕ>Ï(Ü CºlÇz]¶c½þ݇_§¿ù—½ú«oíÖ‰iwÛr'ÅŠT¬XÒ²ôÚû÷†±€oKJ'¥¶äÊï餔IJ² äÜàNÀýµ/—¿¥Šý›qx ÃÇ™ÀÎÎý÷ip›·ŸmîÒuoôq6'ûòCöíím ©·k@à8x€¦"àDg9>2x¹4¸{‹w^qÝàÎU]pjÖ<<¶ Ãc :cc3jƒ½ýü{.ÑÇî¾H?~Lý/{õýc*•«MÿÞ–%ÊR¡li¡F>“Ò)C™¤V~¥Vð™”¡OÅ•p¸ž]*ù8“Ö°T¨ØŽ9-üT´›jà ÷ Í,42™«93¤ŽTøïM–*²]ì)I÷ß±#бJÅÔ×=`;>ÔÃ@$Ö"†[!ÐDç•îÞ¢Á€W\7¸ÓÎ  óK–&-Í䜯qüëGtÆ]Ü$â1ÝyÍéºóšÓU(Uôøózì©}çéQí92Èœ*¦”+XÊ^ú“Ÿüœ“q)4”I­´½g’RúÅÿM¨­Ìéý›[¢Áýµ– ö¯IŒmB¢äph÷o"¨É©½½£ÍP+<\úÄ‚i[¼œLÄôžÛÎñwB¯ñÈkzÞ~QüPw ¼È@ð/91ÜèáLÇG¼Øƒ ÛÖ"Üxe|fÉÕ×Ñà ^ÅŠ4¹hibÑ”C®ñUŽŽ/6wRkL:•Ð —ž¦.=M’41»¤ï>3ªï<5ªï<=¢™…Â)þ…æ+W¥rÕR¶ ½6Š¿¢ùýåߥöh`îËÜ_˱Á¢9a`p3ÒSUî<2á¢ÁÝ0¤d¼ “°f,•VBí“YKe‡àŽÃî¿s‡·‹°˜ahÛæ^mÛÜ«·^æË>Ÿ-jÏÑY½phöÅÐûŒöS±äòוª4³4[¹&Ö–Xi }éû$„E<¦šaÅ¥BEUÓbÑÎ+äZíy™%î¡eYÒ3ûìîéðoHÆæMÛ±×_¼Q;Nï÷q6'ûê#ûeÖZµ¥•ŇýáÈ :à7^q b¸ÑÃÙ11®H{Êî‚ÔËMƒ{Š !€ª¦4•µ4±h)[hìÚEWGJ¿÷‰×ëìM½Ívz»Útõtõ^þ3Ó²45·¬ãYŸÈjd"§ã“/þ>‘ÕÈTN•Š}(«ÙŠibqå½&Iý†6ö®„Ý %lî’´´\VWGÊß …ØRw„_±b<³a ÝÇ™àµNÌä5=¿\s,“2!ßÜÎå-9=Üã#ï¸Ð¿ÉÔ`YÒ—Úg;¾¾Ë`1"–Avš‰€;=œîøˆw„Oð–Iƒ;ä–ÊŽá";©çx~b±°ÒÖ>³Tm0ó|öæ^Ýwûv½ë–mèI{3AÔ-fêo×P»®8wè¤ñªiirvI#“Y1ô~dlQ‡ÇtxlQ³‹_ç;›·4›·”II{cZßeE VÚk_»Íp•¥¢Cƒ;©I„„Sƒû îÚéÔÞÞf„>Œ0:oŸï¬M=ºéòM>Îæd??®Ãc ¶ãCÝa… ©kCÀšˆ¢g„¤½EÀ€&fëoo—hp •«Ò䢥ñESËí“«ÑžNè­×Ÿ©{oß®Ëw QØÑâ1C;´a°CWžwòøB®¨#'uht%ð~xlA‡GW~_Ì7ø†q°\’Nš:2- wÚÔS’}|ä´°"·T’D ö%Ž îìS¶ ÷{3J&XI¤]ûî!_#™/Zš_²¿Ï÷á·]xqØîµël3ÔÑÆ†2A¾ã"†€;=ìì}TðQ±ÀK‚¾³Ö˜œ¥ð€ë€;WtH²$Íç-/®´e7zyâòëuïíÛõ–ëÏTg&éÉ=mºxÛ:]¼mÝ«þܲ¤¹láåÐû¡Ñ…Ÿ4¿.*_°ot®GÕ\iFÌVuÎpL}í\›„?œîÞ¼¿×Š¥eû×#êO`¨TWÂÕ•ª¥Š)%bR{›!z„üåÔÞ><ÐîßDPÓÎýÓ¶c]!_9´·÷vµé]·œíãlN–Í—ôÍï¶ê ÷ë DÑßñŠÃí z¸Šç£b©ôÜ=Fƒ;/Lº¸sŽDI¡,M,ššX´Ã^«ÑßÖ»nÙ¦ûnß®m[z½™ Z†a¬¼ú»Óº|ÇúWY–4=¿¼v1ô¾ûð¬~ôܸëà{¹*=?jjSŸ¡­1ž€¦sjÏ9º£ÈéõˆZÀݲ¤¹%KSYKsù•PûkÅ ©·ÝP_‡¡Nƒ'*ù T±¿³a€§1ɲ¤Ž îáÝá—«ÒdÖþ½õþ7«L[°ªÿóÝC*ØôÇ i]Wx__ ²H¸ûˆî@ô4ï¤8I±BÀÁ#àî-î¼@ƒ;;¦%Íä,M,Zš_jì:DÌ0tãå›tïmçè¶×mU2±ä"VÅ0¤u}­ëËèªó‡_þóJÅÔ3û§ô½gÆô½£zrϤ*u>µtdÎÒ²©íÃ1¥yXš(á:^Ìskì%–%åmîQ ·ç +OE™ÎY:Õ­<Ó’fó+OP9<%mì3´¥?F«{Ü ¸éȉÛmj"®PïëOÌ›¶9ÔD"¦¾ù<'TÃîµè4Ä¡<>+yýFXˆn‡ÑCM…–‹Ü¼'Už2Y… À³yW_Gc$°vå‹+a»©ÅÚ ²õØ4Ô¥{o;G÷¼ám$w‰˜®8wHWœ;¤Oßw©– =þü¸ýñq}õÑýÊ®24œ-XÚy¼ª 7ÅÕžjò¤YN¡¿±©œ ¹b¹¢ªM‰KÛËeéÈ´©™œ»ëü¦%ÌZšË›:gÈPG[^´8=µfÇ5ÚµÚv¬+ÄŸÓ’N,ØîßvÙZßßîãŒN¶÷蜞Ùgߎ?ÜÞ׈2‹ì4w z¸û¨T&àŽàÑàî-³ÁÌ I³Ë®¾Žw`m©˜ÒTÖÒÄ‚¥\±±ã©d\o¼ötÝ{ûv]{ÑJà¹ötB7]¾I7]¾I¿ò+ôõGèÏÿáy8>ʯ-W¥Ý'ªºds}þKÿ¦‚C2qbÑRo»¥u]¼iá­LÊþ=uxlÑÇ™„[Þa[cÇ™Ë%iï¸ÙðRNåÀ¤©D,¦A¶kž):ܸ¥R5õÜAû€{W[8?óK––JöÛ¼#øöö‡?¦¹lÑv|}w8_[w b¸ÑCÀÝGEÜ4¸{‹w^˜[´¿ym'!V e –FæVÚÚuõtïíÛõ¦ëNW¦[<ÃÞsÛ9ºlûz}ì÷ÑÞ£s¶÷À¤©îL\¼…᥶„3Tó©'¦óZ.VØnJr:”\K‡™ã –M™u?%%Ó–ÐÙ›zÕÓ™R©bjß±9Í;„N_²wÂT<S_ÇZzƒSªØÿà6Ðà˜Ççµl³ú •XùFNííglìÑ­Wnöq6µ=ðà^Û±¾ƒc& Ä*^?"§BXˆƒ€è)=(Y&àŽ ÁÝ[&ÏàÕe^+oÂD4…%i6gitÞÒârc×Ö÷·ëÝ·nÓ{nß®Ó7t{3A I¶méÕ7ÿàmºÿóÿ¬'^¯ùwª¦t|ÖÔÙë×X]4—IÊÛ´u9±¨sOï÷yFá“t8 \ Ý.媴ÂÔl~õÿ1‰DL7_¾Yo¿ñL½áª­jOÿ$BQ5-}ï™Qýî_>¡çÎØþ–%í7ué–¸ÒɆþ"Ï´V~޵tf’êÌðe×Öko_*IsKöÛƒ¿íüÀMçõØS#¶ãC´·¡V®p÷!, b¸ÑCƒ»ŠEŽ­<ܽU] Wù*›/©ââX2Îùv¦%M.Z3µÜÀ•ØxÌЭWmѽ·o×Í—oR"N­#Jè~ùfÝþ‰¯k!W{A×tÖÒ™ëV·¯d’RÞf á¡Ñî’RIûýI«w»Ìå-í›0mÃѯzÿ›ÎÕ§ï»L=iÛ¿sãe›tÝEõ_xZ_üòÓ¶¯SÕ\ ×_¸‰}v#Jµ Â%Iô·ê™}S¶cépîÐÇæíÏ»{:Ût÷­çø8›Úþöá}¶Û•d\àÉ@¨•ž:‚¦¨¿1@K#àD î>ª˜¦LÓ"`Œ¶ ”ã IDAT@Ý<°Ö˜Ü4hv±àêëhp«\•N,X:1¿ú`]-gžÖ£{oß®»oÙ¦u}ï&ølã`‡¾ðéôÓ¿ýPÍñйFèäÚ%¼“NÙ]ðo"!–L8Ü}œ‡—,K:Û6à>›·T1%‡Bi .‡MéaÜ%I)‡\«抖v™Žè—†ô3ï¸P¿üþ+”jðžÝ'î¹D'¦òú«oí®9^5¥“¦.8›%§€û@»Á«[T±Tû1Em‰ð=mÌ´¤±yûÚ[®?CÃ!x"ÀíµëJjOq³XÌP ®lu܈!àDO)è DMÕl±+‚Xsb\Cõwš[tw/&çæ6$KÒlÎÒ蜥ł»ëíé„Þý†sôÞ;whÇéýÞN¡[¯Ü¢®Ž”²ù“oM˜–4¿diwx$ã</i¥)þÿýäõºï×ÿÉöïŒÎYÚ6Ä}šÕ*Ukÿy"SOÚßÉ@’”[.ëØxíE†!e’áy/—¤Ù¼ýÖâÃo»@ñXðó}àÁ½¶c™”Ô ~ŽNÍÁö$‚¸CÀˆî>«V ¸#X1N¬«†EÀhp÷Ÿiš]¬¿Á=£ÝðÊü’¥#Ó–rEwçøgoîÕGßy‘ÞqÓYJ%Yy¬Æp‡mÀ}åz;9x££ÍP".Uj£sËe=hFo[çÿÄBäÌÓzÔß®yLZ5¥¥¢¥Ž¶`>“–%™15:·º}ô–á.ýÙçoÓŽÓû›<3gÃzçMgë+ï«9>³´uÀçIµ ¢Ã‚†áÿ&‚Wq ¸·´­¨etÞ”Ý-¼xÌÐO½õ|'dãËÕÞNHR_‡¡§@Ë àî@Äp¢‡€»ÏLÜ0Ùè-Ü4j.[ÿ½˜…@ÃrÅ•`ûü’»sûk.Ü ¾ë"Ýtù&®·uʤíoIr ^ëÉšÉÕÞÖÿ`׉ÈÜ Cºâ¼!=øÃ£5ÇgóRG&)”¥='ÌU/@»éòMú¯¿tshž¢òÑw^dp_.IK%ç' @*9ÜÅ&àœ=N îáøø©\•NÌÛo;ÞtÝ:m]§3ªmd"«ï>3j;>ÔÃ9ÐZøÌ€€;1Ü¢§ô¢¦ÂÕyŒwopЈ|¡¬RÙ¡šÐF2ιàV¡,í7õÌ1³îp{Ì0t× géÿàíúÊï¼Y·\±™p;àB¦Í>ànr ëÉØo§ðì g^W7l;6±èÿ‡r2kéécÕU…Ûñ˜>ÿ¡×é/ÿý¡ ·KÒ¶-½Ž‹'ì]à'ŠUû×hà ÷ X–´û°CÀ=ŽãâÑ9ûövIúø=û7_¶Y#IɸÔߎ×Àêpi ܈¡ÁˆÜ}V% ‹€ñh,oñ™Ј¹Ew÷a<¦¨[¹*Ÿ5ubÁ’Uçé|{:¡ûnß¡¿í|mêjÎiwjpçr<Ö“±{üùqUª¦ñh÷ÀÝ|Å&ýöŸÿ¨æX¡,Í/Yêõ!hY5¥ƒS¦&W·!Ø2Ü¥?ù•[BÛÂçµ§kçþ©šc³yK›û¹_ãĹÁ½Ý¿‰àeã3y-æk÷ç%âR*‰£rU:±`¿ ¹ýê­:ÿÌgT[Õ´ô•‡ìîCÝaY ÅX4¸€;1!8Üà3Ü}V¥Á‹Óàî)Ü4b.[põuIîÀªUMilÞÒÈœ©z/Í­ëËèCw] ÷ݹ#T­°@«koKÚŽÑà¯u´JÄ¥J‡æä–ËzîàŒ.9'œi¿œ³¥O—n_¯§÷NÖonÀÝ´¤ó–ŽÏ™5Nµ¼ý¦³ô;?÷zu¶ÛoO‚öÆkN×ïýå5ÇrÅ•wXí•Þ Ã4¸a÷‘ð··Í;óúÞKý›ŒƒïïÓØtÞv|¨;Ú ¯`•ȼCÀˆÜ}V! ‹€Ü=Uᎀ¸mp'àœšeI‹–ŽÍ˜Ž©ZN[שOßw©ÞyóÙJñ—-êŸpÄv|¨;ø×@ýH øŽ#) ‚¸dDÌÈc_´$­ò²¼P©pGð1vù^!à ³.îIN뀚–-íàÞpãø©ÚÛo¼l“.ݾÞÇÙûú¿îWÙ&3Éó§eð±ßp"(ô¢,>ÿ¾)Öûà¾Ìs¶m9ÝÃìåÚPÊSGlÇÛSÁ†²OÌ[rê™ûô}áho·,é÷ÙŽ¯ë2Xì´(‹Ø€ß¸DÀˆ¦’$®ødyµÏYš(7V–¶ aÜn,äJzáØ|ÐÓh9< hž¹ÅÛ%ª4}ιmp'üH’ŠéØŒ©‰ÅúÏÏï¸z«~åWjÛæÞ&Ì €“ã9Û±xŒÖR4GOÆÐL®öþâÏž à.©§³M¿õ³×èç~ïQÛ¿“/Zzú˜¥áCë» u¥ ¯ùØZ–´\¶´¸,Íä,Í/[®B_×_rš~ÿÓ7hÃ`ë.BÛ<Ôe;ƃì•+öo˜ž´3ÁKŒÌÛ>í" ö ,US³ÿ@]wñF]qî3²÷ìií9bß„?ÔÍqЪ¸ûŽ€;AÜhªãa½hÔr‘€;‚ÇM"ï˜Ü.ÄØ»br…h¶Kîxq>0»Hƒ;àFÅ”FfMÍ[u?üŠs‡ô¹ŸºJWžŽ 53 ÏäkŽÅ )ÅÝJ4É©î{×E>Ï(œÞòú3õÕGöëÑwü{ã –Æ,ÅcR&¹rR©j©P’9R¾hÛ ~ùýWè†K7žo5Ý)Û±ZOÀ ÜÃÇ)”]ÏšáÄBk´·KÒîµkOI]éßèFlÀwÜâ’M9IÔRø¤@À!@ÀÝ;4¸܈µúÝÙ€°° h¶Kîx±ðf.ë¶ÁŸ¢É´¤±yK#³¦cˆ¥–³7÷ês¼Ro¸jkˇå€VöÂáÛ±Ž6C|<Ñ,=™ØÇŸW¥j*dqH†ô…Ïܨ»å›:0rê§}öýWèö×­}uwg›íX…ë¶J÷~ܱû°CÀÝ~GÓª½ýu ëê 6ø8#{ËÅŠþî±¶ãCÝ샀VÆnÝwÜ"àDSíª4ÅR€;‚GÀÝ;ínДì î@ó°]rÇ‹óy· îÜ÷FÄX’&-›1UoÄP»~é}—ëî[·\BàÙÓ¶cö9P am†ñÚ­ÙùBYϘ֥Û×û?±èIë+¿óf½ûsÿ¨ÇOroÔéºõ‹ï½\o½áÌ5wÿ¢+“´«w±^”86¸;­VAÓìiƒûø‚åø~ùô}—ù7™SøÖ¿Qn©\sÌ0¤õÝkkûD ±ßp"ˆ€;M¹ '%ùBí“VÀOqšþð´þôïžUÙ£Êñu}}âžKôÞ;w¨-µ¶UÓªn—¤Çõ¶œ¹ ¸ûo>[ÔøLí‡ÂÇ )mÿ ‚¦:U{û§î½Ta¹ÜqôÄ¢~ðì Ûñ!ÚÛ–ÇÂ5ßp"ˆ€;MµÏFÑnn\^KpÕÔ3ínpwÇô )@ml—Üñâ| ·\ÿ“ÞhoGLç,š4Uª£+Â0¤wݼM¿ø¾Ëµi}gó&Àµ¯ÿëÛ±LJê ÁMÖ×nÿ{b÷„ò…²:‚Jj†T¦-¡_ýÀ•ºïöíúÿãqýóŽÈÍéù`oFw\½Uoºî ]sá%#²j³èp0ôì9Ü3þM’¤=GíŸâÐÑf(ˆ·ò©ÚÛ/Þ¶N7^¶ÉÇ9ûòÃûlÇR çý€ÖPôh! V€;AÜh¢ÁÝGÙ¥úo\^‹sÕÔ3•*'ª€úÑ”ì Ë€æá)OîX .¼)–ª¶mŽNøya-+V¤ƒ“¦fóõ}¾n¾b³~íƒWêÜÓû›43šY(èÏÿáyÛñõ]Ñ»"X™”Ô–XÙß¼V¥bê‡ÏŽëÖ+7û?±°uC·þôsoÐèTNß~rDß}zTßÛ9¦…ÜÉÙ¢˜aèôÝ:{s¯¶oíÓ—nÒç Eò8v¹Ö›íEtÙs ¸÷Òàî·Ý‡íîí)'ò ‹–Jö/}ú¾ð´·WMKûð~Ûñ¡n#4sà^¹Âý Ÿp"ˆ€;M4¸ûh!Gƒ;‚Å‹ÈÍR%hp}±;4¸ÍÃÂw]x㦽]¢Ák“eIcó–ŽÎ˜ªç£uñ¶uúÜO]¥k/ÚмÉðÄïÿ¯'•ÍÛ__×ÅñüÑÛnhb±öÎæ;Op?…ÓÖuê½wîÐ{ïÜ!Ë’f–U(VT(WU(VÕ–Škëp—RÉxÐS …‚C—ó0{N!AÜý·çÈœíXO_1-idÖ~±øg èÖ+·ø8#g>qLã3ö‘Œ¡nNòµ P¢ÏgÜ"àD î>ªÕdøPw¸܈±/v…w yØ.¹Óè›<w@’”+Z:0a)W\ýgêô Ýú•\©7_wm‡@ عJÿûŸ÷ØŽwg ¥“>N‘ÖçpjÔçÙ´6Ã{ ;É9<Ù™Ó0{v îñ˜¡žÎ€*Ã#l÷û÷Ž6'ò¢ÉE«æ“8^ò©{ÃÓÞ.I_úÚ.Û±Ž€5£HÀÝoËAO€ÿ¸ÑDÀÝGó4¸#¯x‡€;À ºÜ±hpš†swkpçÇ…5¢jJÇfLίþ³ÔžNè—Þw¹~ê-ç+‘`µРƦóúÐÿóã°­ìÜàŸžvû÷Û‘yMçµq°ÃÇa-›²¿ ›"QSÕ”í}úºÓ\Wó™iYÚ{Ô>àÞžò÷çaYÒq‡öö§÷ëö«·ú8#gO¼0®'^˜°êáý ¬KN+oÐ ‹AO€ÿ¸ D“ýó°à¹éÜ<ܽCÀàARwhpš‡í’;n–òËîÁÓàŽµ`6oé©£ÕºÂí·^¹YüÉÝúÈÛ/$Ü´ˆÜRYü÷ÿ¢ÉÙ%Û¿3Ði¨'ñü“ŒKiû÷ÜwŸ¦ÅÞ²¿ ÛFÀ½&»öv‰'áøxVK…Ú¡ÍTbe›ê§Éì©ÛÛôâO¾jßÞžŒKƒá™+€Æ,v`h†lÐà?N¡€h¢ÁÝGùBY–eÉщ5¢‡€»w¸Ü HêŽSã#€Æ„éæo+i¸Á}É]ƒ;¹^´²RE:4ej:·úÏϺ¾Œ~ëg¯Õ›¯;Cl®€Ö12‘ÕOÿöCÚ}ľõÕ0¤3Ù±Á½íR®P{ì±§FôžÛÎñwBX³œÜÛØÔR®Ú'ô¤}œ $9îÇ;BÖÞ¾mK¯ÞtÝéþMèöÓóߨ—‰µc¹d¿}BSp"ˆ€;M4¸ûÈ4¥B±¢L:ôTa„ê¼Su¸Ð €‚¤îÐà4çîX .¼É-» ¸ÓàŽV5¾`éÈ´©J÷|ßÿÆsõ«¼RÝ©æM €ç¾¿sLûÝG4—u~¢éæþ˜¸TŽ ôµ™­},÷ÝgFU5-Šbà‰Q§€;Û¿šœÜû» ¸ûmÏ‘9Û±ö6'"i*g©àpý©÷„«½ýK_Ûi;IzÃ3WIÄã2-Ü}FÀˆ î@4Ñàî³b‰€;‚Å…yïÐàpƒ ©;&(@ÓpŽàNP îü¼Ðj–J–LXZ,¬þ3³mK¯~ï×ëÊó†š83^›Ëõ…ÿý¤þêŸvŸòºÙ`§¡-ýìÓŒ®´¡xLªÖ8ÏœÏupd^çléóbXsî¤3jr ¸öfü›$¢Á½Í¿ý¸%çöö3OëÑ[®?Ó·ùœÊÈdNÿØ!Ûñყ³kH"z QDÀˆ N¡€h"àî³b¹ôq±WL¼R%ip€»;ìwæa»äN£ ^ipÇZgZ+!”‘9K«}àA*×§ï½T}×EJ’øZF¹bê/ÿñýÁ_?¥Å|锿+mèœa>ãN̺3†æòµwPÏœ!àŽ†Y–tàø¼íx[‚ó°Zœî=4¸ûm÷a‡€»YšÎZZv8Äøù÷\ªÅàÿýϪRk•$ÃNëå8XKÈ_‚€;AÜhÊ=¨)–¸#X‰]àiu4¸Ü HꎹÚd€º…éÞ­¤ÑíRž€;Ö°ù%K&Mêx›_{Ñýî'^¯36ö4ob<52™Óß<¸W<¸W“³K«úštR:ocLœ!h]mҜͲçNë7Ÿíï„°æŒMç4³P¨9I)Ò5•«öçY=4¸ûi¹XÑ‘ 5Ç I™”;s§öö-Ã]zûgù6—S™],èoþe¯íøú.ƒÏ?°ÆÄâ4¸`1è ð‡P@4Ñàî³bÉ¡zð¡:ï8]hÀARwL–MÃ9‚;n—rNõs¸#ÌÊUéð´©ÉÅÕ>úºÚô¾Zwß²M&á·+ê;OêoÙ¯o?y|ÕOh¤Î´¡ó6Ä”$ÿèH’ìÜFíÚ?m;ÖÙÆA§aÓàî¯}Çæl÷ó™”áÛbµÉ¬¥%‡ÓçO¾çR%Bt¢üß|AËEû7ò¦¾ðÌ€7 .fw ‚¸ÑDÀÝg%§+3€Âôˆ¾Vgš–,­4U°ZIݱ¸MÃvÉF·K4¸c­™\´thÚT¥Žn‡»oÙ¦ßøðëÔßMX «JÕÔ®ýÓúöS#zì©=³wÊÕSLÖw:{=Íí§€ñs‡fdYbá²kÿ”íX'‡>¶ÊÇ’ƒ½¼p~ÚsdÎv¬£ÍŸ9˜–ttÚ¾½}ÓúN½+DOÜX*Tô?þáyÛñNC™”à î àDw šlÀˆf)ÐàŽ€^ñ–eYœ´êBƒ»;äÛæa»äŽ›pß+å¸c(”¥“¦æ—Vÿ™Øº¡[¿óñëtý%§5qfV˲¤éùe]Xù5¶ ƒ# :<º #㋪Tìƒe§bÒƒ1m£¨ÒL IDATìåxáÒ–qÕ\˜•Í—t|"«-Ã]þO kÆN‡÷.Üm9Üû»3þMÚ}xÖv¬#åÏ{xlÞ’Cº>~Ï%J$Âs’ü7îÑ|¶h;¾©Ï>°YÔá€;AÜh¢ÁÝgÅ î îÞ²LKŠóšV/ž{.-Å$á4 ‹`Ýit»”[rpçç…ð˜\´tpÊTu•Ù×D<¦½ë"}òÞK”NqK­¥jZÊ/—e¹\àÇ”JÄ”LÄ}k…6-K…bUK…² ÅŠ–Šå—Ë:>‘Õ¡ÑE9Ôîv¿äd ÃÐéëbÊ$=ÿ§Ot¶¶ ´ž=8MÀ®Y–´Ó±Ácz;åªý~–wí9jpo÷¡Á½R•FfÚÛ‡ºôî7lkþDV©R1õ§_Öv¼'c¨‹Ï>°&™܃@Àˆ ®&Ñ´ô¢¦X¤ÁÁ"¼â-Ó²z€–¾ØF›’Øc»äNà î®î }[ÀUS:8ij2»úÏÁå;Öë÷~þzmßÚ×Ä™§fYÒb¾¨¹lQóÙ¢æ šÏ5·XÔ|îÅ?Ë^ûÉŸ-æ‹òê4‘ˆ©-W2S*_ù•XùßÉDLm/þþª?OÆ”JÄÕ–ŒË’¥¥BEËÅÊË¿/¿üÿË+¿+*ô4ÑŽ6Cg êmçáÖÙ&ÍÛÜ%{îÀ´Þ|ÝþNkƱñE-æK5Ç1)ÍÂ[v î‰xLÝ>¤ª!iåxé…C3¶ã><…àØ¬)§‡Èüêÿu…RÉðÜ¡ûÆwjl:o;¾©Ÿã"`­²,>ß>3EÖ ˆ$î@<öÅê¦?¹,‰gºùd™wŒðŠ·h“Ô+æW]ãÃ>h¶Kî4º]Ê/» ¸‡èé눨\ÁÒžqS…U¾…;Û“úܯÒ{߸ƒí |5Ÿ-êðØ‚-êÐèÊï+ÿ¿9måõ¨TLU*¦TtžëÉî14ØeÐaˆ–ÐÙfHª}L÷œC°8ÚÛÝ©š’ÝiVOÚ·' @šË4—-ÖKĤ¶&§‹ eéÄ‚ý9÷EÛõÖÎlî$ê`Z–¾ôÕ]¶ãm†úXø¬Yî]ø-;òØyÑ"àDWNÜ}S àŽ€ñ8{oq¾ ¨W,F2Ñ î@ó°Ö†Ü]Üùq!H#s–ŽÎ˜«n±~óugè7ö õ·7wbˆ¬ÜrY‡ÇtäåûOíó6¡,x+—†º wÇ”I= >N ÄÇ'²>ÎkÍÎýÓ¶c]i'ÒbìÚÛ%i ›ÎOGÆmÇ2©æŸ”™v>çøŸ~]¨Ï>òÄqí;6g;¾©/s£n½rs“g†µ¨jZÚwlNO½ØÎþÔž YzZ‘’ŒK™”¡LòÕ¿§“¢¡kZ<&Uk<0,_(˲D(u;8² |¡ö½Àd\j#•aË)à>ØCƒ»ŸŽŒÓà>“³´¸lþqßÛµmsoó&àŸ|u—íX2. u³#Öºb™{>#àD§R@t僞@”Ì.ƒž".Î)OpÔ‹¦dwÌÞ àîN#çù¥•ÀT½8Ÿƒ_–ËÒÞ¦rÅÕ½Q_ñFýá/Þ¤õýíMžÖ’ÜRYß~jD?~T>q\sÙp_7MÄV‚°nç-kå—ùâ/ëÅ?k–˜±ò+“b1)nŠÅVþ,×IAö‹¨QvwË’–ŠeuðÈÔi×~ûöö.ÚÛ•ÖÐàî«£ã îMÚ,¾´ÀÖN{:¡_¸ÿòæ|s—öÓóߨc¡ Å27/|f¿“°¦p¢‹wM/‚ž"ŽP·h“Ô‹ ©;,*š‡sw9pût7Üá‡ÉEK§Ìša¿×ŠÇ }öýWècw_Ķ«r|"«‡~tL?~L?xî„*•`‚+ º†ñ•àz"¾òg‰˜±òû‹¿’±Ÿüf½Å_¼Ÿô»eóç+_÷RX=þòïÆ‹Aö•ÿÏGX§ã«üwÔo×)Û±Î6'Ò‚ÊUûs¬^î~rnpoÎAÆø¢¥å’ýøÇÞu±Öõ…«ÉÿK_Ûi;Iz9 ¢ @ÀÝo4¸EÀˆ.Ü}49·ôq„ê¼EØP/ƒ¤‰+,*š‡sw9 àŽ0ªšÒÁIS“ÙÕ½·7ué>{³.Û±¾É3C+«š–žÙ7¥‡tT=~L{Îùö½±•fòô+›Ê“R:dmå/5­ŸŒý3à‡•'äÔÞ÷å–Ëb/‡z=½×!àNƒ»£RÕ~l '\Áæµl1_Òìbí¶—z­jJÇÚÛ×÷·ëgÞq¡÷߸#“9}ãÛmLJ{ÂuÌ  y N;04w ¢¸ÑEƒ»F§–‚ž"ŽðŠ·ÛêžØ*‹Ê€¦¡uÙFÎòÜ2¹‚¥=㦠«|kÞuÃYúÝ_§®ŽTs'†–”/”õ§FõÐãÇôèÇ4Óä'Zv´½^O­4ŠfRR:¹Òħâ>t{̆èZȵsw·ÊŽwÜýrô„}{{:Õœ÷ðÈœéøóÿ¥÷^®öt¸"MÿýÏÚ^¯4 é´^Nà¨X.V‚žBÔp"*\GƒüDÀÝG3˲,‹àÄ ÕyŠw@½’ºÃ>hÞ¸Cƒ;ÖŠ‘9KGgL­fÍF¦-¡ÿð±ku÷­çpm ¯bYÒãÏëËíÕ7¿w¸i7øq©;m¨+m¨;#u¶l4ÄéP˜°êõ½c¶ aÓI)Åâ+GÜÃáˆCÀ=“ôþû•*ÒèœýÉÈ9[úôîÛÎñþ7`v± ¿þç½¶ãë» ¥H`‘±T ÁÝg܈âð ˆ.ÿž ULSKËEu´·=D¡:oY4¸êDÔžš4Á9‚+Ü—W[“ýq~TðP©*í75¿´º÷òùgèùµ©§É3C+ŸÉë«ЗÜë†r«£ÍPwZêÊêNJ7!T ÚJy¤ÎvžT‚ú<öÔˆíX_ó§R®Ú—öd|œI´9Ó5ãXìèŒ)§Óë_ÿÐU¡+ïú‹o¾ BÉ~Ô¦>V`Q‹ÅT®p÷™÷´î@tÍ=¨É/—¸#0„ê¼E›, ^ì‹ÝaŸ 4OØn·ŠFÞœ’TøQÁ+sK–ö›Ž-™¯ôá·] _ûà•J%©…T®˜zøñczàÁ½úö“#ž-DŒRO»¡ž´¡.ÚÙø¤X¶ß†mZßéãLÐê,KzìI‡€{;ó§bwlšHÄXpâ£#cNwoßÇù¢¥‰EûíðuoÔÍ—oöô{6j©PÑÿø‡çmÇ: ex»‘‘HÄ%¹+²€k4¸EÀˆ.î>[rÙÔxP·h“Ô‹§©¸S5Í §¬Yœ#¸Suh<•RÙÝ6¶}4ʲ¤#3¦FçV÷þíïNë Ÿ¹Q·^®P ‚±ïØœxp¯¾öèÍ.<ù7S ©¿ÃP‡¡Þvƒ…<|eZöÚÎLR]jQ‡ƒ£ó›Î×3 ©'ÃNÎIÅ\9V­e ;-N…üãÔàžñ¸ÁýÈ´óyɯèªÐýìÿæÁ=šÏmÇ7õ…lš*‘ nî@D±Å¢‹€»ÏòËÜÂ+Þ¢MP/öÅî°Ïš‡…7î4²Øµ´ÚÚì×`‚F,—¥½'L劫{ï¾þâúÃ_¼IëûÛ›<3„Yn©¬oûþ+ô±»/â¸%¦ç—õçÿçyýÅ?¾ l¾±k™1Cêi74Ða¨¯ÃPw£„D±b<·i}§3ÁZðØS£¶c}íSJÉá Yý=igmK…Š&g—jŽÅcR*îÍ÷±$vhoO%ãúìû¯ðæ›yèß9hû¤IÚÔÏgˆã #êAÀˆ(.)ÑEƒ»ÏòK4¸#8´ÆzË4W‘à’ºCÀh¬î4pwª'tÀ õ²$652·º÷ëæ¡.ýÑgoÖe;Ö7wb­‘ÉœþÛ×wéoÜ«bÉݶJZ µtì4ÔÛNk-€p*8ÜªÙ¸Ž€;V¯Xªê»NØŽ÷vø8™å´x°‡w¿Ÿ°Ï ¦“ÞN-ZÊ;h–¡CW9(–Ý-”eêQ5¥½ã¦fó«{¯ÞuÃYúÝ_§®ŽT“g†0Úl^üÕgôoTµí[gÚÐp·¡Á.C ö/BŽwxå‰Ý*”*5Ç’q©³ùS)×~ù$I4¸ûf|ƾ<íQ¢È´¤£3öçÄ}]múÄ»/ñæ›yè‘'Žkß±9ÛñM}|Î(ªZ|ö°ôƒ€;] Z)tâÈË'Ùw‡wo™„íu"Hê‹Ê€æaá;œ ”œê p:‡Õ*V¤ÆLÇVÄ—´§úí^«»o=‡§DÐÓ{'õG»Sþð¨ë#—Öwê6ÔA€@ ):4¸pG={jÄv¬—FçUq:Eè¥ÁÝ/“³K¶c)Ecs–Š >uߥêá¢Û/}u§íX:) vòY¢¨\å¾E‚ž€`p"jä±/š›nü䜤þ ç yîwo™îŠFÔî@ópŽàN# ÇnîìB°Ù‚¥ÆLÇÐK.8k@ôÙ[tÖ¦žæO ¡aYÒ÷žÕýí3ú·]'\ÿ;}+¡öþƒ8ZRÖa!ØÆuܱz=ipï#à¾*NÁnÜý21·l;–J4þ^.W¥ãsö7Ö¶nèÖÿõ¦óþ>^{â…q=ñ„íøi}1Î׈*•¹o᳊¤lГ î@´p÷Ñìb1è) ÂÕy‹w@½ Ò?®pšÇàÁ•F¶K4¸£Y¦²–öO˜ZÍÛó#o¿@¿ú+•JÆ›?1„‚eIÿòÃ#ú◟ѳ¦]ýé¤4ôÿ³wçqz•õýÿßçÜ÷=û>“}% B ²É®‚("¢X­¶j+•еZµ._mµV­Z—FÔVl ‚’¶ ›!± „„„ìÉdö}Ÿ{9ç÷Ç(Îufî3÷9çž9¯ç㑇>¼î™ùx/×Yî÷õ¹jlͯ±TÊ·Jf±ñ¬4jèEd[–Ö.¯· ÌZ=#zöPqœîÓãu‰ÔTGÀ=,^Ü qÙp´ÇQΣqÔÇÞq¦RÉâÛþò†Û·ÇR iA Ÿs ®F ¸‡­«yóFžt ¦¸ Ä[¤ÕQÝcQ—€Kˆ((Âv€|±ØÌŸ™tJàîþÌäZ`<ão+(!ðr¤ÛÑ‘ž©ß—å¥Iýë‡.Ök_±2ø¢P4¶ïíÒ§ozTÛvµùúùº KKë-Bz挾ó1sà óT]Yb5˜Í~ê˜q¬²ÔR )Œiñ ¸7Ô–‡WHÌyÜgú^ÍH­ýæ¹÷ôçëŠóŽ›Ù ÀžÃ½ºÿ±#ÆñÅu6‹Ñ÷׾uG]€èpiÄ›¹µ ®£Ç¼½4Â+…å¶ä‰Åfþ°¨ ó’?3Ù͉î($Ç•žksÔ54õ{rac¥nùûË´~uc•¡´uë‹?x\·?¸××Ï7UYZÚ`©ª” ÀÜâp?ÿe‹C¬³Ýæß4Çê*B,d–óìà^K÷°tôp?ÔéÈë2ú“~vQ.ê¾ñާc [ZTW„EÍð(÷pbŒ€;oÜCÔÒm¾9®±…5“P ž,Ò‰¾ÐÁŽÅ5‚/¹wD/•vµ:›úýxêñMºùS—iAI«8Ëê;?Ý®ïØ®Ññl^?kYÒüjKKëm•ÓÀÀåp¿ð´%!V‚ÙÌq]=üs÷zv>™¶ŒÇõU#ÜCÓîÕÁ=áÿýÜ3ìª{Øü_~îJ¹nïß”æŽ!ÝõËýÆñ…µ–’vˆ(:£™¨Kˆ›®¨ î@¼pQKçpÔ% Æèà^Xt“ä‹ ©?sàpàOÜ9„à…†Æ]=Ûâh:Ùåןœ¾úÁ‹T^Ê×s㺺ó¡ýúçlS[w~÷ mk"¤³¤ÞosÙð¸kì]^šÔékç‡[f­ºÕ306é˜mI5åœÀO—é3Y’J¨²<n11åºÞ»§|žæi‡cO&l}ügúûå»é®Ʀ–%-©#ÝÄ›¥Á‘ü”cÆèàÄ·+x#࢑ñœÆÓY•Ît/7ÀÂ+…Ew@¾,M lç‡î@pØåÉŸ™ÌKãó—û^x­ð;ÝC®ö´9šÎÛð|š>ø'§óþ‰m»Úôé›Õö½ù54KÚÒâ:K‹êl¥E¤Ïc“ݳ×/T “!¦i³G÷öÚ ‹˜¦)ëL„«'ÓX[ÆBß ¤5–ž<¨Y’˜¸§éÇÑïE¹o{í‰Zµ¤ÖçoNÏÀ˜~|ÏãøüjK|ÕÄ[*•PÎ!à2:¸1Æ©oÜC6<š&àŽHp/,‰?’¶¥4ǼpÌ‚Ã5‚?3™—üvp·iIͽ®uM½H¢$•ÐW?p¡®ºhuU!JGÛõù[Ó¦­óú¹’äD×É…µ–Ì/b¤oÄ|wÁË–„X f»ÍO4Çê+¸Îš®ŒG6°©¶<¼Bb®½×¼ú§$éïý<<îêXŸyÎm¬-Ó‡ßv†¯ß´[7í2þ%ii='Ð@Ü¥RIIãQ—7tpbŒ”%o½Q7ãi5ÔVD]bˆŽm…E7Y€ ¤y˱k ‹k_¢¸óRÅ›ãJû:u LýÞkª+×÷?y©N?q~•!*éLN_ÿÉ“úöÛ•ÉNgÛ’–6ØZRG°@ü8®Ô?êp?€;¦gp8­ÇŸm7Ž×pŸ¶LÎü™l¨- ±’xëè5Ž¥|¦‰öwºÆîü’ôÉ¿8[uÕ¥þ~y€FƲºåîÆñÆ*Kå%! (Ù6»þD€€;cÜx£ƒ{ÈFFÓQ—€˜¢;caÑMà÷üqÌ‚Ã5‚?3Yì껃;/UlerÒ³­Ž<y¿sÒÊÝò—iɼª*CTžÞÛ©~m³öéËëçæ×XZÙh‹%ÄÕÀ¨+Ói\S]¹Ö®¨· ÌZl;ªlnòf¥I©‚ðë´y]5ÕpKGGwÎö×óúåœõ‹ôæKŽÏÿ‡à¶_ìVß ¹+óÒz.ÎH6[-F¡+êD‡Û™@¼pÙðh&êS„W Ë¡›,À‡D‚ãq¾Ø5—þ̬ƒûô;-¿¯U<¤]íjq46[I—žµ\?r‰ªÊSÁ†H¤39}íÇ¿ÑwlÏëü¨¦ÜÒª&KUeL$â­kȼî 5åásCß]§ò ¸grÒÁ.óuo2iëóןW”»”e³Ž¾ûÓÆñÚrKÕœS䈀{èàÄw Þ¸‡l„€;" ú¢›,À:¸çc.‹k_×_H]’Æ}vp祊ŸÞW»[šƒ¾Èuo>U{Ç™œgÌaÛ÷véƒ_Û¬çŽôNûgÊRÒÊ&[MU¼/Àq¥®Aóµå…§- ±Ìfcé¬zâ¨q¼‘ãn^èà^¼vË÷ãP—£¬ÇëúWo>UÇ/«Ë䮇÷«¥kØ8¾¬Ï7€ ôÁ‹w ƸñFÀ=dƒÜ:¸a;€ ¶®ÌÜ`%l‹ÏYžfò|yL¬ßþC|´ô¹:Ð9u²=™´õÏן¯·^zBU! éLN_¿íIÝpûÓÓž{¶´¬ÁÖâ:‹Ýà·z†]e ‡ÖTÒÖeg¯· ÌZ[ŸjÑÈXvÒ±„-Õ•sðÍG&g>¿i¬¥ƒ{X¼îÓO÷ºj0¿¦ËVëýo}Y^µ…Åq]ÝpûÓÆñªRKu|¾LðÙ¿3Óu¢CÀˆ·é·ýAA G]bŠî…å°4àC2Áñ8_Žã¿S2€©¥¶rßÊäc&‹]ýtpçR.>\WÚß騭ê÷X}u©nú—êìõ C¨ Qرo¢kûžÃÓ¿}»°ÖÒŠF[©D€…À,ÔḼô쪫. ±Ìf÷Ý÷tΑö¶{ßÃû§ë^¡²’âŒ'=°í¨öé3Ž/­çà à÷ÒYr!s$™'is^qžAEóæé¥½XReÔµÄEï wDƒ†±…Ew€ Úhæ-ëÑÍ ÀÌ%–ÄFcyÉÍ`^òÓÁCG<äéÙVG}#S¿¿Ö,«Ó­™V,ª ¡2„-“uôõŸ<©oýçSÓîÚ^Uféøù–*K™0à¥29©wØ<Ÿ^óÊ5!VƒÙ,›st߯Ç«8ç‹€{q7mq¡é_èt4æqoáŠóŽÓ%/_–geá¹á¿ÌÝÛËR|¾¼ØX†¦ÕîÐ鬴·Ãûüõ#v†6o¯½oytoO%¤ù5\”x±á±üX`Fº£.@´¸˜^K Äá–¡¨K@LÙSÝ…B^¸ü Hš?î@°˜—ò7“y)“õÑÁK¹9k,3nËx?.a[úÇ÷œ«?»b]8…!TÃc}ä_·èî-¦õxº¶Àô¤]ÏR®yÕñ!VƒÙÌu½îU”ý0åªKKª(M…[LŒyܧxkïmwäu™ûŠSé]Wžì³²àí>Ô£¶5Ž/®³ÙU ÀÍF]BÜpbŽ€;î!Úß:u ˆ)B…EØà‡Í7"ycQ¬D‚y)_~ç¥LÖ‘ëãGÙknI»z¦ÙQzŠ5Õ•%úÎÇ^¥ N[NaÕþæ~]ûùû´÷Hß´?ѵÝRE óL‡W÷ö5Këtêšy!VƒÙl×Án5w˜X5TrlÎW6'™>¡Mµå,ä ѸÇNc^/CKŸ«Þó<[SY¢¯ýíÅE}M{ãÛc [ZTW¼µˆÎàð Ph]Q ZÜpÑØxNƒÃ㪮,ºÄL1ß@šÛüH°â,o,*‚E÷üù—Æ=ºâyáRnîsµó˜£¬9G"IZ¾°Z?øôk´fi]8…!Tÿó«ƒúÐ×ÖÐèÔ_Œ[–´¼ÁÖÒzº¶Àt¹’:Íçmo~ÕñÌ©˜6¯îí5å–R‰ÐJ™3¼.jË|j½³ IDATÂ+ž÷L—¿#iéP—÷Í?¿ï|-nªœIijîÒÏ6ï7Ž/¬µ”äV.€—H&“Ê䯣.#nèàÄw½Q7ýC£Ü::Æ–ã§õ" ö’æ€;,æ¥üå|^ ärS¤™ x…æ–þQW»ZMõvX»¢^?þìk5¿¡"œÂšlÎÑø¸¾íÑ-ò…ªJ-°®í¯þWéìäc–%]}ñêp ¬vÏ#‡cU£ýÈäÌ×UMuå!V¯kŽñIæÑLNÚÕ’3†ß%éͯ\£+/XU€ê‚óÝ;wï;Z–´¤Žt;€?”bU[èàÄwtpÙàи´ ê*7tp/,:¸ü°ó•süBL;KäÏñbxa,z†]ínu<ƒ ’ô²æéGŸ¹\uÕ4G˜kºúFõÞ/>¨Gv´NùXKÒòFº¶€_æî+N]¬%óªB¬³ÙáÖí>dþ*µ±’µiî5tp“W—õtÖÕ —]çiW‹£1Mˆ–ίÒgßóŠVXx=cºíÞ=ÆñùÕ–JHR˜D2Áä:¸1ÇÌ  =ê⦈-‹>:¸w€ ÒIy£ƒ;,:¸çÏï¼äw6ãš:]=׿Lù>8oÃb}ï“—ªª<J]Ï»;tÝP[÷ð”M%¤Ùª-g?²ŽÔ5d>ê¾ù•LJX f»{5wo¯,µTÆi›/Y¯€{÷0-ò¸¿°ƒ»ëJ{Ú Ž™çWË’þõC«º²¤%Ü-wïÔ˜i›IKëi`r–M÷pbŽ€;€¶¨ ˆ›¾Á±¨K@ Yê Š€;ÀÜóFÀV’y)o~w–pý¶pç%šõZû]íï˜ú}séÙ+tãG_©Ò¾,K\WúÁïÒg¾÷¨²Ù©ß5å–N\hÓ1f ½ß5î˜RV’Ôk_±2Ôz0»ÝóÈ!ãXc'ë~yvp¯-¯xvpaÀ}§£žaïëÚë¯Ù ³N^X¨Ò1<–Ñ­›vÇ«,•w>@„nÔE¡+êD‹Û¤¸‡¬g€îÜ ËñNÄ’ó—ÍqÌ‚ÄuBþ|wpg:‹¥Ö>Wû;§5_}ñ}õ*™¤Sà\’Îäôwߨ¢;Ü7­Ç/®³t\“-zÀÌ´ö›½¯;o%;¥`ÚºúFõø³æ°͹`L!ãq¿§©–îaòìàžq•ÍIºu x_Ôž³~‘þömgº¼‚»íÞ=ê4W¿´ž“qf^ ´:¸1GÀ÷uöF]bÈæÛÑ‚¢›,ÀîùËpż”?ÿw泸iëŸ^¸ýO_w’þé¯^Áuû34’Ñ»?wŸ~õtË”µ-éø¶æUó€™êv5–1ÿÙëÂ+³Þ/~}ظPµ,%U–rìö+ãl ƒ{¨j*KUY–Òð$“g&'=z`ê4çÚõúþ§.UªÈìf²Žnºs‡q¼¶ÜRuŸkfciîïE€€;sÅ}† ’üí¯ _ÚºG¢.1DgÆÂr¸|àxœ?•Á"àž?Þ`:Úú]íë˜úvÛûÞ²AŸû«ó·Ï1½£ºæc›¦n/OI/[N¸ ¥µÏ|®vÊê&¾v~ˆÕ`¶»ç‘ÃÆ±Æ*ŽÝ3‘õ ¸×”†WdYÒikçùþùEM•úÑg.WMeI« Æ]›÷«¥kØ8¾¬Ï5oÃã´p@OÔˆw æš7oÌi"äŽiŠºÄºÂ"àðƒãqþrkq 1/å/ì…7¼B³OûÀôÂíç™úè;ÎÙö¹å`K¿®úðϵóÀÔ Æ«,mXžPE o(„ÑŒÔ;b>W{ç•ë8îbÚ†F2ÚúÔ1ãxc%o¦™ðìà^S^!$]qþ*_?WSY¢ûÇ˵¨©²ÀžãººñާãU¥–ê*ø\ð60œº„¸éoÞ¼Ñc&q@À€$µF]@œìoŒºÄÝà ‹n²?蔜?޹@°˜—òçw^r™Îb¡cÐÕÞvïp»eIŸ¿þ<½÷š !U…°lßÛ¥«?r·Ž¶O}ïoe“­“ÙJò LkŸù\W]ª7\è/À‰xz艣Êd'O¥Ru9×R3‘õØ‹€{ø®8ÿ8••$óú™TÒÖÍŸºL',¯¨ªÂzà±#Ú{¤Ï8¾´žÏ4€©õ ‘µÙÔÝÌyÜ> ImQ'­ÝÃÊæèD‰pÑ™±°èàðƒãqþ¼¾ð0s¶Í­Á|ù¸3ŸÍuƒ®žk›ú~Ïßwþôµ'…PÂôð“Çô–oRwÿ˜çãR iý› XΑ:Ìç[|ÙڼÛˆ·ÿý¿CƱÆ*‹–fÈÔÁ=™°UUQn1P}u©®ËôàVU¤ôýO^ª³×/ °ªÂq]é[ÿeîÞ^–šø\€˲ÔO÷°uD]€èñ-‰€{¨Gêº Ä Ü Ë!œðNÉù£ƒ;,æ¥üå Ö™Íæ¶®AW{¦nÿÂõçë_³6„Ц»~¹_ïøô½óþ¢»,%mX–P]s/Zç +C³mÙ–¥?{‹Ë0}éLN=~Ô8ÞXɱ|&wâßdêªKÅ×YÑxßmÐyOù¸WŸµ\Þp.yù²ª*Œm»ÚôÄnsFri½ÍûÀ”JKKÈ„¯%êD€;‰€{è†Æ£.1c\)(Âv?l‹Kp?èz ‡%òǵ^ªkhzáöºîzûkO ¡"„馻žÑ_ÿËCSîÖXYjéÔe •¥B* b¦¥Ï|Žöê³—ké‚ê«Ál·õé f&KØR-‹ÕfÄÔ½]’jÊÂ+/’LØúÁ?¼Fôê&o¨)Ó·þîÝü©Ë´¨©2äêfæ†ÛÍÝÛS i~ ŸiSK%Ù (­Q z̾$î¡öÞ®(4:¸–C¨àARWJðÔ ƒ{þr9×~ëp)WܺnŸêÕýÌ_ž«w¼~](5!Žëê ·nÓ·ïØ>åcë*,´ÈV‚µŽˆþQW#ióÑøƒ‘§ÿý¿CƱúJK\FÍLÆãšŠ€{´JKúÊ.Ի߸^w>´O]}£ª®,ÑY'/Ô%g,SEÙì‹í>Ô£¶™wdXRgó™0-–ˆº„8¢ƒ;î$p]ß Ü.›/Q Š€;À$)m_Ç%„ „ÏVþüvpg3й§wÄÕî6gÊ×öïß}Žþü '‡SB‘Í:úÈÆ-ºýÁ½S>¶©ÊÒ Í@Z=º·¯^Z«ó7, ±ÌvÙ¬£{9do¬ä >SYîõ5¥á£“V6è¤wuq£Ç‚Ô„--¬ã3 `z1_D€€;î$±­KèúèàŽpÑÁ½°ü†ZñFwÇ‘Äj= Üó—õÛÁ½Àu Zƒc®žm™:ÜþÿÞu–®}ãúpŠB(rŽ«¿ùêfýüáýS>vq¥Uó8‡€ g'vT1yçëOfGäåWÛ[ŒMª,Kj à>c€;ÜQHÍíƒúÙfóyû¢ZKIN×LSÚãø…Àe@À€$:¸‡®»Ÿ€;Âe\)(:¸ü`Á™?và°ð&YÇñõs.-ÜçŒÑ´´³Å™òøôÑwœ©ëÞ|j8E!Žëê#·L+ܾ²ÉÖÒzæXZ[¿c\HXY–Ò5¯<>Ôz¢àºÒèxV©¤­IÍÛ´õ q¬¾ÂR‚§xƸ#,ß½ëcÃ*Ë’×ñ0}ãiîíE€î¸DÀ=tí½£Q—€˜!PWXŽë/Ôˆ7‚¤þ¸$ÜÀ0/åÏu'º±çûÌ‘oŸÒYé™c9e§èÚõá·Ÿ¡÷½eC8E!®+}êÛè¿îÎóq–¤5 l-¨a~€ 9®ÔÖo>ɺæÕÇ«ª"bEáÈ9®¶ïíÔc;ÛõØ®6mÛÙ¦Þßv¯,K©®ºôù 5e:yU£.;{…Ö,«£›ý²YGÿû‡Œãóªy ÁkW¬úšÒ+Á\ÖÝ?¦ÛîÝc_Pc©„´€< ÓÂ=tp@À€$iPÒ¨¤ò¨ ‰‹–®á¨K@Ì$®”©ã^8ûã üäë¸ì’CYg¢sûxÖûqøãÓô7ÿßiá…P¸®ôO7ÿZ?üï]ž³-éÄE¶*™ ]C®g'èw\±.¼bBò¿ÿwH_¸u›¶ôO:><–ÑðXFÇ:‡žÿßîÞr@ÿüƒm:nq­^sî ]}ñ­;®!¬’g•­O·¨h|Ò1ÛÇøÉxôª§ƒ; äÖM;5–6_¼-¡{;€< ŽLqC…–‘Ôu¢ÇY5oÞèŠ.î¡:ÜFÀá"|QX9#˜Ð)Ù‡…e@`ØéÉ_ o|.Öá*Ž+íjq4<îý:¾ûªõúÛ?9#¤ª–¯þø }÷ΞIÚÒ)K ·@˜ZzÍÇåó7,ÖñËêB¬&XÃc}ø_Ö_~þ~c¸}*[úõí;¶ëò÷ÿTŸ¸áWÊdÙ¥ô¥6m=`«¯´” YQ^ S¸£†Ç2ºånóâÔ¦*Kå%!`NèÌD]BÜ´þ6Ë æèààwÚ$uq±¯Ùß HÀ/‹àJA´øAÔ:¸Áaá?ŽãJ‰ü~†™lör%íis40êý*¾ñâÕúԻχû¹å†ÛŸÖ×o{Òó1I[Z¿ÔVU)/>„¥ÔÕdzw^yrˆÕë©ç:õ×_~H‡Z òû\WúÑÿ<«¶®a}ç¯V*Ij[’2YG÷ÏòcY–ú‡éಖ¨ P¸bð;­Q'ƒ#Œ¦£.1b‰ðJ!å¸|àXì Ë€à$˜—|ñ³ðÆ÷Z^¢ÈíïpÔ=äý^xÚ}õ±˜m޹åîú­Û<“°¥“—n€°óèÞ¾d^•^u沫 ÎMwíÐ?üó‚…Û_è¾ÇŽèë?ñ^Ä'[Ÿ:f ÄÚ–Ø¥¥€èàŽ e²ŽçîKu–ªÊø<ÈOii xÂGÀ€$î~¯-êâ¦h,ê3IÂ+CÐàw\na^òÇõq=À\6;évÔÖïýÚz|ÝOç ÛîÝ£¿ÿÎ#ž±-iÝb[Õd T£i©gØ||þ‹«NV21ûË7Þ±]ÿø½_ÚlåÛwlWÏßUIÒÝ[Çê+-Í·TÑÈæÌïi»6ïWk×°qœîíüH%“Q—G4i ‰€;€ß#à²þAn"\tg,:¸üàXì Ë€àp÷ÇWwŸ‹W(:mý®Žôx¿rÇ-®Õþá5ª*O…TÂpç/÷é£ßÜâùË’NZl«¶œO)„íXŸc«*Oé/;1Äj‚qÛ½{ôù[›öã¶”LäÿwÒ™œ~ò‹=ùÿà“É:º÷‘CÆñ¦*Ž÷…dêàžLتª( ·Ì)Žëê†ÛŸ6ŽW•Zª«àó ÀÛljfŠî$I,1ð;ÜCÖÓ?u ˆBu…CÐàARØúN¦÷…Ž9S…9¢oÄÕ¾ïz^}¹þý³—«©®<¤ª†ÿùÕA}ð«›åuúaI:q¡­zÂ1ºLNê0OÒüšUU1»žýϯêcßÜ:åã’¶´¬ÁVm…TYbÉúía)ëHÙœ”ɹꕺ‡\ Ž™Ÿ³û;¢÷^³¡PåÏJ[ž:¦áô¤c¶%5TrÌ/Çø7™ºêÒçßÇ€s¹–-¨©*„aÛ®v½ïËMyÍÂB[tr€H´õ»Æpl¶ôWnA¶å©czß—šr¡wm¹¥Ú*ä›þ¤=ñ¯,e©ºl"ÐÙ>àjoûäç7[ Qú¬¶iËãX}¥¥ë‚ ÆÔ½]’jÊÂ+sŽëJßú/s÷ö²”8‡à[Úãø…ÀÐÁ€$‰Ë1¿CÀ=dmÝÜ.Bu…“#œðÁ¦ •/ÜàpàŸ%¸„˜²Ž´«5§¬G¾=•´uó§.ÓÉ«Ã+ knÔµŸ»O¯_Òñ lÍ«fî€(8®ÔÒgž§¯8•–Ì« ±¢Âzê¹N½ûŸ¼E–¤•M¶Ö/<Ün² Æ’éÔ¿»TÙ\|·(JgrºçÑÃÆñyb *“3_pÇLlÛÕ¦'vwÇ—ÖÛìÀ·ñ47ö"@À€$î~€{ÈŽ´E]b&asØ/Çã&,&tJöÇOÀô°ðÆ Ü ¸Ï®;ѹ}4m~ŒeIßøÈ%:÷”Eá†À fôÎü…ºûÇ<·zž­5Ì›•ÎA׳ûó{®>%¼b ¬£gDïúÇ_hd,ëù¸ÚZZoÉÏѨĈw]©opÜÇoœ¶<Õ¢ÁáÉOmk¢ƒ; 'ëñ®¯) ¯Ì9^ÝÛS i>çñf`x<¾‹#ÔuŠI7¿ÓuqóÜÑþ¨K@Ìбp¦Ú®€Ép÷‡î@p˜—üñÕÁ]þæ2^¡ðìrÔ7âý:}úÚsuÅyÇ…TÂs\½ÿËiÏá^ÏÇ×dkQŸHˆÒ±^s°è¬“êÔã›B¬¦p×Õß|å—êêõ|ܪy3ÛEÄëҺ̔~M[Ç*-%HS”×":¸Ã¯gõèÁÇÇ—ÔÙÆ],`:F2Q—7IÝQ 8pI@’Ô¼ycZœ „jçAï/΀BK&¸{S(9?-±GÔòí@p˜—üq}LL~3†£}ÀUKŸ÷³ý¶ËOÔ»®<9¤Š–/þ`›î{ìˆçc–7XZRÏ| Qêq5â±ËÊlîÞ~ãíÛµõéÏÇ,o°´x† ­LÁâÒ’„*ËS3úݳU:“Ó=2Ž7Í`A&GÀA¸ñöíÆ±„--d¡*€êòÞe×Ú¼y#·EH"ààÅÚ¢. NG2òÞú($:¸Ü~ØÇb?èà‡€»?~:¸§|¶~ôñ§§QWû:¼1Ÿ³~‘>{Ý+Ä¡|nù¯ûŸÓw˜Ã0’4¯ÚÒòF¾F€¨ë5Ÿ·¸V¯>{yˆÕÎovwèË?zÜó1‹êf~,ÊäÌç•Mµå±=ÇÙüä1 :²Ú–T_Ó'&@Ùœù³\_Sb%˜+šÛõó‡÷ÇÕZJr:`lÛVßÇJKÁ{õ'€XáTÀ pYOÿHÔ% F¸w€IýqIwaá?~Þ$}~£Î ¬±Œôl«ã¹`Ù‚j}ç¯RŠTÄœ²mW»>úÍ­ž©.³tü^wˆÚ𸫾óÁúÚ7®Ÿ•絃Ãi]ÿå‡<ï57UYZ=oæÇ¢Á1óߘßP1ãß?[ý÷ÖƱ†JK>רÂCÆc]i=ÜáÃwîÜaœG-KZ\ÇÀÌ”••Ò€"|­Q xp6à…¸‡¬»4ê#Ü 'çÑeîþÐÁó’?¾:¸'>ÿ–¯Ã4䜉p{&g~LeYJ·üýej l3§4·êÚÏݧLÖœ°*MJ'-¶Å4 Ñ;Ög>!ª«.Õ5¯:>Äj Ãu¥~s«šÛ)K©` ­<îëW7äoÌ6ãéœî}ô°q¼©š“€ x{sÎ|u÷é'¿xÎ8¾ ÆRI2Ä‚ÌIÉ$Ièààyܼб¨ ˆ›î>:¸#<„W ‡î?fcG¹bà'H `zX럅7~»3ç¹vGÃãæ'ز¤o|äb­]QbUÚÐhFïúì}êî3>ƶ¤u‹m•ø[—( tVê4¯ÿôu'©¼tö…Žþëçt÷s÷pË’N\h¬ƒø€G¯¥³Ö-,Ì™e~²YC#™IÇlKª¯àZ)Yî( [îÞ©±tÖ8¾„îí À!ZîžÇ, à…Ì­ ˆöîOÂæ°_(Ü~$õ‡î@pXëë#užô™N"àŒ–>WÝCÞOîGÿìL]zöŠ*BrŽ«÷ù!í>Ôãù¸µ mU–2?@1héwŒçC©¤­w½þäp *€ÇúõÉÿÏó1+mU•æXä¸ÒG÷—¯[P¿3Ûܽå q¬¡Ò*Øâ¼˜W÷úêÒð Á¬7<–Ñ­›vÇ›ª,•—„X€9Ëc ‚ÓuŠ—f^èHÔÄMsÇpÔ% FÕw€IýḠ‡yÉ?óR‰ÏîL…74æê`—ãù˜«/^£÷^³!¤Š–/þ`›î{ÌûöçŠF[UÌP rŽÔÖg>ºúâ5šW_bE3çºÒG¿±U£ãæ¤T]…¥%õ…; »ÆsÊ…•Z2¯ª`k¶Oçt߯Í=¿šª9J6gþLÓÁùøñ={Ô?4n_ZÀy@¼ {ßCB èààyܼÜCv e ê#v‚›9…’s¸ä ©?.éN 0¶Å¼ä‡Ÿ%’I[~žnWÌ…”u¤ÝmæN°’ô²æéKï?ß×ë…âuuãÛ=3¯ÚÒ²^x(®²·aÿòêSÂ+¦@np¯}ÆÜ2•NXXدïFÍcg®[ËsžÍ¿iÖÐhfÒ1ÛšèàŽ`˜:¸'¶ª*h·éÉdÝt×ãx]…U°]0 ˜î ƒ;€çpðBtpÙ³‡z£.1’ˆãê€ÐIàAR¯"€a—'üÎK‰Dþ·b™ k_»£±É³L’¤ù úÞ'/UYI2¼¢¸Ö®a}ø_ö|Lu™¥ãðu  WÒ±>sºýÂÓ–híŠúð *€ž1}ö{z>æ„…¶J…ý»£æÊ3×-(ì›%îÞzÀ8ÖPe‰Ë¤`äóUuÕ¥±\l~öð~µv™wI§{;€BêêOG]BÑÁÀó¸c àyÍ›7öK꺎89Ú1¬ñ4+>Â+…“óØF:¸ûã§S2€éa^òÇï¼”"à©Ö>W]Cæ'Ô¶,Ýðw¯Ô‚†Š«BÐrŽ«¿ùÊ/Õ78n|LiR:i±M˜ ŠHÏë¹(í=o:5¼b äs7?¦^ãÑâ:Kõ…? ŒyÜüï»±tV÷=jî÷5¯Š‚ xíÈÐPS^!˜Õ\WºéNs÷öªRKuÌ¥âɶmõzœ”"IÝQ xpðRtq‘ãH=ý#Q—˜H$¸¡S(tpøAÔ:¸Áag \ŸóR2™ÿ­X.= chÜÕ.D¤¿ý ½>~!¯¹î†ÛŸÖ#;Ì;[Û–´nqá»åf¦¹×|tâÊ]ð²%!V3s>Óªÿ¼ÿ9ãxiRZÑXø¯íGÓR&7ùXeYJ'®œ]]ð aóoŽiذz"aKõ•\#%ãÑ8ˆ€;¦ëÑgZµë`qœîí ©¬´„ï'Â×Ö¼y#O:€çpðR‡£. nzúG£.1A÷ÂÉÒÁàARèà‡…7þø—J|Ü™g.çH»[Ïnøœ¶D×ÿцðŠB(~³»C_ù·'<sü[•¥Ì…PLúG] ztÿË7®×lº¼Ngrúø7åù˜ÕómùØìgJ}#æçñô“æ+Ä-rwo9`k¨´ØÑ%@YÃb Iª¯) ¯Ìj7ÝõŒq¬,%5² €J¦RQ—G4eð"ñ»j0NBÖÝGw„ƒðJádïÎL†c±?tH‚üäßyÉO€ˆ)pæöv824é”$Í«/ׯ]ÌB´9fp8­ë¿üçl j,Í«æu€bÓÜcž»ç՗몋V‡XÍÌÝxÇvíkî3Ž7UYj¨kx÷°ù¹<ó¤üÍb6–Îê¾_›û|5Œ ”i7‰C­ºÿ1ógxq=«@(~±Ê(ŠºÅ…™ÀKÑÁ=d}tpG8¯ŽëÒI?‚sþÐÁó’?~ç¥T*‘÷ÏpŸ™¶~W]ƒæ'Ѷ,}ó#¯TS]yˆU!h®+}ü†_©¹}Ðø˜ò”´j_@±wÕëÑuüÝW­W‰sª¨léׯÿxÊ8ž°ƒ;esR¿ÇsyÉË—òw‹ÙC7kd,;éX–êZh€ Ü1S7ÿ|§ñ9aO,`€Bò:v!0dÖ¼wp¼ÜCÖÒ9u ˆ‰÷‚r ÛòÄb3¸Áa^òÇï†N)Ü™ýMK:½_¬þÉézÅ©‹Bªa¹ýÁ½úÙæýÆqË’Ö.²åã# ˜W÷öªŠ”þôµ'…XÍ̸®ô‰Ùb IDAToýJidÔŠF[%É`þ~ϰklÒ²°±R§ßÌ.b›¶4Ž5TZâò(XÙœùó]OÀSNë?îÛc_Pcq~ à†ÇÙÕ=‡¢.@qáÀKpÙá6s7) ¯–C+E@ž8ûÃ1ó’?~ç¥dÒßóÍ,˜?WÒsíŽçó6,Ö_¿õe¡Õ„plé×'oü•çcV6Úª*eþ€b3š‘º†Ìïw^±NÕ•%!V43›¶ÐÖ§[ŒãUe–Õw<êöx._sîŠØíæ4:žÕý™‚6UÅëùˆBÆ##X_S^!˜•~ò‹=Æ$iqÑ'…×7D ÷ŠºÅ…³</Åv/!{îH_Ô% &èà^Xt“ä‹ ©?9_f†yÉŸœÏî%É„¯ŸcOþZz] Ž™Ÿ¸¦ºr}ã×p<Çd²Ž®ÿÒCžÁ—º KKêyÝ ë5Ÿc•–$ôW­±š™Oçôù[·y>fÍ|KA‘rŽÔ;b>ºüÜ•ýåâõÐãGç [ª¯äü h›¨îðÍ9ºùç;ãU–ÊR! 6ºÒQ—G‡¢.@q hÓ3³X›¤¬˜Bóì‘~¹®++fÝ2>Ûb][!ÑM¯¸uG+޹@p˜—üñ»Ø5és¿tוK?ÍA£iép·9 gYÒ7>r‰æÕ—‡XÂð¥=®ûºŒã©„tÂBî`îÊ9R:+¥s®2Y)“²ÎD§+Ë’l[²­ßþ÷—üK%&‚aœ *é¬Ô>`>Çzë¥kÕT7{ŽÝ·Ü½SÍíæÝ{×Yî&Ò;âw²©­*Õ9'/ ìo«M[Ç*-±î1xYîðéÞGëXçq|I€»aˆ/˲¸GãhÔ(.X¼Hóæ¹¥½ÿ¨¤ã¢®%.ÆÆsêUCmEÔ¥`Ž£;ca¹tpä‰c±?욇yÉ¿×%©Ü1-®¤çÚc K’®{Ó©:ÃâÐjB8¶>Ý¢oß±Ýó1',°Uâo# hŒ¤¥Á1WÃãîD˜ý·ötVžsßtX–Tž’ÊK,•—H©ßþg‰%Ÿk´€i;ÖçÏy¶¥ëÞtJ¸Í@ÏÀ˜6þçSÆñ’¤´¢1ØU÷yB¸ììåJ&ãõ¡ÏêþÇŽÇ›ª¹. ƒW÷úêÒð Á¬ó½»ž1ŽU•Zª)ç3  ðÊËJå¸ÃQ—7­Í›7ŽE]€âBÀÀdŽˆ€{¨zúG¸#pl½^Xt“ä‹NÉþpÌ‚üäß¡ßîæ^äx©–^WƒcæhÍÒ:}èmg„XÂ0:žÕßmÜâù˜Åu–ê+™ó0»draö‰ÒИ«l€×Ф7þ~>-INÝë*,5TNüw P²ŽÔÖo>~¿áÂÕZ¶ :ÄŠfæk?þ‡ÍÝ>W6Ù.q]©wØü|^~îÊàþx‘zèñ£ÏN:–°¥ú æ´0dsæ÷%ÜaòÔszüÙvãøâz>¿‚‘H©ŒÀ¡¨ P|˜LæpÔÄMOߨ´<ê*0×%Üä)$‡” OtJö‡î@pìx5n,¿ó’ßN™¬ó™žÑ´t¸Û|¡f[–¾úÁ UJ ï9ç_ò¤Ž¶Ç+K-­lbÂCñÏJ=C®~jËD]ÑïMt‹wÕ7âêP—Tš”ê+-5TZª-§Ã;f¦µÏUÎã^ë{¯95¼bfhs¿þíwÇ«J-͸[xÿ¨y1LyiRž¾$п_Œ6m=hk¨´Äíšp˜:¸'¶ª*JÂ-³Æ÷~fîÞ^’”æUñ‹ûG8uŠw“1ïÓ‡@tõD]b€îŒ…åpäÉâXì w 8,¼ñÇïÎ%ÜãJÚÛîxv×Ï›NÑikç‡V±ûP¾óÓÆqÛ’Ö.´ ®¡hg¥®!W]ƒÞ;P›ñìDÇí¶~W–%Õ–O„Ý*-•¥¢®³‰ãJ-}æû¬¯>k¹N\ÙbE3ó¹[SÖ#­ܼàH]Cæ¹äâ3–ª¬$^ñ€Ññ¬îÌüµç¼€`BÎ1ï„UW]*n™a2­]Ãúo*‹jmÞ;3nX˜…@ÑŒÀˆ×,€éâ¤!d-]ÃQ—€ ¼RX~C-€øâXìÇ\ 8,‚õÇwwŸím™§ÖÒ7ÑñØdÍÒ:}èmg„XÂฮ>öÍ­žAÂUólÑÅ&ý‚P»×Ü5[¸®Ô72ÑÝý@§T]fiq¥¦*‹Ð¦ÔÖï»:KÒ{¯Ù^13ôÛ[u߯Í_¯5VMìx´€ûåç® üï›?ªÑñì¤c [ª«`¢ ƒiWIj¨) ¯Ì*·nÚe<×·-ia-Ÿ_ÁŸý×j³Ð¡¨ P|¸˜ ÜC¶ÿØ@Ô% „ê Šî€|q(ö‡î@pXxãßy©$åok㉅>¼V&£ép—ùͶ,}媴„­¥çšÛîÝ£'vwÇkÊ-B/(χڇ\ ŒÎíóÛÁ1W{Ú\LH ël-ªµäóˆ9Îu¥c½æcøY'/Ô™ë„X‘Žëê³ßÔ8nYÒÊF‹ó10æ*mX0LØzõY˯¡ØlÚrÀ8ÖXiq¯&$™œùØGÀ“ËêßïÙmŸ_Ãù€`õ O¾@:uŠw“¡ƒ{ÈžÞ×u ˆÂ+…E7Y@¾8ûCÀŽE[U_ü^ øîàîë§âc_»#¯CŵW¯×é'ί „¢³wTŸ¿å1ã¸eIkæ$¦28æêXïD°=H¶e©±®Lóë+4¿¡BóêÊ5¿¾\ µårWã鬯³ŽÆÓY¥3ŽÒ™œÆÓ9grIë`Ë€Ž¶ ô~W:'évt´GšW5ÑÕ½ªŒsü^ç +CcmIÒõo™=ÝÛïxpŸžÙßm_Tk©<„Eº=æšWœºH5•ñÚÖdd,«û;joªfN KÖc§††ZîøCw<¸WýCãÆñÅuœëV÷@:ê∬€?@ÀÀdÌw{ˆgö)“Í)•d©9‚c^)(—° O¶Í/~p‚Ã.Oþø—’IŸw¦A£öWýW/­Õ‡ß~Fˆ!,ŸùÞ£6Ù¼´ÞRE¼2|(2ÝÃÁöBwk¯¯.ÕikçëôçëäUZÔT©ùõj¨-›ñq}<Ó¡ÖíkîÓþ£}Ú×Ü?ñß›û42æ¿{¡ëJƒ®:]U—MÝ›ª,q«ÍÝÛOZÙ KÎXb5þŽgõ¥>nOÚÒò†pîxÜ/ÅÊPj(&>~TcéÉ範-ÕU0…%ãp¯¯. ¯Ì Žëêû?Æ8^_Á¹>€`Y–EÀ=Üüîþ@óæ#K/z§¤yQ×YÇQG÷–,¨ºÌat-,:¸òÅb3rÜÀpàOÎ1‡±¼”ø ¸3 N.““vš_ Ë’¾ò‹TVÂ-ð¹fóošõ³Íûãe)iYHABà…Wêpu¬ÏÑh²É„­u«túÚùχÚW,¬ ,^Z’ÐÚõZ»¢þEÿ»ãºÚw´On;ª?ªm»Ú•Íù;޹ÚÓæêH‰´jž­zÂ¥±Õ=ìjÄãsrý[6ÌšEß½s‡Úº‡ãËl…ÑÛhhÌÕXfò1Ë’^söŠà‹(2›¶0Ž5VZâr(<^÷†:¸ãÅ~ùD³ö7÷Ç×óá¬ò²RåóùÑÞ¼yãhÔE(>ÜÝ`rDÜCÕÑ3LÀ"¼RXt“ä‹îþpÌ‚ÃÂ|æÛ•¢ƒ{Aèt”õx-Þ}Õ):ãÄùá„PŒŽgõñoýÊó1kæÛÖªLNjíwÕÚçxø¦cÅ¢]yþqzå™ËuʚƢX¤c[–NX^¯–×ëº7ŸªÁá´¶€B˜é6Åx1:¸òEÔ޹@pXëß…7¥%þZw²Îçõޏêôq-]P­¿ÛZsÑÆŸ<©£íƒÆñyÕ–ê¼ $ãY©¹ÇQû€;£¹zùÂj]yÁ*½þüU:yUcÑw­®®,ÑëÎ;N¯;ï89®«ºuÿ¯è'¿Ø£–®üîq÷ »êÉiq5ÑåšEÁ±Ð?êjpÌü¡¹îͧ*™˜o†›~öŒ†F mÓ%­l gÑ•ëÊóÜè ®¾ˆ"óÀ¶#Kg'KØâ|!d^ ÀêkJÃ+EoÏá^myê˜q|qÝì8>˜Ý\+„íwðR‡£.@q"àÀ„“‡y}9¡ºÂ¢›, _IýÉqÌcqà‹ß…7e)ÏgÇø¹*çHû;¼Ÿ”/¼÷Aôêãuêšy³6Ôn’LØÏwvßy [·Ü½Swþr¿Ò^m{_ ““öu8jí·´jž¥Úò9öA’44îªwÄ|rsí×ûÞõ&l7ýì ztoo ï=Üáѽýü—-VS]yhµƒá±ŒÜvÔ8ÖÂü^ÖãP@À¿ÓÕ7ªŸ>´Ï8¾¨–Å)Â10:½kÔ¡¨ Pœ¸0¡ƒ{ÈvìëºÌqtp/,ºÉòEÔî@p¸FðÇï¼ä·£¸Gž7v†Æ]ë5?ÿµU¥úôµç„XÂrçCûõø³íÆñšrK k™ÓœÁ1W:] Žå hª+ן_y²Þþº“T_]@uÅçäUú—¿¹PŸx×Yúñ½{ôƒM»ÔÖ=<­Ÿwµ£ÙÕ¢ZKÇͳ ²Í1^ÝÛ«*RúÓמb5þMÕ½½®ÂRMH‹4Wê2?¯W_²&”:ŠÉƒÛŽj,=ùJ¤¤=ñú \^kârlÄÔþýžÝÆ…q–%-ªe·&áèHG]BŠºÅ‰€;:¸‡ìÙ#½Jg²*I15#„ê ‹° _IýqØ5 ×þø—*üvp'à.Ir%íëpåõìê/ÎŽ]‡Ò8Hgrú—{Ü8nYÒšù„]Œñ¬t¨ËQ§Gwd“5Ëêôž«OÑÕ¯™5© ­¡¦Lï{Ë]wõ)ºí¾=úòWïàø´~¶µßÕÀ˜£µ mU”\(B1š‘º<‚Øï¼bª+gÇ‹ýÝ»vxvo_ÞÞyvϰk<_,-IèòsW†VK±¸{ËãXC £õØ–Šî&ÎùoÝ´Ë8>¯ÊR _¡…¥Öîé]³  h `Rœ0áä!dŽ#uti麨KÁEx¥°ÛòűØ•Áaá?~ç¥ÊrŸÜ]W¯UkŸ«!ÎÉç¬_¤?zõ !V„°üðžUsÇq|i½Eø—s¤c½Žš{]å;íŸ{Ê"½çM§ê’—/åXû[ɤ­?}íIzëôõÛžÔ­›v);\Ã㮞:’Óªy6»4ÌÇzͯyiIBqÕú«ñ¯wp\·ü|§q<Ìîí’Ô9`ž¤.;{…ªÊý-²œ­†Ç2zðñ£Æñ¦*æ’(˜:¸'¶ª8‘ƒ¤Ÿo9 ®¾Qãøâz>»ÂQ^^¢Lv$ê2∌€Ip`Ò%iXReÔ…ÄIGÏ0w†P]a¶ä‹p‹?9޹@`,®|ñ{-à·ƒ»Cwg¥ÃÝæ'"•´õÏï;_jçžÁá´6þäIãxYJZÖ@÷vV÷«ýŽÒÙü~îÊ Véº7ªSo ¦°9 ¶ªTÿpí9zÛkOÔgnzT¿|¢yÊŸq\i_‡£¾QKkæÛJò‘Ÿ•ÒY©Ý#ˆýÖK×Κ]XnºsŠîíádsRψùy½úâÕ¡ÕR,xìˆÆÓ“§©“¶T_Á cØrŽŒ‹ÅêkJ9‡‡\WúÞ]ÏÇkÊ-U•òFŽd²D÷u6oÞ8uŠ·LªyóFWÒ¾¨ëˆ›¶.s7*`¦Õ–Kw@žXlæ‹Ê€à$˜—|ñp÷ÙÁ€»öw8žÏÃûßzšV/­ ¯ „æÛwîPï ykð¶˜ÊP(9GÚÛîèÙÖüÂíg®[¨ÿþÚuÃG_I¸}šÖ,­Ó>s¹~ðé×hÕ’éÍß]ƒÝÜ=vó@ñ:ÖçÈt;5a[ºîM§„[O½ƒãºyªîíeᘺ†\ãóZ[Uª‹ÏXZ-Åâî-c Uaêd=Îãë«ËÂ+EëÑgZµó@·q|I\áq,¢”8uŠÜxÙ+iCÔEÄÉÑvÂ"lÈÇbèà‡E°þä|¶T÷ÛÁ=î÷®!W=ÃæcÁšeuzï5§†XÂÒÙ;ª›îÜa¯*µ4¯šy …18æjO›£1sSæ?°t~•þߟŸ­+Î;ŽÀ¤O¯|ù2]ð²%ºuÓ.}õߟðìŠ-Ici{³£¶–Öó¤ÏÙœÔÖo>–¿áÂÕZ¶ :ÄŠü»éÎö˜(ÂìÞ.Iƒæçõõç§T̶<Íè¡'ŽÇçU1oD!“3¿Oj¸CúÞÏÌÝÛËR‹S ,£i¾ˆÀᨠP¼¸ð²7êâfÏÑþ¨KÀF¨®°:¸òd‘zñ…Ee@p,®|ñ;/UúìàçiÐq¥Þ ÿ/ýõù*I%BªaúúOžÔ踹öÊ&æ0ÌœëJͽ®Žt;šît[Y–ÒûÞú2]{Õz•–0ÿÌT*iëÚ7®×åç®Ð{¿ø žz®Óóñ®+êr40jiíB[‰xåwg¥£½Þ;±Ì–…j=cEÕ½}<+õšg®«/^Z-ÅâÇŽh<›t,iO¼F_vò—D’ÔPKÀ= ê¾_›s‹ëlñɦ¾a‚r(ê/nûð²/êâæé}æí×€™¢;ca¶ä‹ÅfþÐÁ×þä|.v¥ƒ{þš{]¥Íùf½íòu溅á„ÐjÐïÙm¯«°©aÆÆ2ÒŽcŽO3ÜnYÒ[/=A÷-zß[6n/°e ªuç—®Ô_½yzaçžaWÏs”!RÔÆ³RKŸùöê³–ëÄ• !VäßTÝÛWQ÷öÅM•:óä!VS6m=hk¬²Øm#"^ót}uix… (ýøÞÝ2]b'liA \áêèKG]BŠºÅ‹î¼ÐÁ=dûšû56žUY)Ó3 P]a91™üáPì‹Ê€àØ´¾ðÅï¼TQîïZ?Ói0•š{Ì^óêËõ‰wbEÓ—~ø¸²«;V†"ÄÜÓ1àj§wWé:ëä…úô_ž£SV7[XÌ%“¶>ñ®³tÞ†ÅúÀW7««oÔóñƒc®¶Íéä% ù\G†€îvŒÁEIºþ-Â+fzÆtËÝ»Œãõ–ªCìÞ.yܯºhuì³fôàãGãMUñz>ЉWÀ½¡†îq–Í:úûž3Ž/¨±Ø©@¨lÛVgßxÔeÄÑ¡¨ P¼8à…€{ÈGê茺 ÌQq»¡4Çg×F@|Y‹}q\V•AáÁß÷Ò”¯®‘qÝÉâp·#¯ÿ럾öÕT–„WB³c_—îÞrÀ8ÞTe©*ä!掬#ínuô\ûôÂíÕ•%Úøá‹uû?¿žp{ˆ.:}©~ñ7é‚Ó–LùØÑŒ´ýhNÃãñ<^³áqWæ×åUg.ÓËOš]Æ¿;E÷öå!/¼I»žïù«/Yb5Åáþ_QÚ¤NÚbç—e=VìÖpµû·ñ\̶¸Ž8€p•——Æö>\ÄG]€âÅ!/í’†¢."n:{†£.sT"Á ÜB¢›,ÀmÜóÆ e 8s’/~¯,K*+É¿‹{wwÕîˆ;sÝ]yÁê+B˜¾pë6ã˜%iE#_kÀŸþQWOΩkhzóø¹§,Ò}ß|“®¾x¯J˜™yõåú·¼\ç™S^G¥sÒöfG}#\;“ÃÝæ×ò¤½ãÌ«ño¢{ûNãxÝÛ;<º·¯]Q¯“V6„XMqØ´Õ¼8®±ÊbW÷úšÒð AÑùñ½{Œcu»³]"ÁÄ‘ýQ xq'€Qóæ®èâºÖ.îÝ +Ç” `Æ’,8ˋʀàpàÏLÞT–çÿEÙt: Ï5;½Ÿã¸öBJsÔ–'iËSÇŒã j-•Ó¸yr]éP—£͎ƳS?>™´õ‰w¥Û>÷:-™W|0²-Kï½fƒ~ú¥+µ¨©Òó±9GÚÙâL{‚50êªgØüZ¼ù’ãuâ, a÷Î3Oawo—¤N…€W_¿îíC#=ôD³q¼©šÇ(e<®gèà[Ç:‡ôË'ŽÇÖ𹾌ÃÜ#Í›7š·ó{ÜL…€{ÈŽ¶F]æ(›îŒå¶ø@÷üÑÁ×þÌdáMyiþÜs1›»‡\õšÿO¿é’5Úpü¼+BX×õìÞn[Òò¾Ò@~~znîÞdºfi~þ•7è¯Þ|*çîEäôçëgÿò°¼Þóq®+ínuÔÒ³ƒg:Øe~ RI[zû!Vã_1vou=ë\uQüv¹¹ï±ÃJÚ„'m©®œù·Â72ÎuDž‹ºÅ-ÿoTÄ ÷=w´?ê0G^),²v?¶-Éã›=ü:¸Á¡ƒ»?Žé[øiðÓÁÝu'þÅáår]é`—¹ÅciIB}Ç™!V„0ýâÑÃÚ±¿Ë8¾¤ÞR ßh ™œ´ó˜£¡i†þìŠuú䟟åk1‚·¨©R?ýÒëõ矽Oíló|ìNG霥•,ЉB÷°«Á1óçî¯_§¥ógÇîßùivo4?·g®[8kžÛBÚ´õ q¬±ÊŠÅyt13¬=DÀ=®rŽ«ÿ¸Ïœg\Pc‰¯4ã%çH£iW£iä·ÿ™ËI©„T–’ÊR–ÊRRUï «gh[~¡Ð¸ðÄ]:S!à²'ŸëŽºÌQ„W ‹°Àd‚ãq¾8æÁ±øVЗ™ì,QYæïvlΕ’1x¹Zú]eÌãïyÓ©ZÜT^AÕÍ?7wÈM&¤%õU1}cé™c9Ï9åwšêÊõ/s¡^uæ²à ÃŒÔV•êß?{¹þúË¿Ô=üÿìÝwœœU½?ðÏ33Ûfwgw¶o²é½B$B( ‚HQ@ô (*Âð‚xÅŠ ¼X/üTDEQÁÊ%¡( é½l¶—ÙÞ§<ç÷Ç^®¨{Îì<óÌSf>ï×ë¾îëå™e¿™9Oûœï©U¾¶¡SÀ£ L.É€¨ƒœT,V+ðgá£WžbaEÆuô ã±gÝÛó­ïÞ.ÐÞ/?Ý|NæuoïŒàÅ7ë¥ãe…œìUlI,̱°rŠ­ÛÐŽWxÞŸ búènm}݃ñŽ{4 " ar‰‡‹Ÿ)%ZºFì.!1àNDJ<3$¢xŽÚ]@¦9ÑÜ‹¡ñ zør†Û]$7Û‡Gï^‡ë.š÷µu:šºy=a¥¶>Á°|ü–w-qMÇæï>§{» ‹'º¢’nØ>¯WM³¶ xþõ“ˆDÇ>‡ôyâ<^ïØMÖÁÝçõ ÀŸmm1äOyýrä\ @Î÷øïöKDz¼@u1Ï¡h|º6ëqåfûðŸ<×^4¼eæ>^†/Þ² •¥~<ðãíÊ×oבåõ œ]œSNÀÉAĤð IDAT8‹ÕþíÒ…Vdœ»·@{Ÿüvf4ÃvDDd;¸'.Æc.QJq^J\,‰ÝœŒwpí¹Ÿž†Â@sü}]0½W¬›eaEd¥žþüòä›HViàTEãÑÖ+p¤MG¼iº¦¢ßwfOæýW7Ó4àãW/EEÐÿxøån‹‡[ux=”äs2I¥¦n°¼á9nÏ©†ûYí;¿Úí¸îí1èè—Î7¯aa5ÎÐ7ÆÖíõÒñ2m§ZÀ,̼üüO‡¥÷ú| ¬€ßÛt3]§Z¤eTL·èÐuGPÒ4;ÎSÓLÀI»‹ "g㦞D¤Ô°m‹»¸[®¹cÀî( ±ƒ»¹T͈ˆˆd$M\2AR"ŠóRâ’Y욟gìaY,ͧÂ!u õÓÿv:?«iìç>Œ¡‘±C„šTñ1Å×Ð%p¸5~¸}þ´üúM ·§‘k.˜ƒïß{²|ò¹Bà`³ŽÞ¡4? Ú(ª ò$ë´ E¸fý +2n´{»|g»º·w i'l®ëOŸbmAð§¿Õ!"IPû¼@qÏíQ\Èd⎙N?}þt¼<À…­éäí]¶ŸŒ¥$ÜþNGÛR §ÌŽq²Á±†m[Kd‰ˆp'¢ñaÀÝbµM}v—@iHã]!S±ƒ;áõð2Å"'yôW»¥ ¯{º·P÷.Úaw ”†ØíÎ\É„Zˆˆ(sñxœ8s‰R‹óRâìèà®§ñ3¶ºNùûéózpïVXX YíÅ7P×"¹Là6ó¤ ‹Ñ K¨?þ¼|ÉÙÓñ­_ƒì,¯•‘6¬š†/ô,ÜõÐËÒ×Du`o£Ž%“¼È5¶æŒÆ0šºåßÃ%³Ê±qÕ4 +2.Ô=„Ç ¯Jlêމ݊ÐÞæµ3-¬ÆúÂØº£A:^VÀs'ˆ(îÁÂë !Gx⹃ұÂ\ ù9üÞº£;+ÕuÆßYéŸU”øqæ¢j̘X„é‹PYêGKhu-½Øu4„ç_;©þÝݱgQÇ–c5¹_g/‰Û€w"Š‹w"Ü-ö—½­B@c{ 2‘‡ÁS±ƒ;Á iâbéœê$rî,‘¸dÞäLÓ¥ëf}Ã݃òÜû6ÎÇô‰EVDV{ìÙ}Ò±ü <ž;ÑØbúh7îž¡øä/]ˆOðtewoJ×\0]}øÿ±7¤¯‰Ä€½1,®ñr‡“ÔwêPÝ}Ãr×tÒþÎÓ{Ù½=Ô' {‹ËŠópÖ)™·ÛÍó¯×!"Ù6ÀçŠx᪀{I€Ü3I¨{T”«¸°Õõ"1à@³ŽÞqœŸ¿-7Û‡‹VNÅëfaÕ’ Ê{çj;ñÀ·+ƒîo/€=uŠ×5çäÍCv—‰p'¢¸x놈ƃw‹õ FÐÖÑʲB»K¡4‡xæbÀˆˆŒà‚³Äñ˜K”Z\x“8=‰…7þ\c·cciºÖ§^ѽ½ÀŸ…Û®Yja5dµúÖ>lÝ.ï¼:¡˜óMˆÑðÌxÂí÷~àtÜ´y.ä–+– «oþr·ô5Ã`_“ŽÅ5x¹Ö/)ƒa ¥Gþ]\sj V-qGøz<ÝÛ lêÛÖ'/9{:|øA~ö•ãÒ±²ó¾CD+uƒ ¸g”§^8‚¨dQŠ×Ã]Ün0 ìoŠa82¾×çfûpãæ…øÐå‹ÈÏ×ÏÌ›Z‚Ü»?úýÜóíW¥¯Š­½‚‹&(!¹9ÙaÀÝ ¸Q\ ¸Ñx0ànƒ¦ö>ÜÉT Ô™KOto=""">/ljJ¦S2ÅÇy)qÉÌKþ<ƒÜÓ0àÞ?"Ð9 /ßÉæXXYí7/Ƀi>/P^Èù‰Æv¸UWîþ>¯߸}56¯iQUä$÷ܰÝ}#xòùCÒ× ŒmÓ1§*ó‚Áf:Ù¡>Iù÷-·¨’ä=ú«ÝŽìÞ>ÝõFæ²53,¬ÆzÂØºC¾HŽAYçPupx®Ÿ)„~ª8&—j\pæb]ƒ›õqÝ·ðz4\}þÜþžSQYâ7ôû®Û0}ƒaåŽ=u:*^ðÑ8WVv6ÜmÀ€;ÅÅ€;G'€nÅv’Iê[{±tž;:›;hlYb*†íˆˆÈvJNœªÛ%óRâbIÌKù¹îBH¯¿Uƒ¢{»?ׇ^ºÐÂjÈϼtL:VÐF 1éhWt2FçÚï}ê<œ½t¢EU‘ÓhpÿGV¡§øK­ôuí}…¹‚;FÔ7,Ðѯ^¯…3J-¬È¸Ñîí¤ãvvoWÍySªX:§ÂÂjœáù×OJ;Aû¼@Q¿ÓNQ^KØÁ=c¼¾¯Ç{¤ãU~gݪ¹[àx»ŽñÜ%Y4³ ß¼} æL &ý{o¹b zÂx仯GGk›äg‹ÆGh^»KÈDýZì.‚ˆœë ‰(®†m[ØÅÝrGëåúDF°ƒ»¹t܉ˆÈÇEeD©Å€{â’™— üìàƒa"w݆y ¼¤¹£ ÝØ¢S:^࣠úW]]ê9¸¬8¿øÊF†Û >¯ÝqV-Q7‘9ÒÑ;Äk#N„äï›ÏçÁמfa5ÉyôW»1v^÷vh듟^¶f2±¯Í³/Ëw)+Ð2ò=qª¨¢ƒ;Ï÷3Ç”woÏϱo'p¬]DZq„Û}^>ñÞeøí›L ·¿íŽk—af¼?c}×øºÊÀPØî 2ÒáÿÍ¢)ñ.1îÛu¤Ãî(Í0·b.]ðz‹ˆˆÇ iâp'J-ÎK‰Kf^*.Ì1ôsª`ˆÕ+º·çd{qóæÅVCvxæ%y0ÍŸ­ÁŸma1ä í}'Bê„JME~óÀ&,šQfQUät9Ù^|ÿÞõXŸ¹ñ4Ÿ×ƒ;®[&Æ€ÆqÔHýò…Ž”2‡í.€ˆÜw"/Ü-öÚ¾VÄt.+&ó°c¬¹ØÁˆˆŒðxxž(܉R‹× ‰KæZ XÀ€ûPd4¨*óž æ¢<˜gaEd5!€ß*îå…œ—èu nUß'- äâ'Ÿ¿È5Z²NA^¾ÿ©õ(-’)ÃQàP³ö³àd‡üÍÊÏÍ­Wb]AIúáo÷bpXѽ½Ô¾ã’êœiÑŒ2eçÚtõ—]MˆDÇ>&dy¢<žG8I4&ÿ  .þ%wùå‹G–¬tðh<÷w›H Ø]¯£k0þIÓê¥ñÌ×/Å¢™©[|ºaå4å¿¥‡Y Ÿ†Ð°Ý%d"܉h\ødˆÆ‹w‹ ŽÄÐê·» J#îËi*܉ˆÈvJN}¥–— o–\wc] #i46tÊÿ1>Ÿz»·§»ƒ';q´¡[:Î ½SÿˆÀ8Áã¼ûÌù˜>±ÈºÂÈUªËòñíO®SÞí¨íH£n µ÷ ŒÈ¿”7_¾eÅîX¬Ö?Á»O:^’¯¡ Çžã’€:à¾ùœÌëÞ/¾Ù +É×ÀÇ Î"ëàîózPÀ-{2¯^<*+/Ô`rSoJ¡h ØÛ¨c0ÿžÈõçãñû.@a~j¿çš|òúÓ¤ãá(Ð?Ì繤–…®>Å–9”* ¸Ѹðt‘ˆÆ‹w4·÷Ú]¥vf4îDDdljcw¢Ôâ›Ä%3/ø³àó&~KVÕùÐM†#@›"¨uåºÙ˜P–oaEd‡gÝÛ r4äfYX 9ÚpØ×¨#¦È{=½{–Ω°®0r¥•‹«q÷ Ë•¯iìõ§Ç17UtœT,(-ÊÅ›YXQr~ô‡èš&•Øw®Ü3(–4–×4`ÓêÌ ¸ ¼¸½^:Ì絓ÄôÑ9c,Á@#d€úÖ>ì>’ŽWñCà1ØÛ¤+¸£ÍÖ>ÿ¡•øâ‡Wº÷aÄê¥5X>¿R:Þ9Às;RËÉáŽ"6aÀˆÆ…w"/ÜmP×Ògw ”F¨3—Î=‹‰ˆÈIK“P'‘Sy¼œ—•ìÎÌ¢iÒP¶±KÞ…ÙëÑð‘w/±¶ ²œÀo^:&/c÷vú_‘°·1&íüú¶¯Ýz6Î=m’5E‘ëÝ|ùblX5Mùš#­ãëLš©š»F$¡k¸íšSQ玕JÃá(¾ûôéx±_Ca®}Ç%U÷ö•‹' ²Äoa5Îp´¡ mcï|¬aôoFΡº† ÜÙŠÜåÙWNHÇò²€s,_Lö5éq;¡äeáñû.À Ï·¨²Qš\rötéx瀅Å+éðÚ]B¦bˆÆ…w"—†m[ºtØ]G¦Qm×L”(Õ¼”¸˜ª}‘œ%Ž܉RËËë„„%;/&Þ*'àéá(ÐÒ+ï6¯‰ÉU…VDvØs4¤lèP΀;áï!šáˆúuŸ|ßr¼û¼ÙÖEiAÓ€¯ß¶3kŠ¥¯‰éÀfõΙj$ ÔuÊߘÉU…xï…s-¬(9O>¡î!éxMоc’.€Ån›×δ°çتèÞ^˜§ÁÇ䃣D J ¸g‚g_‘ïÜTVÀó~7ÐÅèyQïú>HMe!~ýÀ&¬]VcQeÿhÝòÉÒ±þùŽ(D00bw©­aÛ†¡ˆh\x™GD‰8jw™æ­C\S@æa Î\1vp'""$MîD©Å%gGÀp÷E÷vM>zå)ÖD¶xFr)ÌÕã³°r$!€ƒ-ñ;DÞpñ||ä îú@‰+ÈËÂw?uòså]ƇÂÀñv—xSàD»:ø×u§!Ë% ãHTÇ=µK:^˜«ÙÚ ¼k@HÏý²³¼Ø°rª¥õ8Å‹o6HÇJؽÝqT‹tKŠpOwu-}Ø}$$gÀÝù„6ëèTŸ—ÏŸV‚g¾¾ s¦-ªì_M®*ĬÉòŒ¼¿Lr¡Þ°Ý%d¢Ãv@DîᎻ Dä‡ì. Óüí`;¢lC&Ѩ3•ΰàõòxœ¨(¹D)Åy)q1E'Âñ(.0pwq÷˜´*º·_|Öt̨)²°"²Ë oÔIÇØ½€ÑîÐ]q(WMÃ}7 Þê"£fM*Æ·­V¾¦µWÄý,f’®A¢£øÂ¥¸dõt +JÎÓ[¢)4 ŸTbïÓÖ'¯Ï[1…ùÙVã ü¶·Y:Ì·°—ˆâú%hpÑ/¹Çï^=!ËËòsx"çdB‡Zô¸Á𙓊ñ“Ï_„²â<‹*“[¿bŠtŒwR©o—ïèC)À;îD”ˆ}viFÂ1´´÷Ú]¥ vp7îDDdljÓuu‰R‡ÜM6àn´ƒ{’¿×Ní}BÙñõ֫ؽ=4…p¤N¾5»8RÏ@}§z®;ca5üÄZ¿(iŸ5 7m^¤|Í‘6Ýõ;¨˜AÀ±6õñٛ΄Ç%«NbºÀÃ?—woÏÏÑP’oß¿%ªC¹¸â²53,¬Æ9þ²»É2Ûǰ¬©î%vpOwϼ,ß¹‰çýÎ&p¸UW.l€)Õ<ùÅ Ž·Ày+&IǺøX—Æ’—›ƒaw”p/܉hÜp'¢D0ànƒ¦ö>»K 4á– nÁ€;Á Ž1‚Ç]¢”á›ÄÅ’œ“ Ü]°kî‘¿gçŸ1s§–XX ÙeÛöéXAކlŸ…ÅãDb£]"UæN-Á>½9Ù^‹ª¢tw÷ ËqÆÂjéx8 œhwñØ$ :†#òñwŸ7+TYWP’~ÿê œhꑎO Ú{~ÜÑ/áægãÜÓä¾töâ›õÒ± Ÿ×4N¤Z dÀ=­ÕµôaÏÑtœ;79—.€Í:Ú;‰ÀÄò<ùÅ ¨,ñ[TY|KçTHï·èèæýeúW¾ìÌÛÇ!p'¢qcÀˆÁ€» ê[ØÁÌÁàŠ¹’ µQfâ‚3ctÁã.Qªð:!q1=¹ [q±€»ª¢“õ ŒÈçñ\²ÀÂjÈN[wÈîÁ| !G:Òª#•O,/À>{ù y|^ºs- Ÿ«Ö^NE7ít7ê»äÿþ¢‚|êý+,¬(9Bÿ|§tɱƒ{æúã_k¥cþlÀŸÍï¬Åt`_£÷¼§¢Ä'¿´5U6>>¯kN­‘ކ-,†\#ª36i܉hÜ8SQ"êôÛ]D¦9¤Øº™( Ô™‹܉ˆÈIáq—(u¸³DâØÁ=1-ŠîíÓ&aåâ VCv‰Fu¼ô–"˜ÆÎ«­©[ ÎÎòâ‡ÿy>ªJ¹‚ÌWUšÏÞt¦ò5GÛtׇ“u¬]‡j½ñ=ï_ŽÒ"÷U_x£ûOtJÇkJ<°óˆŽ݃ò7|óÚ™VãÇ»ÑÐ:önÇ€bžG8RD1oÆ®‰È¶)¶–ðûêD‘°§QGÏú~GiQ.žüâL­XTYbæO“ï7áýeúWììo à˜ÝE‘{0àNDãÖ°m‹`¿Ýudš‡ä[¸%BcpÅTì$KDDF0Hj »D©Ã…7‰‹Æ’›“Š vpº°ƒ{TWw!½ö¢¹àZìÌðÖá6ôFÆóz€Â\~2UÿˆÀ‰:9üŸÿvº2¬B”¬+Î…uË'IÇÃQàx{æ%ÜC}B¶>un®>Ž…%Gà!E÷öPáàîí•%~œ¾°ÊÂjœãÅ7åaÙÂ< >&IuýÂîék8ÅëûZ¤ã¥ ¸;ÎHØÓ‹ô ägã‰/lÀ¬IÅU–¸5òÚ†ØÁÆÐÚ=bw ™èdö-ÃvADîÁË="JÔ>» È4oî@Ø­û“£0·b®d»6QfbÔÁã.QÊpáMâlëàžd°Þm½²·+;Ë‹+ÖͲ¶ ²Í‹ÛåÁ´b¿Æ…*¦‡ZÔÝ¡/8c ®ß8ߺ¢(#ið•@~¶ô5m½êÒMLŽ+Ÿx4 _ºe•«v ýëžfì8Ø&¯ zl?©î—®™‘±çî/n¯—ŽqçR=ÚdÀ=}½±¯#á±ÿøY^ ?‡ßY'Š»ëcŒþ.*ÈÁ_¸Èñ‹N§O,’ޱƒ;ý3MÓÐbÎÚ‡í.€ˆÜ…w"JÔ^» È4ᨎæö^»Ë 4àñð°o&A;""2€wcØÁ(u<¯ŒIÌKÅ;¸G\Ø8¶¥G^ôÆUÓlÉ [wÓ2×ñv]ÙI±º,||µíSÊ •%~|öæ3•¯9Ú¦#êÂã±';t„£òñlZ€ÓK­+È+º·gyÊ"{'›¡ðè®2›×δ°çŽâµ=ÍÒñ`¾…ÅPB"ŠºAƒ‹~Éù^ÚÙ(ãy¿³ Œì®aDq¼€Š?~ù•‹±dV¹5…%aju@ºl8åÂZÊÁ"¢D±ƒ» šÛûì.Òu抹°{"ÙÇcctÞg&JÎKÆ$³ÞÕxwã¿Ó½CBÙîº s­+†lꞣ!éx0ŸóP&jïhí•O¦MÃÃwžcxÎ$2â]çÌÂy+&KÇÃQàx[ú_œô4uË¿Ÿ•%~|âÚeV”¼‡Ûñ²"t91è±}Ô¶>ùgkæ¤b×-(0Ëë{›‘¬,ÉöìíX²ëŸ×ƒ¿|Ç r·—v(vnây¿cô ìiЕ;-ÀäªB<ýÕK0gJК’”åó`Reá˜cBŒ†Ü‰ÞæõeÙ]B¦bSU"JîD”(Ümp²™Ü)yvß O71.ó'""¼l?i;¸¥Ž¬³©%³£“ျËòtÍ=ò÷hÖäbœ6¯ÊÂjÈNª@¡?ÈñYX 9Âpd´¶Êm×,ÅŠœ'ÈZš|ù£g!/^¶õ t¤÷õɱ6õ¿ï¾›ÎDAž»A[~&ïÞîóÕ6woFþÈl^3#cw³xã@«tŒ‹äœ+¦Ë9ûyNw¡î!ì?Ñ)/ÎãÞ ºö6Æß•fΔ žþê%˜\5v`Ü©fÔIdž"é}G‰ Ç8'Ù„w"JîD”¨F=v‘iÕuÙ]¥w M•L …ˆˆ2—×ËËp#»D)ãõò:Á‘Ä›âÂx \ŸE]´‹T$tôËë½î¢y µd­Ûå]LËxºt<¦';\p`§ž!¶^ùwtju·\±ÄŠÌñí§vIÏÛ4ÍÝÛ{†„t±„GÓpñYÓ­-ÈAvl“ޱ{»³ET÷€;»B“šÀ~EÀ=?‡ßY»Ô†tå-o»jýl×n!p,NW×/ݲ 9Ùî ¼5…ð‹ŽHÇ+²}$꓆V.®Fy0ÏÂjœeÇ!ÜÝJpò$0µu ¢£gìnÈ>w\°ƒp´MGCœ”à¦Í‹ðµ[WÃçâøáº.Ü÷½¿*_SQÈcòx9)Ù„ÍT‰(aî=;!";1ànƒ#u]v—@i€ÝÍÃUÝDDd„Gã±Øˆdƒ¤D$Çyɘd޸ǜ=êè×xíEóÀ\fyc_‹t,ÇC¦ˆêPvÌÍöá‘Ožëºð,¥?¦á¾›ÎT¾æxÈÙÇæñhì ËÇ/9{:Î^:Ѻ‚Lò_íFT²:PP´ÿ1¹@¨_þÚ´z†…Õ8ºƒ»……PÂT×-A®rLK{±{»“è8Ô¬£¥'6è5µ IDATþyÊ]ן†{?pº«¯Õ‡ÃQ|ä«/b$,_]S’¯¡´ÀÅÿH2Õ°d÷J9܉(aö_¹‘µ_¥RJì8²»J^//ÜÍ ÁNÉÆ°ƒ;Qêp^2&éîéÙÁ½kP &©ÑŸëÃek3;¤•iúÂ8x²S:`çÕŒq²CWvr½õªS0³¦Øº‚ˆ°ln…òøÕ;$ЮèÀít#Q ®C~‚Q—…ÏÜx†…™#Ô=„'þxH:^^¨9¢›pÏÎ>¯­œji=NÒ7Æ‘zyã'vpw6Õq¿„÷´tHqÞŸoìò— ŠéÀþ&]¹€ 4mt‡–]yŠ«Ãíð…þ kåŸÁl0«’ñ8ú»Î~&Üm ß^‰ˆH‚Gp"JXö-ìân¹­;š¨¥¤±ƒ»yØÁˆˆŒà±Øž¥îÆÛ:¸'õkS®Cð[úä9 IF–Ù~° ²¯Š?[ƒÍº3ÂÀˆ@s·|n˜RÀM›YXQâî¾ar³}ÒñÚ·^²oS×~ÇuËPYâ·® “üà7{1–—jJœñˆ\µ8bÍ© Ÿ3¦ƒGÚ•ç^gü IBp2÷sÎÚ:‡¤cþlÞw°JTö6êèTŸ˜ø¼°Ý}ò ra®†)Ùµ…œ#77WºK ¥îDdäDdî68ÚÐmw är^ýfaw""2‚wc’ ’‘œ—»<¢'47êˆ8x¡mHÑôœÓ&!/‡mû2I4ªã­CíÒñƒii/¦'Úå“ev–Ÿ¹ñ +"JN^ŽŸúÀ é¸.€ÚƒW¢ý“Ã-ºráÜ{/œ‹¥s*¬+È$ƒÃQ|ï×{¤ãA¿†‚gƒÚûäçNë–OF?ËÂjœE`‡¢ƒ{!óÑŽ§ºn \ìKÎÖÕ+gñ~hJ †v7Ä0,_Û(-ÊÅ/î¿+TYSXŠ}û©]øëžfé¸×Ì©ò€}èŸÅ4®º±‰ü$ˆH)7"2Šw¼u8dw ärìàn܉ˆÈ‹áq—(uØÁÝ=É„{EÐoèç"í +Ð1 Ÿ«7®šj]1ä{w`8<ö6Ûäfnf/cÔuêÊî­~×bL©XW‘ .9{–ϯ”Ž·÷ ô ;ÿÚ¥±K G±»BiQ.>yýr +2ÏÏD—¢“«Sº·Çt C±8pÓêéVãß»—ÞjÄ?#ïÁ¨iÀœj¼L‘D^^.ŸñÛƒÙ2"2Œ‡u"J;¸Ûà˜bE2Q< ¸›'æÀ` 9ƒ¤ÆèìàN”2ÜYÂ3Þ”ý ÿL4†¸±­Ö;$‘täóy=X¿b²µ‘í†#8Ö8öý+ @~çt%Äh€VÆçóà³7 zÈíʃyøð‹¥ãƒaö^g°»šºå5y=¶|b­2¸ïdϼ|u-òÝoÔ½½³_HKò³±æÔk r E÷Ÿsþ–46U·î’4 ÚÒ?**È‘ŽÉ®)qM݇[ã7A>oÅdüøs¢ÀïÎãúXºúFpû7·)_3¥Äƒ^o’‚иŒMp'"Ãp'¢d0ànƒÝGå°ˆâa¨Î<\ÝMDDF0Hj ;¸¥¯Œ&¤Ì+K¸@ØaáU÷ö³N™  :Pz:p¢Sº#/[§ôÕÞ/0‘ßtÙ"̨)²® ¢úàe QVœ'?Ù¡'½ã‹Y†#À¡fuîÖ«—âÔ¹Ud.]<ôóÒq6PZàœƒO»rç›iÈòññ};¸»š*Ì\àµAºRu ï±°4Vסãx{üpûæµ3ñ½{ÎCnvúy…îyä´uJ_ÈÓ0ÑA ÚÈ™ú†r‚žyöØ]¹¯‰( ¸Û`ÛÎ&»K cwó0àNDDF0HjŒÿÙ ÄyÉs:¸ËCq*‘¨³®ET÷ +§YX 9žcòæ \ïÞ:å'mU¥ù¸õêS,¬†(µòs³pû5K¥ã#Q YÑ1Ý*QØßCTqMµtNn½Ò½ßÏ?½^‡#uòokJœó8<º埋M«§[Xs5¨îìàîxª€{°ÜÓÕ¢™eÒ±¾!û‡nw¼]G]gü÷ñ}ÏÇ·>±¾4[,õôÖ£xö•Òq¯˜]éOSWÜØ„܉Ȱô:«!"K5lÛÒ  Ñî:2ÍÉ–ttØ]¹”×ËC¿Yp'""#˜#5F7¡S2;KcƼd4àî¤î}Ã#ѱǼ œ9ÅÚ‚Èö IÇòs9礫Ž~Á°|ü®ëOC~.ÛîRzyÏs1µ: ¯ïÒ•ÁòTµèÊï¦?ׇ]„Øò³·¤ã¹Y@¹ƒº·wô é.'eÅy8sQµµ9Tc»*àna!dH4&¿V pOWËæVJÇz‡ås©ébôXÞ4ŽEs¿z)>óÊ´»ÏÓÐÖOý׫Ê×L/÷€—×ëAChÈî22Q{ö-mvADîåλDä$ìânƒºæ»K —bwóDcl%KDD‰Óx,6ÄŒNÉD46vp7ÆŒy©"è7ôsaI Ü!E÷ö3U£„–Œ´ï8;¸g¢zEGÉI•…ؼv†…ÕYÃçóà®ëO“ŽGc@C—}÷O†tt ¨ÏYî»ñLL›PdQEæ{yg#v‘/¬ª zज_{Ÿüï±ñ¬ið±A ú#è{U†Ï;Ú¥—œMÕÁ×ékúÄ"Ž}²ÓÕóm$ ìnÐÇõÞýçÏÀ×.sÔ1Ï º¸ýÛÐ?‘¾¦´@Ce Íþá”yyyÊEX”2ìÞNDIá% %‹'#68Ñ$ßn“H…áó𘈈Œðzxn;¸¥ÁcgwU`ÄjŠÐ܆•S­+„#Õqðd—tçü=INu½ pµcºÒ4`ùü*éxã8:Óßu 쬋¡Xý¾y4 _¿m5n¼l¡E•Yë{OïÅk{›¥ãY^`f¯3h|„Æm`l²ÇîˆÈÝx¤'¢dí°»€L´÷˜¼‘ Ã+扱“,ÀÅfÆèÜ9…(e8/£›°àµÜpwg\‹„£ÀÐØÍ5¡iÀ…gNµ´r†Ãu]ˆFÇ>nçf>>‘HKªîí•%~\yÞ, «!²–GÓpÏûWHÇuÔuZ{=Ó3$p¤Mý;—ϯėnYåêN¯¯îjÂë{[¤ã‹=pÒ©®jç›ê²|,›Wia5ÎÕ¤¸çdYX&9Àîéî]çÎ”Ž Œt:ãZÖé»ö6êq·gù<øÎ=ëpåy³­)Ìbj;ñ•ÿ÷†ò5³*=ÈòZT¹^_œ#”2lšJDIáíd"Jî6xi§ü¦-‘ Ã+æì&KDD ò¸9=`#®+#JÎKƘÑÁ½Â`÷°C:¸«:.œQ†Šc~r7US†voOK=C½ŠùàæË#›©Jsg-™€³—N”Ž·öé¢0³ ŒìoÒ¡:U™X^€ïÞsž«¿›Büx»tÜ窊œuÜiï“ÿQ.9{:ÏËÿ×Ј|Ë.”sU(—÷ôvá™S1©²P:Þgg‘LÓƒÍ:N„â/Œóçúðÿ>{aÚ., Çpë[Q¬˜©*ÒP’Ïc'_K׈Ý%d*܉()¼ $¢d0hw™æP]zú†ì.ƒ\ÈË›ä¦bØŽˆˆåáU¸!:ºD)ÃE°Æ˜1/íà‘g~,¥ ¸¯\\ma%ä${…¤cù ¸§%U÷ö’@.Þ{á\ «!²ÏÝ7,—Ž µ©ïâ>ö5éPm€•—ãÃ>½eÅÆÚ9ÅÖíõxó@«t|b±^]GÔ]C/]=ÃÂjœÍë¤?QìvÅ€{zóz4ÜxÙBéx× À`˜÷øÆ2vÕÇ”»}¼­¸0O~qÎZ2Á‚ÊìñÕ½‰ƒµÒñÜ,`Z4~uíÌרdŸÝ‘»ñˆODIiض%`—Ýud¢º–»K bxÅ\ ÛQ¢x,6ÆŒNÉD46ÎKƘ1/ se  eX±’j{ù•‹Ó÷A;©í;®êàna!d‰þa¡œ >xéBøs}VDï$Äh÷KžJ[cÑŒ2\ºFRîèÊ€s²"1`_S á8 áüÄZ,˜^š²:¬ ð5U÷vP]ì¬s\U`qJu‹f–YX³ñòÄý¢’î>¯ùyYÖC–»rýlò³¥ã ìâþ/:vÖÇ08ŽÝ^L/Åï¿u–ΩH}a6yñÍz|÷é=Òq Àœ*g-d#çóûsrþ±ÁɆm[zí.‚ˆÜw‰È ;œiw™¦¶±‹fUÙ]¹Œ—w‡M%ø„ˆˆÄ-Çá¢2¢Ôá¼dŒYóRyqšB ýL¼àšF¢£HÇâõhX±€÷+2‘.ö—wÙËÏå|“nê¥Þwñ| «É\mƒx}_ þº§»„ÐÑ3„¾ÁúÈéy9>LŸX„5ŘQS„¥³ËqÖ) -²"µ;¯]†ß½rQI õÚÀ¢óç˜ìoÒ1'wǵËpÑÊ©¦ÿ~«=ÿúIì9*ß1¤&èÓ>Þ¡>ù|¹iõtð”üï<Š­ïx;Þùbº|çÛ` ‡Ÿõ Ÿ›…ë6ÌÃ#¿»?^[¯@u‘@!¯ ÔuèÊ‘Þé]çÎÄý9 y9éój àÖ¯oU¾fR‰ÆÏ%Lx¸ÀÊ&{í.€ˆÜ/}Ï|ˆÈJ;ì. í¯íÄ%vA®ÃîŒæbØŽˆˆÅc±1<æ¥ç%cÌÚY¢<èO8஋ÑàˆÝÊz†äÿþųÊQÀÎŒ©94€ÉʇlïèÿQú t(:ß°q¾²{'%'Ô=„ÿ~v?žyé8N4©wú‰bßñŽØa¡¨ VMÅekfâô…UlŠa’)Õ\{Ñ\<öìþ1Ç{†º‚ùæ½ßB[ô¸Ýáß{á\ÜzÕRÓ~¯]t!ðµ½)Ïò:¯{ûPè‘ÿ}.]-ïüŸ‰TÓï 8_tìõ=€’@®u…­ÞÉ|çé=ˆJ>GZuœ2Ù›Ñ;6DcÀ¡]ŠÝÞæózð™ÏÀû6ÎOëE"‘¨Žùt÷H_S«aR‰ÃV±‘+ô§p'%RÚiwDä~ ¸‘p·Á«»Ûì.\ˆás™j!"¢Ì¡¥óSˆâ1—(uØÁݳÞTó ý\8 äÙ˜íQ<„_¹¸ÚÂJÈIŽ5ÈC¶þÎ5éFÕi27Û‡^¶ÈÂj2GCk}zž|þFÂ1Ãÿžþüô¹Cøés‡0¡,½ê\³~|Nk{íB¿z)~þçÃ{Ë•Úâ| fÍŠGÚtt ¨ÏKÎ?c ¾ðá•iŠûÝ+'pèd—t¼¦Äcë"À±´+͞Ĝ)A «q>>Ãp·HLþy2àž)*Küؼf~ñ‘1ÇÃ@C§ŽÉ¥›°-20"p Y—îŠöNåÁ<|çîó°|~eê ³Ùý½åùÌ©ô¤Åù Y¯µk_8J…ív@Dî—™gŒDd¶ýâl~IfÛu4„x{Žývc2»ÉQ¢ø Ös‰R‡ó’1fÍKåA¿¡Ÿ +‚#VPup_¹x‚…•“­ï–ŽÙ¹ ƒÌ7ÚûäóÀ{/œ‹Ò"†ØÌt¤®·cκñçxüÙýI…ÛÿYSh÷<ò*ÎùðSxæåã\\š¤²â<Ü|ùbéøÀˆP~QÒÑÖ«þo-Ÿ_‰Gî:>§¥¾ ˆÆt|ý'òŒL¶¨.rÞ¹m{Ÿ¼¥õ¥«§[X‰;¨®O8=9_Tqx*á¹AF¹íšS‘›-ï·Yß%0 ØÝ" 4u ìª_¸}ùüJüñÁÍnøÞ¯÷(_3£ÂÃëJ2Äãñàdkb»'’iØ,•ˆ’æþ»Dd»†m[ÂöÚ]G¦Ñu ¾Yþàh, ¸›‹a;""J;%ã1—(e8/cVø¯Ü`÷ˆy¹Æ„ G }ïóypÚ¼ôøNc;Ú ¿OåÏâ\“Nš{äaMŸÏƒ›/g÷v³ì:ÒŽ¿øgœ{ËSxêޤô¼¸¶¹·|åpñm¿Áž£¡”ýžLpÓæEÊE'C:’ýS6u 4t©ÿ#³&㇟>_0t“§·Sî2©Ä§ÝþPõ)º„÷ÁëwS]§”r¬+„l7¹ªw\»L:.p¸U &?­L+½Ã;ëuoß9À ÏÇϾ´%ÆÅ»I]Knÿæ6åk**<>1~®r‡J™uvADîÇ€;™…+ïlPÛÄ€;%†ÝÍÅŽVDD”(.63†Ç\¢Ôñx9/aÖb× ƒ÷pÔ”_oˆª{ûÒÙåðç¦GˆŽÇî™A(;F_¹n6ªËò-¬(=mèÆ{>ý\|ûoðÇ¿ÖZú»÷ aÓ'~‹‡±‹ M *ÈËÂǯ^*‰-=ÆßÛPŸÀñvu"°º,?þÜE(.L@i4ªã›OÈCåøàÈà[¨_þw^4³ Ó&YX;x×'œ‘œOp²ƒ{¦ù·K`ñ¬2éøÀˆÀ¡=­¿Û‘p¤UÇîz}\ës²½øæ¿¯Áç?´Y¾ôs…#1|èË/ o@¾ÌŸ­aFEú¿”Bž,»+ÈT;¶mIç)žˆ,³"2 î68PÛew ä2 ¸›‹܉ˆ(Q<£³Ã QʰC¢1fþʃƺ±…mœU÷3U[X 9²ƒ{6çštÑ5(¤á5Mn¹b±µ¥!€Ÿýé06|ü×xù­Æ¤þ[^å5ö³Ñ˜Ž¯<þ®¼ûwhhíKªŽLuíEó0©²P:^ש#j km÷ À¡Võäà'Ÿ»Òh±ÉÏþ|õŠÏâäRçuo€®ùØ¥«gXWˆ‹dûä—»ÑøD×)Áî™ÆçõெÏ+%uÔÆY´åFBÍÝÛkchU,}§šÊBüúk›pʳR\s|î¯+wòz€yÕÎ<Æ“{Œgq ¥Äv» ¢ôÀ€;™…w¼´³ÙîÈeª3—`7Y""JÆ ©!ìàN”:¼F0Æ´î·ØÙÁ}Pþo_¹x‚…•“ô„ÑÞ54æ˜×d³±ÚhUt>û”‰˜R°°šôÒ?Á­_w<ø†F›è r5L j˜?ÁƒÓ§{±j–gÎðâôé£ÿÿ”ÉÌ®ô ´@C"—$Ûׂõû¶íhHð_CY>>yýiÒñh hìJ,Ð×?"p Y‡êò('Û‹Ç>s>fM.Nè¿íd#á|ò-éxnPQè¼sÚ‘èèßLf㪩Öã"5Ò±áï 8jB îiÞÔ|äÝK”¯iìIílâ4½Ã;ëukÿb¶5§Öà÷ߺ g”¦¶8yæåãxüÙýÊ×̬ðp70JZKWÄî23dDd ܉È,»°w‚Åv¡o`Øî2ÈE¼ Õ™Š܉ˆ(Q ’cV§d"úWìànŒY o*‚y†~.lSÀ}82ÖK–ÏƒÓæUX[9Æ1E÷öK‰þùØÂ¥ÖBŽÓŽåfñ>D:hí•Ïyç.Ÿ„²â< «q§§·ÅǾ¶5îymŽX\ãÁ¤ v{j‚¦—Ç?Oxèg;ñÌËÇ-¨Èýn¿æTäåÈW-Ô†ÚzN„Ô ºšŠüès¢0?Ûì¡£g?øõ^éx OC±ßîoˆ\§ü°ˆ *HÓ¿›™&”çÃ' ƒG€HÌâ‚h\"Ša°wúWž9?ýÂäŒëõƒaàH«Ž7OÄp¬MGç@â¡s™¡0ÐÒ#p¨e4Ô¾«^GS·04ßÌœTŒ'¿¸ÜuªJóÍ)ÐÅ~úüA<½õ¨ò5³«ÁÂüøs¡²ÄovyŽñ_¿Ü…aùV5NîÞòïúy+&[X‰{ù¼,œ._@Ù;ÄûòNUKŠp§±-Ÿ_‰§¿v fM.÷Ï„c@sÏhW÷׎vX?Ù¡£µW ght±f !€¡Ð=(ÐÒ#PÒq YÇëÇcØ~2†£m:Úû“äàÞœŽçº«–L0öI3ûŽwàÓþUùšš †’|gÛÉ:û¸"Î&Ûí.€ˆÒ o/‘ÙÞ²»€LôÚ¾V Ž ß?¾ª3;¸Q¢$5†Ç\¢Ôá5‚1fvpŸh°ƒû°…Ü#1Hòûs}˜61`]1ä8ªîìÂç~mŠîíeÅy8÷´IVã>?ÿóaÜñàKˆwؘT¢aJ©3/*<š‡[ô1Ãb00Á‡î¿ýÆ&äre‹Ò‡/_Œýn?ºú[£Häåøðø}`FMQ *s†¶ÎA<þìéx±_C‘ƒü³H è–á×-gÀ}¼–ϯÄÎÃícŽõ ”8÷s©T®K|~Ir³&ãnƃ?Û‰G~¾3¡… ¬wÿk×´Ñÿ)Õw'Uâ¦Í‹påy³áÏåyÐÛúÂøÐý/ ¬˜yÎ=&÷;Þ2hw ™ŠMQ‰ÈTØS^¨anµGy¼:PÛ‰Ï|ç5ëŠr©n½ziÂ?çõhøÎÝë°tNE ªrއ± ÊֹNïÞÞ¥èÞ>mB¦OLßÅ f;m^¥t¬wØÂBhÜT÷`€ÜI-;Ë‹;¯]†g¿y(vpH„Hq¸ý”Ùåxôîuxù{W↋ç3ÜþBwnyµÍ½Ò×dy¹UêóK"£üþ\t÷Ëw¢”bw"2•³ï˜‘ë4lÛPgw™èH]§Ý% °k¬¹¶#"¢Di ’Âc.Qêh|’hˆ™óR~nù‰w4‰X77(BD f˜> ÷RÜÙÈÙ݆ÂÀ"pÕúÙÖã2?úÃ|ò¡Wâ¾nj©“JÜq,.-Ð0§J}sñ‰çâé­G-ªÈ½®ß05 îàòµ¯Æ9i¾cBc{?~üy÷ö’| …¹Îþ¾t*îç­H￟ٖϯ’Žõð6óDcò?J°wŸ…3Jñì7.ŧ޿¥EÎûÜäd{qÉÙÓñ˯\Œß~ýRl\5 ^ÞïýßÿÍ^üîÕÊ×Ì©òðz‘RÆëãÎ!6pÄî"ˆ(½0æFD©À-gl°ýÀØ[5½»ê™‹܉ˆ(Q<cf§d"úGìànŒÙ o ¹£­šUÜšÔ]Ü«¹CÕÁÝÂBÈtƒòïþ¢™e˜3%ha5îñûWOàžG^ûº©eÔ¸$Üþ¶² ŠÕ5ÿÇïàhC·E¹Sv–w^wÚ¸_÷ Ëñîu³RX‘3<ô³ˆDå»FLvx÷v!€.ż¹nùd «q¿ò`¦TÆèæ}§Qup/awJ€ÏçÁ‡Þµ¯ý÷Õ¸ÿ#gaÚ{w¿ðz4¬]VƒoýûZìüñµøö'ÏÅŠUì<.±mG¾ðƒ×•¯™\¢¡ØÏ7R§Äî 2Ö[ Û¶(ΈˆÇ€;¥î6xîõú¸ÛÝ1¼b.v“%"¢DñXl ¹D©Ã…7Ƙ½ØuByâw±h·eUÀÜIÝÁsŒ›u):_´òÿ³wßáu\uúÀß™[tÕ{—-ÉŽ»„‡R –%,}—ewi›]ÊÂRö·ÀÂRBBu „T6¤ÇJHb;v\c;®²ueI¶ºn/3¿?”€CtŽ4ã)wçáÉópæZ_Ë÷Ι™ûžïér®ÙtŸúÎãs×ݨ¢£Ö›ŸîUÚE;‘ÊáC_ÉtÎÁª¼ç-¯]Œ]us÷Á7¯Æ‡ß~†¹ëÈà~÷ð>áxC…‚Š’ÂþÌL&uäùüвÎY%îHN³[»¢Y86•t°šyÀtɸH8ˆø«åxì'ïÀÏ¿pÎ;½Õ±gáP¯^ÓŠ«?t6ßø÷øõWÞ€·_|*ÊBŽü|¯:ć¯]'}fRS¦`A=£jd¯QÉV„d§-n@DŇýSˆÈ ¸»`x<…cÇ'ÑÞìî*v*l ÕY‹a;""2ŠARs¸k ‘}x`N!tp€tNGiØÞü¤Aú`@Ų…ìàìg¹¼†ãc‰YÇT.ˆ,“×fš"Ÿ½ÀÁj¼a:žÁ?_ó0⢓æ 5ªsvA/dŠ,kQ±íh¢fÛÏÇ~ü¾õ‰ -ÎCTEÁçÞ·ÿôå…ǼùÂÅøâ•¯òE‡Øïþv+r¢t8 ¿{;ŒI½ö¬„‚ óµvU3n_·Ö±©¤ ðß~"Ù€µìàN§  *xý¹xý¹˜Œ¥ñĶcxls?Ö?Þ‹U â•+šñêÕ­xÕꜹ´aÞÌ2KãýW=„éxFxL80sɳ7Ù)àÈ0W¹„Y1"²îDd‡­nàW‡£ã ¸“CuÖbØŽˆˆŒR$5%ÏEeD¶á=‚9VŸ—ÚMvpŸ#Ci‰¸¤{û’5üÒßçF&’ÂÏC˜ß>xÚDRîÙTW†•Ýܽádš®ãßéÅ¡Iéq‹›T´V{î„€¥-*v§o}d^sFÞöºÓ¬Ì[^ûʸàÌv<±màecçŸÑ†ï|òB_\«ˆNàÎÇÇ+”Ù¼ Ï ²€û%ç,t°’â±v…¸ëýTJ#î…EÞÁw²FuE Þt~7Þt~7tØwtÏÃÑáŽMáèÐ4ŽMcl25³@LEª(P ¾º Z*± ¹ ›+± ¹­UX¶°A.D2-—×ðák×áð1ñµ°`Y«ÊEÐd»Ò²Rä5ñB ²;¸‘åøˆ™ˆì0`€xï@²Ås‡Fqþ+»Ü.ƒ X À‡3Vbw""2JÁLÇC®‘2†s.‘}¸ðÆ«ÏKí§ÐÁÝîXO,-[½˜W¿‰ ÇJ‚<¿xÙ¸$¨yñÙ |ÑQÚˆünÚpDzÌiM*ZŠ Üþ¢ºríµ ÆÅül.;g!*ËÃVæŠüð3ãíŸùöøÓÿÙ«:Ñóé×úfÙ·o~VØHD°°¾ðŸi'3â…‡ŠÂ]/ÌZ¼ 5•%˜˜~ùi^›éâ^]Z<çU¯ËæÅóîdE–uÖbY'wsÛÕ×oÂ[_¾`ïd‹šTž³É9QH—$<ïvDT| ÿ‰yN´·G·žqÅã;Ý. œ:þ8‰a;""2#Äg†qÎ%²O€wS¬ÞÍ©½±ÜÔëÒ9K˘•¬ƒû*Ü}ï˜$àÎîÞ& ¸¿î•VRøÛÜoÞ,oT×^£U¸ýE]õ**#â¿×ØT ?¼}»ƒyOme êynøâåøê‡ÎÃo¯y#®ÿÂe¨( ¹]š#öôáOŽ7U)(õÀ¯BÖ½ý•Ë›î5IU¬])îâ~bšÏ INÐÁ=PQî…2™rËCÏãú»wIi©VŠb#ò†‘i¶;¤Ùl‹öö8𤒈ü†ßª‘]6¸]€=µý8NìONž¥2¼b)«C-DDä “—cÀÈ6 Áš’—t'4££©ÒÔëÒ<vp_Ô`TÐäÜ,„,•ÈèÂ4Á€Š Îlw¶ vdp ÿvÝcÒšªKt5ç×qŠ,oU”4ÿÙïwaàD̹¢<(TqÙ9 ñ¾7­Äùg´ùj‡„oÝ$^¢(À‚:o|vd÷KÎYè`%Åç ¯îŽÆtîW ò ztS[Uâ«ó‘Ÿ<³{ŸûÑ“ÒcªK,nôÆ|NÅáÐ`ÂíüŠMP‰È¼Š "»0à¦¡o`Ìí2¨€1Og-v“%""3p7Žs.‘}¸Öœ¼Åç¥ÆÚR„C’t @:gïùQÓg‚®"«±ƒ»ßÉî<¿xÕ˜øŸkW6£²<ì\1,‘ÊáÊkÁT<#<&œ €s°¯$,iÝ˜Éæqí¯6;XyÅŽý#xpÃáxK•‚ˆš>ç4`*)¾^ºtí«)>¯?·Áàìç˜l˜”üîÉ99M<Æ ˆŠSôx W^ór’@$Tü×ÂTXÊÊ"˜Œ³‰¸KäÛš™Ä€;Ùe#>UrÁþ# ¸“˜ÂðŠ¥¶#""3ÎÇFY$%¢?ã-‚9vÜ ´5”~M:gï×DFܳ³µ eH‘­d÷0ßž5.éD|ñÙ j€®ŸùÁØÓ'~«(ÀŠV&Ö/yN}¹‚š2ñEÅ]ë`Çþ+"/¸î&ñÂÕCÝÛ'âºðz¬½±Ë:ë­§ØTW”Hw‰ñyA!ÈJv¸bÀ¨øÄSY|ઇ0:™P•mþ¸¦Â–¸]‚Ÿ1àND¶ðÆ“"òœhoÏ$€=n×áGÏî;áv TÀØÑZ÷?%""ØÁÝ8.*#²Â6Z¦hº¤E¡IíM†_£ë@ÖÆÆTñ´xl5»·€¡QYw !ËÌÕ‰øbv"ÜüÀ^ü~ýAé1‹UTFü3Ïv7Èÿ®W]¿A¸hŠüç™ÝÃX¿%*o­VöÈ<2&YtÉ9 ÙµÖWœß-‰d’sryñX-îDEEÓu|â[½Ò…ž°¬EEY˜“ 9+&yŽE¶Jƒù0"² îDd§§Ý.ÀÜ8àv TÀT>M·ÃvDDdF@å­¸QìàNd/.¼1ÎŽóR{£ñ€;¤sö#ciñŸ½j1î$ïà^ä¹Å‹&âNÄm åX² ÖÑz ÑÈD_ûå&é1-Õ Zªýõ(/QÐ\%þ;oÜ5„‡7q°"*dßœ£{{‡Gº·ë:0–_/]ÊEA–¸üÜNƒ³¿'²y`T²È€œ‘•ÜëªØM—¨˜|ûægñÀÓ}ÒcºTÔ•ûëZ˜ ÃÀ¨xW²Õ¶hoOÖí"ˆ¨8yãéyÕ· ð£q ž˜r» *Pìàn-܉ˆÈ IÓ4ë;%ÑŸ·õ[ú±yϰp¼½FAÐC™ð©”xì’µ\d¥¿>¿­ åÂqvqw^2ìаoH“vp¯cw"Ï;1žÄ¿ú0Rñ ûpXéㅞ侜îó1w1àND¶á·WDd›ho`£ÛuøÑ;ĈÉߨ³ÃvDDdF ÀùØ(v^!²ïŒ³ã^Àl÷tÖâB^’ü¹-UÜ!Œ08*¸û=àëUÓ’ÝÜÏ]ÓŠòHȹb Ð/îÙçˆwÎl¬TPSÆsc@Ö‹¿~ŸNã7>ï`ET(4]Çu¿woª@›‡º·ë:0_¾Æç‹‚¬ ª¸ò-«…ãã ñ4Ÿ8AÓ£c:¶ÍKw1xQgk¥U‘]Ò™<þùš‡¥ œUe&Üæ} ¹hdÚ¦d4—hoO¿ÛEQñòÎS"òª nàG?;ˆx’]pèåØÁÝZ Û‘AÎdžqÎ%²W o ³ã¼ÔÖPn*4.ê²~ªRYñß±³µÊžJž"ïàî`!d™˜$xá™íVRx†ÇøöÍâ`n@ºø•Û‹š«”…ÅsÚoÚ —ø¾swï!ì<8"ï¨SôÐÇ(žÖ‘×fk¨)Eg ¯—¬öî×/GeyX8ÞÏ.î¶›LÎÛŽj˜Ï-QK}9ÎZÞdaDd ]>ûƒ?âٽǥÇ-iVQá³%rסÁ„Û%ø»·‘­<ô˜€ˆ<Š3.Èi?(&ÿRØaÏR¿‰#""¸à̸|žs.‘¸³„qvœ—¡êk"†_—–ÑOERÒøª‹w‚<à^äyÅ‹¦Sâ±W,ów8íªŸoDLrb\XÏŽ•'St7ŠÏ£“ؼgȹ‚Èu™l×ÞøŒp<Z«½5wLIΙkW6ƒâ­WQÂ?½q…p|$¦c2ÉçvÈæ}ÃvF5Ì·¿VUy7|ñ2îüDäa?½k'n_·_zLG‚ÆJ~ÎÉ]e¥LÆmêAsa&ŒˆlÅ€;Ùm£ÛøÕ.I'ò/ꬥ±›,™Py+n;¸Ù+ÀûÃì:/µ7V~MN›ùŸÕdÜ»Z+­ÿä9ìà^\òÈÌþ¹W`Õâz‡+*On?†»?(//QÐæ±`®jË”—Ⱥ¸ïs°rÛ¯îÝèñ˜p¼£NEÀc·ÊS’ õÚ•-Vâ/¸bB’VÿŽkÜ!ÂbÃS:¶ÉãøÔü±¯?·ÿðíX³¸ÁÆÊˆÈN>Ók~!zÔ•+èª÷ØNEI •¸]‚Ÿ1àND¶â•Ù*ÚÛ3ày·ëð£Þ­ƒn—@ˆ2¬Å€;™Á ©q ¸Ù‹ç%ãò6¥f:šŒÜ{º¸§$»Úª-ÿyä=ÇFÄAÅÜ='žŸGwÔ ¢4ä`5…#›Óð…?%=fq£ÂNÍ-Uâ_Ì=OB,!Ù.„ŠÆd,ïݲM8 y¯{; ¸Ÿ³ªÙÁJü¥©® ïºt©p<™Æù Á ‰ °#ªaÿ°†\~~¯ik(Çõ_¸ ?ÿÂehk(··@"²Íþ£ø·o¬“.* +XÖÂȆXŠs¿K2žu»"*n¼Ú "'lp»?ztó)~A@/ÅîÖbÀˆˆÌPœÊk6´&&¢?áÎÆiy{îÚLtp€´ »0'%¡ùÎvp'y÷’ ¯w¼&–±Ä¿ÝWyÏnˆNÇ›ªT•òý.ÒX¥@ô82™Îáÿ$ñ©xüà¶í˜”œd:ëUáû¤P¥²@Fø-- bU·w½p§ßóJT”‰^ÓÀ¯ÇÌÓtàȨ†­GóÒ…' ¨ ®|ˬûÉ;pù¹6WHDvŸNãý_}±¤øD +Û¼·û ¯¾ã)·Kð«­ÑÞÉÓ"¢SÇË "r·¤qA&§áàÑ·Ë ÃîÖÒ¸×)™à|l;¸Ù‹ܳë¼dºƒ»Åw]ÿ™UA»É >]†F³Ž)Bìàî9²Žw§ŸÖè`%…#“Íã'wîŽU »_³ÉU ¾B|ñÛ¹ùk±‹ᆻŸŽW”(h¬ôÞµ¨,ôûŠeyn°Scm)>óOk…ãš8®OŒ›HèxöHýcº´sóÉÎ\Úˆ{¿û|ñŸ_…òˆ?w|!*¹œ†ÿÏ£828%s1šëÊì-ˆóôÎAü÷Ož’SS¦`Q#fTxŽO¹]‚_ D{{úÝ.‚ˆŠ¯>ˆÈ)\¹ç‚t&ƒý£n—A„_2[‹܉ˆÈ vJ6Žw"{ñ>Á8»ÎKÁ€Šö¦ ïKf++’æ»ZÙÁ€x*'cwï‰Iò§ŸÖà\!äG·oŽ•†ú ÎF4U‰_“±4ÜÐç\1äˆÇ·FñÇíÇ„ãÍU ÊÂÞüM¥Ä×I+ºëPQ&Ù²€,÷Ù÷­E‡äú9¯{Žå‘å:š?Ék@߈†mG5LKÞÏ' T|ôg`Ýގ׽Àæ ‰ÈIG‡¦ñ¯_{¹¼x¥K$,oQ¥»f¹¡$Bÿ‰„Ûeø3`Dä>j&"§lp»¿Ú}ˆwú3•O,•Ï3lGDDÆœbÀÈ^ûÞµ¾ÜÕ…¨˜Å’Y|à«a|:-<& +ÛŠO³D® GJÁ ×]À;9»OˆÈkpwÉãÛÄ]RÈvf´”Æ;f""2’“u"¢SÇó’q9»v·™ ˺®%É.£“wÜyJñY÷ÖÓ—4:XIa¸ýÑý±phªä›ÜŒ–jñïíÉíǸ¨µˆÜùØì鎷×*ðrFvJ²ëîîX½¸×}üé1‰ŒŽýy¤Å›ÐµDØsLÃîcÚ¼Uåa\û±óqÇ7Þ„eµöHDŽÓtÿæz<d\zÜòea‡Š"2(–æ½™‹p'"G0àNDŽˆööœpÐí:üèQ¤3>}bG/ÃîÖÒøÅ™ 2Hj˜AR"T•²3„×ÝVmêu²PºQ²°ü–Jë~yV<ÅîÅ"§¢Î`@ÅŠ®:g rY.§á®õ„ãm5*øxÍœÚ2Ex~˜Œ¥ñÜAîDZ R™®ûõfáx(´{xM—/ Z»²ÅÁjèdo}íi¸ò-«¥ÇÌtrÏ ç½b”Îû‡5<{$ÑøüïaÞúÚÓÐû¿ïÄß¿~9¿W"*R×ݸo<"=¦»AE­d"·=!YyHvÊxÖí"ˆÈ¼ûˆ¼ˆ+ø\Jçq¨Ÿ_Ð æV¬ÅÎRDDd;%Ç9—È^èv T \±–Æ»f""2ó±9\WFdvp7.Ÿ·ï¤´ ¹A­M“’`º±?G<ÖÕj®»<iw.®÷”TN|îXµ¨ÎÁJÜ—Éæ±~KT8ÞÌîí§Lpß´{éLÞÁjÈj=·lC,!žºTx}Šuý>ge‹ƒ•Hme nûŸ7aÍâ†9=:ªaWTC:ç@a6KeÃ'4l:œÇ‘Q yN»ºÿàmøô{^é»[ˆü&z<†~õaé5WIXѦ‚ЍÐÅ3Œ<ºˆÙ/"r ÏöD䤒náG÷=u™,¿ @ñú7†܉ˆÈ IÍá¼Kd.¼1ÎÎîUÁ‚&ãÒSYXÒ¹JÞÁwšO‰“`ìàî-iÉ¢–…-þúÌoÙ{IAÊ1¨uœ/OUYÂ.ø™lûúÇ-ˆ,sdp ¿ºo·p¼2¢ ¡>C²€ûZvp/µ•%¸åkoÄ+—7ÍyìdRÇÖ#y Nêžì;™Ô±ç˜†Í}y Lè†‚íµ•%øö'/­_ÿkœÖQc_‘DTF&’øû/Ü᱄ðU™ ·s­ yÁÑ’íÈÈn ¸‘cø¨™ˆííÉxÆí:ü(‘ÎãPÿ¨ÛeP`pÅZv†Zˆˆ¨xq>6G÷â7ÍDÁnËÆÙ}/ÐÕf6)=ni‹ŠŠž¨ð…BA/Ö [E£½=â­Ïˆˆ,ÆGÍDä´ nàW{3àN€Ê'•–b'Y""2ƒws8ïÙ‡ç%ãr6Ÿ“ºMÜ )é¾>_YI×Ç–úòSþó©8Ä$wvp÷Ù® í> ¸oÜkÊ8WZ¥\šÚÓÇî^´mß üá‰CÂñºrÕ¥Þÿ ɺ·Ÿ½¢™ÏÞ Py$„¿òz\~n缎Oeç‡4l;ªa,®£žBä5àÄ´ŽÝÇ4l<”Çþa ñ´± xÇÅKðÄÿ¾_þ—sQW±©Z"*$©Lï»ê!ì:(Ï ,¨+ŽÝVÈJKË ±!Ž[ؽˆ%؈È6¼ØqÉS;ñÖKV¸]¹ŒÁk1hGDDf8›ÂÖDöáyÉ8M› ¼Øõ›ën«6õºT@Ù©ýì\^vp÷]®¹a“p\ÐÝPƒ,à¾ve³ƒ•‘p?ÿüe¸á»pÍ ›•ì4ð¢XZÇîc:ÂA ©RAS•в°Åþ…œŒÇuŒÄtŒÇuœÊ×—³ÿùOgcyWuQÁËå4|øÖaÓsCÒãê+tÖÇ|MþÏðþÌEÌ|‘£üót’ˆ ;¸»äÞ§úñµË# ¸] ¹ˆwkå´¹†ý%IÍáÂ2"ûúu8409¯×er@t\Gt<ŠÈLgãêÒ™(ìx´“ÎÍ,¤˜Jé˜JÂp‡öÙ¬]قϽo-ߣD>¤é:>õÝÇñȦ£ÒãªJ,ka¸¼¥$åv ~Æ€;9ŠäˆÈQÑÞž¡Ž‹>¾ÀR·kñ›éD‡£cXÚÕèv)ä"n“j-íˆˆÈ .83‡ó.‘}xŸ`ަéPmJòšíà.iª=oYÉ:Þê ÜiFŒÜ‹B:'ëhªt® ;V—rž´R$4sž˜m÷€‘‰$&¦ÓÜ1Ä#ry _û¥¸{{@I7ØœˆÖvƒ*ÎXÂï]¼`õâzÜ÷½·àKÿû4~÷ð>C¯¥tÄ^Xä *@EDAUdæ¿%A PbÎà»®ÏÌ¿©¬ŽTöÏÿNéÒyÙE.=§|ó*œwzx»Gä?º|ù§p×úÒãÊK¬lSmY´Cd—P0ˆ¾¡¤ÛeøUÀV·‹ "aÀˆÜÐ Ü]±çð(î>§ð …¥ò Ú‘ ’š#ê¨ID§Ž oÌÑ4°i“´Žæ „‚*²9c»F¥2§~®ÌågÿÿË#!„‚ÅR£S—HŠXÜ­Æ;$øÑÞè¯‰ãdNiHALЙxd2É€»GÜúÈ>ì?:!o¯Q.’ e’k¬u(å6žQ á›ÿ~!Þøšn\sÃ&ì;:nøÏÐô:­'à¥ï`f:¼ë˜y–¡ëøÓÿ2‚km+T”†ðw—/ÃûÞ´­æv„"¢âðß>‹_üá9é1‘°ª]oóÉkJËJ¡éi·Ëð«-ÑÞþò‰ÈQ¼Û&"7ô¸Òí"ühî!üÍë–»]¹HÁL÷æÃ¬ÁN²DDdƒ¤æpÞ%²Ã¨æØ¹ðFU,h®”vžM*7s¿gv-•,Oϰ!,.IF³ƒ»w¤sâóXG“Ïî’ómiÈÁB|" ˆEŒN¤pZ‡£å ‰Tß¼i‹p<Úk‹gBHHb<Ë»j+„,sñÙ pÑY¸ó±øÖM[0p"fÉŸ›Ë¹¼³Ï/:[«ð+Vá]—.EE'-"¿»áîçðß<+=&V·Šf!ùK"[<טô´Û‘ÿ0àNDnèu»¿º÷©~\ý ~ÓèkAUEv¶=€É0íˆˆÈ ÜÍѹBÈ6ÆáèNëlp»rQ@UµqL?É3àNDD&°S²9\XFdÜͱ³ƒ;t·Uè7üºdFG$dîß4'9ײƒ;,! ¸ó”⩜x¬Ýg÷Á‘ø¬ÿ¿¢%ü&Ír²n¡£“)ç !SF&’øñí;„ã¥a ¹ª¸&ƒ¸$󼬓ܽ®$À•oY÷¼a9î{ê0nt?žÚq¬àv­®(Á^݉+.X„לކ`°ˆV‘Ñ){xÓQ|ú»ò>ƒXÕ¦¢Œ 8É£BÁ Í~ïFŽxÜíˆÈøXŽˆÜÒ Ü]±·o”wŸ @Ò¡‹æw""2ƒ]µÌ±;HJäg ¸›£Ù¼1Vw[•©×%³€Ù˜•¬ƒ{MeÄäŸJÅF×xjö ÅÔ­×ÒYñõ•Ÿ:¸kºŽŒ D@ ¹“µ‚Àìï?Ü ßw~»U8@W½ZtŸywÜ‹EY$ˆw\¼ï¸x NÄp纸õ‘}èïòa·¥ kqΪf¼þÜ.¼æŒ6„j'¢YlØ5ˆ}ýQé÷–ЬhUQ)²Iš|¥´¬yÍ»­¡ÝÑÞžãnADþÀ;¹¥ÀÜ.žÞ9„7]´Ìí2ÈEìkv’%""3$5Çî )‘ŸŠ-äg:¸—ÌêÌvpÕT°ƒ;ÍH¦sÂŽ¦ ¸{‡¦C¸Ã_EiUåþùÌg³â“/Ýí!;Wdd«­Èu£“¸ùþ=ÂñªRõÅõÁÉæÅçËÊò0ZêË-ˆÑÞXýí™ø·w‰Ý‡G±é¹!lÞs[ö càDÌ–Ÿ ª8si#Ö®lÁÚ•Í8{E3wQ"¢9í<8‚÷å!á‚Í-oQQSV\s4ùO"ˇ.ZïvDäO ¸‘[äûc‘mîz¼_þÐù%ûÀRQcÀÝ:ìàNDDf0àn;¸Ù‡ç%st›ïÌvpOeÌÿLyw†khFBÒµ—wïHKv÷koª(ºîË2²0§H{È.íKB|n]È®½ñé3Ñî†âûÐÄÓâ¿ïòÎZ_/ýHQ€U‹ê±jQ=ÞÅ*ÀàH›÷ c×ÁQ Æ1<–ÀðXÇǘŠË/ÆÃ¡4W`As%4Wbas%´ÌüwéÂZ”„y$¢ù;Ä?ü÷ˆ%å[w/iV‹nùSt”ÝÛ]ÄŒ¹‚w"rE´·çHÇEïÐår)¾3Èb_ßVÖìv)ä’ ¿m¶ ;¸‘\lfŽÝAR"? ¨¼G0Ãî…7mM‡svaûK3ÜÍ‘ý¨êаé?—ŠK\žàŽޑΉÏMV⾌dû ¾¥í!»´ç³ËµyÏ0îªO8ÞP¡ 2R|š„$¯¼¬³Ö¹B¨`´6”㊠አ½l,•Éad< 3ç³PPE0 "T ¨‡œ[ˆÈÇFâøû/܇±©”ô¸®ÍU<ñ÷ƒAô %Ü.ÃÏw»"ò'܉ÈM½`ÀÝÛ÷gÀÝǪ³N.Ï ÇNÉæä5qðˆˆN ÏKæØ½£“ª(XØR‰ý†^—ÊÎtÆ5œÉIþNìàN/’ud.Õ;Ò9ñX{S¥s…ywΑv­ ‡x")Dº\}ýFḢ Åùo—Ȉ߰Ë:묄¼ ¢£Ù_ó(9ot2…÷|á~‰Kë¨UÐQËëY*¥e¥ÈåÙÁÝ%{£½=CnADþTœOˆÈ+¸…KÜÐïv ä"ܭà™Á ©9làNdž—Ìqbg‰î¶jS¯KÉw'ÊI:¸×T0àN3’7îÞ!{¤á·-iIÀùv{ÈvA VBóõÀÓ}ز÷¸p¼¥ZAiȹzœ—䍨ÁˆˆœKdñ_z¢òÅð-Õ ºŠtñùS<Ã÷³‹˜í""×ðìODnâEKÖo;†‰é¤ÛeKp·ŽÆ¤™À.æpÞ%²îæÈÂyVén«2õºdÖ\m²Smy±¦ÖȰTZÖíÚÁBè”È6¥+-ñ׿¿òîâ#²8ßž\NÃ×ùŒp<  ëŠ÷+ç”äºjéB܉ˆÈ9éL¼ú!ì<0"=®¡BÁâ¦â›ÉŸ3ßâ¢õn@DþÅ+"rÓaQ·‹ð#Mvw[¡âð›9«ä´#""$5Gw HJäW\xcŽ oœîà.ÃÓ0ÍO'Þ!;‡•ù,à.ëàÎKw{$3â±®Vs‹»È>¿yp/›ŽwÔªiã}MD§ˆŠÒêª"ÎDDD¾•ËkøÈ7ÖᩃÒãjÊ,kQÁËX*&‘H ¢'pw›—‘kp'"×D{{tðBÈ5Ïìv»r ;¸[‡w""2ƒwsØÁÈ>“r3]Dä*^Ú‘ÛÖ»]€_˜ÂÑÁq·Ë °;£up'""38›ÃîDöáÂstÞÔV– ¾ºÔðëiëkãýÍ ß&žÁîVUŽåòâÓ)I÷övvo/$Ãc üô®Âñ²°‚¦Ê⾎”vpgÀˆˆÐó»­øÙïwI‰„€Um*‚L€QQRð|Ìí"üŒw"r/oˆÈmp;—ì:pÂíÈìÎh<ˆˆÈ IÍaw"ûpá9N-¼YÞYkø59 ÈäŒÿ,ÙÅûz‘Âk™¢ ëà^ê³î ’…DÙJ2e"!þ®è®s°šË7oÚ‚dZ|AÑÕ ˜ÚiÆKRYñûuAs¥ƒ•‘ßè:pÝM[ðÍ›¶H Õí„ýu O>RQQŠÉ¸‰‡\d܉ÈU ¸‘«¢½=:xAäš'¶s»rîÖaÀƒˆˆÌ`Ôvp'²Ê'„¦8µðf©‰€;$2Æë“ÍP<vpÿ³ÚªáX–Ü-7‘wz›s…ÔÎ#øÝÃÏ Ç«KÔ•ÿ½­$ßvvp'""›è:ðÕë7 ç–­Òã‚êLçöHȡˆ\‡xÇ-²ÝÁhoOÔí"ˆÈßøõÜ]r×ãGá·4¾`zÅ2yvñ"""¸ØÌ+‰ìÃ%Ìqê¼´t¡¹€{ ÙZ¾îÌ©¬xlA;¸‘õ4]Ççô$~öû]ÒãTXÕ®¢¼Äs2ù×À˜™\d‘õn@DÄ„Ü]Of±¯ï„Ûeê³N./ù6˜ˆˆH€ÜÍaÀÈ>šáT÷ef;¸§­íàάˆŠ‹¼ƒ{À¹B D}M©pŒýA¬3¿ñV-ªG}uÄÁjHäÿzbóžaáxc¥‚Šˆ?îkÓ9ñ{–܉ˆÈj¹¼†Oçqüúþ=ÒãXÙ¦¢Ò'ó1ùW0ÀþhÌí2üŒY."r¿½"¢B°Àq·‹ð«íÏóWï7 ÕY‡""2ƒs±9NI‰üˆÜÍqjáͲ…µ0óO”0ÑàJös4Y»gò…猢Àî/ÕP- ¸ó:Ô*ǧſËóÏd÷öBHåpÍ/6 ÇUèjðÇ×Ëšdr³•–QWÅDDdlNÃÇ®{ ·¯Û/=NQ€e-*jÊx_Fů´¼Œ÷cîbÀˆ\ç'DTТ½=:€ÇݮïîÛxÔíÈaìàn܉ˆÈ IÍaw"ûpá9N—*ËÃh®+7üºD†܉HL¶x°´$è`%…¡¡FTÍ ®dL* L$Äï» _Ñá`5$òÃÛ·ch4.ï¨Sá—S„l÷†öÆ S ‰ˆˆf“Îäqå5ãž?–§(ÀŠV œ„Èâ¾×]t8ÚÛÃ0¹Žw"*ëÝ.À¯þ¸}ãS ·Ë 1¼bDDdçbsØÁÈ>)žGÞuÉþ{ßš¯^¿ÉŠŽîF~z´œ“,ª®(q®""*Z±DÿðÅðĶéqXÕ®¢¦ÌG1ù^i¤#I·Ëð³õn@D0àND…c7€Q·‹ð«MÏ ¹]9ˆÝ­¥³›,ĹØ+‰ìÃó’9š$ôd53Ü ž±®vp§âso‘½CÔÁ½4â¿îíÐR_.‹\,D/7–Б‘tÂÿ»Ë—9W ÍêÉíÇpÿS}ÂñêR þºf”íÞPÀ;¢‰é4þöó÷â™Ýòïéƒ*°iEé IDATº]Eu©¿æa¢`8Âg îb“R"* ¸QAˆööhw»¿º«÷0o|„Ü­¥3äADD±S²9/X‰lÃ[sœÆu7mŽU ³ÞŸÏ“syñ{·º"ì`%DDT,ú‡§ñöÏ܃ƒÑIéq%AàôŽÊ8ÝOUT”a*žu» ?[ïvDD/òç "*T;L¸]„_õnp»rÃ+Öâ—÷DDdT€s±)\TFdEÚ·›Dœ>/-ë¬5üMR¾ ÍÞ¼0:™4üó©8É:¸sAšwˆúè:Îú³‹ûK…cÓ ¸›6<%nƒýö×-vÎ'g|ëæ-˜Œ‰±-¬W¥×ÅLÖÁ½†܉ˆÈ C“xûgîAÿð´ô¸H8}A‘C… <ÄÏÈlNJDƒw"*ÑÞž<€ÇݮïîþãQ¤}º±ß0Tg-M“|ÓADD4 Uá\l†“’‰ü&ÏkZSœ¸/]h<àëâ”ØÆ¦ØÁfH;¸ótâ²ÇCÉtÞ¹B ÈKeÜ,¤ˆL$téB«w¿~™sÅÐËìíïïÝ#/ ­Õþ½ÍIN…Õ ¸ÑüííÃÛ?sGâÒãÊÂ3Û%kЉ|!:Êîí.Š8ìvDD/bÀˆ ÍCnàWñdûúN¸]9€Ü­Å/È(ÎÅæ°ƒ;‘}t~¾Lq<àn¢ƒ;$ äÒeZÇØÁ^ „ öò­KXýË[× <r® z‰ŸÝµ Ñáiáx{þóÈlñ;ɬÛÜúòƒs.­-S°ª]•.>%ò›ƒƒI·Kð³>Ý.‚ˆèd¼L"¢BÄ€»K4 عØí2Èfì.c-†ˆˆÈ(ÎÅæpÎ%²?_渱ØuYg­á×h:’7Œ{ Ù–èãìâN/(tpfž/Qác÷Ù½ñ¼.áX,­#i`W ¿ÒtàȨøDÐPSŠyÛ+¢“ ŽÄñý[· ÇÃA`A¿>ž‹Ê_ Ü÷äa|ðê‡‘Éæ¥ÇÕW(XѦ² ÑIJ#%86Ê€»‹z¡))QÁàí7¢uøU˜KzŸº]ÙŒ¡:k±ƒ;ÅNoæ0€Kd^ÓšãÆyiÙBãwHdæ_k( ž§Fp§H;¸ó©ž'H;¸û8ྼ«K%çÚ1Ιsב‘¼…>õž³Ø½ÝE_ûå&ég¼«]d_$û´ó¾žˆˆfóëûöà#×®CnŽÝÏ+,oa¸è/‘yïBH¶`3R"*8|DAD'ÚÛ3`“ÛuøÕ­žsE9y[€OK,ŰÅÅfæä9çÙ&Ï4ª)nœ—d¡K™„ŽÃ² ¸ÓŒÊ²°p,Ç9Ûd݇)ÿÜào.\$;1Í9S&›¢ãâßÑ¢öj¼û²eVD'{f÷0~¿þ p¼2¢ ©’÷«"™Îx_ODD'Ëå5ü÷OžÂýèÉ9Ÿ4W)XÚ¢‚k¥ˆ^îÄs*.Ò0ÓŒ”ˆ¨ 0àND…Š+]2Ï`Ï¡ãn—A6âÃwké\FNDD)üöÂ.*#²;¸›ãÆïmY—¹€{¼;ŒÇ›«TFx¯z2Ù'MdˆˆŽ Náo>}7ß:0ç±µ 52¢E$RQQŽDš+æ]ÄŒ$^=Q¡Ú`Êí"üêwŠ·)%ïSÙ]ÆR ‘Qü"Üœ|žs.‘]øù2Ç€{(¨¢³µÒðë’Yóm8’´u›bÀfÔ׈îìàî Òî)Üào.\,žÔÁÇA/wdT“Î5ŸÿÀ9àcIwLÇ3¸öÆÍÂñ€ tÖó+c#øV&"¢ »ñ¦OýD'æ<¶³^EWçZ"™é4?#.cÀˆ g"*HÑÞž,€un×áWÏDßÀ˜ÛeMª³–>ß”Ñ ¸•¹9Ù;¸ÙEã5­)n-v]ÖYgø5º>rŸPP<Æîô¢†êˆp,ËE3ž J¾J¤²ÎR ÞtA·p,›†$Êýh"¡ãÄ´øwrù¹X»²ÅÁŠèdß½e+F&’Âñu*Â’ù߯dwîi®æ""òµß=¼ïþÂý˜˜NÏyì¢F êø<˜h.ûân—àgS˜iBJDTpp'¢BÆ‚.ÚºwØíÈ& ¸[Ë®DDämœ‹ÍÉåp'² ;¸›ãÖ½ÀªnãwˆÏý½; 1àN/`wï J¾aý¢½±ç¬²£c»¸¿ ›ž_««Š‚Ͼw­ƒÑÉF'qÃÝÏ Ç#! ­†÷¨³ J®‰¦bç !"¢‚‘×t\}ÃFüÇ÷GnŽfXÕ¦rž%š‡Šò2 ÏóÁÙaÝ MH‰ˆ ×ãQ!cÀÝE÷=}o½d…Ûe ª³»]‘Q*;¸›Â€;‘}xMkŽ[¿·Õ§5˜z],­£±rî9Hp?>ž0õ³©øÈ;¸;X™V"ùv(:<í\!ìCo[ƒMÏ Í:–Ƀ“:ÚX¾!Mú¹ÿ»Ë—aÉ‚ç ¢—¸êç¤÷R‹Uðqñì’…@S ܉ì6>ÆÞ¾1ŒL$1:™zá¿IŒL¤0:™„¢(8­£¯9£çÞ†ÉL"+Ä’Y|ìºÇðȦ£s +ÛT”…9ÉÍGN ¹]‚ß=ìvDD" ¸QÁŠööì¸èã‡,r»?zhSã“ ÔV—¹] YŒ¡:k±ƒ;ÅÅfædçèŠDDæå¹€Ä·îV/ª7õºØ<›¯—ÅóÔácS¦~6Y€ˆwo( ‰?ëýÇcVR¸.=§k7`çÁ‘YÇ£cZ«¾ŒëOˆçòHŸzÏYVD'[·¹ë6÷ ÇkËÔ•ûø <ÙNÓq܉ìLçðàÓGpë£ûðÇm˜kMñ¦ç†ð›÷–uÖâ5g´áü3ÚpîêVT–‡¨˜ü"z<†÷_õööÍylU©‚­ªtñ8½Tÿ¯­\Ææ£DT°p'¢B÷€¹]„i°}ß0^»¶ÛíRÈb ÕY‹Ý.‰ˆÈ(.63‡܉ìÃkZsÜ ¸7Õ•¡©® ÇÇŒuS§çWo(0Ó±t¶ÓîÈD±Deì¬åwõÕâ€{&ÇsŠ„ƒ€¢`ÖàØà‰ry AYûbPà“ï9 ¸jöïú³>ïâKéè•_£éÊsÑ\Ç*nÈæ4|åg„ãŠt7úû3>Ù)pš܉,£ëÀ–½Ã¸í‘ý¸û‰ƒˆ%²¦þœçŒãù#ã¸áîçð®K—à“ï> Mœ‡èmÞ3Œ+¯y#É9m®R°¸‰»£‡pà`Üí2üì0€ƒnAD$Â'DTè¸RÐE?;àv dÜ­¥1kGDD)œ‹Mɱƒ;‘mòy†QÍps7'3]ÜsšgV¤TÒÙùðà¤áŸMŧ,DYdöþ9ìàî €A ¤¼¦chÔØ"šbuéÚ…X³¸A8Óf]Tìò°wH“vÖ}ÓùÝx÷åË+Š^âx‡Äsvkµ‚267–’upŸbw¢Svl$Žïߺ ýëmxëÿû~óà^Óáö¿”ÉæqÓý{qþ•·â›7mA,iÍŸKþsçcð®ÏÝ;¯p{WƒŠ%Í ·U)Cž;¦»é¡hoÿˆ¨`1àND…î1üZÌ%·Y±»]‘QœŠÍÉú19Dä~‰dŽ›÷«O‡-ebóìâ‘4hï;6eêgSñ‘uqgÈÝ"’Å,ÇcVR¸^ìâ.’͇Nøï:õÀqMºhª£©×~ìpó*wŒL$ñß>+€…õüŠx.Á€ø Ì€;‘y'bø÷o­Ç«ß ¾qãf>fßÚd:‡ïݲçÿóïðË{v#Ëæ 4Oš®ã7nÆ¿kýœï›€ ¬hSÑQË "3Fb<7»ŒMG‰¨ ñé´hoÏ€n×áWÓ‰,ö:îvd1vp·–›]‰ˆÈ›8›ÃîDöá5­9n. X³Øxw`þ÷RIG×Ã’n°ä/µâ€{:ËóŠˆ:¸@ÿñiç )p—®]ˆ5’…EÃS:FãþyÏOé81-þûT?øÏ‹QUÎöànùŸ_=#í‚ÜY¯J»“ÓŒ€äw4Í€;‘a±D×þê\ô¯·áÎÇ8º`xt2…ÿþÉSx݇oÇž8$Ý„(‘ÊáC_ß¿uۜǖÓ;TÔ—óy/‘ªªbwï=]¤XçvDD2||AD^Àƒ.Ú¸kÈíÈb*['YJgˆˆˆ RUÞŠ›‘ÍsÎ%²K^ã3Ü\°z±¹îñÔüŽ+•tuîdwš± ¹R8–”tv¦Â!ëàf÷) ð©¿wq€Ú/v.HfæîXÿÿx6^¹¼É¡Šè/íØ?‚[Ù'¯(QÐ\ÍçÃó![0:9Ï‹*"B.¯á¦û÷₹?¸m;Ò÷&Ì#ƒSøÈµëðž/ÞÁ‘¸kuPá㟹÷?Õ7籕g,  ¼„ó*‘Y刧}p#U¸6¾Ðt”ˆ¨`ñ[u"òÜ]të£Ý.,Æ®±Ör³k#y§bs²9>è&² ;¸›ãæï­£©5•%†_7ßîY÷c ¸ÓŒî¶*áîÞPõ³‹ÞÉ.Y»¾¢]8žÍû‡‹{ÁX:÷Ã?bd"iøÏ€¦*µ ºU,kQ±º]Å+ªXÕ¦¢½V1.~bë.ùè¸cÝvs§?Ù±ýÉÿÃ΃#sÛX©`M‡ŠpÀˆŠX,ÃØ¢Ë˜Å"¢‚'¹5'"*ϘPív!~ôüÑIô Œ¡«½ÎíRÈ"ìàn-'·Ñ$"¢â p.6%—ãœKd.Ú4ÇíÎ÷«ÕãÛzM6?P,™ã©°¬ƒûác“†~&¯î6ñ£ºTF¡,xɹ zœáÍ“) ð­O\ˆK?z'&céY‹ëžÒÑ\U|ïýtØÍ#%Y¼R_Á÷>ýZ>{tÑï{`óžaáxc¥‚ªRþûÌ—l—‹£ ¸IíéÃW¯ßˆ'¶~­¢õå šªÔ–)M+å%@mùÌ`6L&uŒLë‰Íïþv:žÁ'¾½nèÃ×?z>ê«#†k¥âñ‡'á“ßé×õ*Ôq>%²Â¾„Û%øîDT𸊈 ^´·'àQ·ëð³g÷¹]YˆÜ­Ån—DDdF€ó±avp'² ¯iÍqû÷¶ú´S¯‹Ï£‹{(OŽG'S˜ŽgLýl*.]­ìàîu%’ðfÿpÌÁJ¼¡¥¾_ûÈyÒcÐæ½[†Wdæn€oò"4Õ•9S½L<•Å57lŽ« ÐÕÀ¯…€€àWv|,d:çlADp|,ÿ×óÞð±» ‡Û+" 7ªxUwË[UÔ•‹Ãí)*,oUqæÕóÜÿT.ùÈíxpÃCõRqH¤røÏï?\»nÎp»ªË[n'²Jyy)†ÆRn—ágSÄ7DD‚O2ˆÈ+¸rÐE÷=yÔíÈB ¸[‹܉ˆÈŒ`€ó±QÙœ»’‰ŠY.ÏkZ3Üî|¿fq½©× ¿Œ¬kéácS¦~6—îvq÷d–ç/! Ž ŽÄ‘Ëóúë/½ùÂÅxó…‹…ãy Ø5 !Q$ë€29`Ç<ÂíW¾e5.>{3EѬ~xëv ‰;`vÔ©sîàB/'»Šr!ÑŸè:pó{qчnÃ-=oè{“æ*guÎÓ[k§VKEDÁš«ÚT”—ÌïùÛèd ÿ|õÃøä·{1Åż¾±óÀþêßïÂo|~ÎcÃAàô |¦KdM »]‚ß­{¡Ù(QAcÀˆ¼‚w=¼9бInU,¸M°µÜîÚHDDÞÄîÆe°"²M^ãçË ·ïV/6×Á=–š_Ý¥’ïû'Mýl*.µ•%¨®(™u,—¸6­ð)€0ðšËkÒ°¬Ÿ]óáóÐR_.Ïå]s‡Â Ý|ÃíkW6ã³ï]ëLQ4«ýýøñ;„ã%A £–÷ fDBâ±#C\ðGG§ðwŸ¿ŸýÁKÌò«)SðŠ…*–4«( [Žª-WpæBK›ç¿ÀçöuûqéGï@ï³QËë¡Â¡é:~|Ǽù?îÆ¡¹ïm+Jœ¹ €ŠçR"+EG=~Ãä}Ì`‘'0àNDžíí9 à€Ûuø•¦;ö ¹]Y„Ü­åv¨…ˆˆ¼) òvܨ SrD¶á5­9nïæ´¨½e’Ô•@<=¿ºe.vp§u·U Ç’ž[¼€Ý‰«©,Á·?q¡ô˜Ln&äžñh?¼ù†ÛÏZÞ„_}éõ‡N±Ý.™¦ëÀýðIä$÷KÝ*øHØÙõÐÑ¡iç !*@yMÇÏ~¿ —~ôN<µcpÞ¯+ +ÛT¬nŸ‡u³MU Îê  ¹j~?kp$ŽøâøÔwÇä|·¿"ωãÝŸ¿_ûÅ&éÜù¢† §/Pæ.(D– ‡CØåý¦Ëp'"Oà7êDä%¼ÀrÑúgÜ.,€»µÜµ‘7±ƒ»qY܉l“ÏóšÖŒ|, XÙ]oø5éÍÏ}\©¤‹âácìàN3º$w¯w¯ö YGÓþã oŠ\ðŠv\ù–5ÒcRY`ç@~^çÜB2‘бõèüÂí7}å ¨,—lùA¶»}Ý~lØ%–V—*h¨àý§Y‘ øwÇ€;ùÙþþ ¼í?ÿ€«~¾©y®æ €ÅM*ÎZ@]¹³ç¥€ ,iV±²MExžk²n{d.þÈxxã{‹#ÇÜÿT.û·ù/ÈXP§`y+‰Ù¡$RVÏÕ|ìP´·ç ÛEÍîDä% ¸»èÖG!íÕ–Cô ÔY‹Ý.‰ˆÈŒ@€ó±Q™,îDvÉsѦ)…p/°z±ñ€;ÄæÑŽ”ÜiºÛª…cìàî ²îú'¬Ä{>ÿspÅ‹¤Ç$3Àöþü¼Î»nÓu oTîmÎPþ+–1Ü^ƧӸúúÂqE7ýöî;>ŽúÎøç7[¥]õnÉ–;Ø€mŠ Iàr¤“~÷$—‡<¹ãr¹»Ž”»äòä’+\ !D„äBBè6L3ÅXƹ[–dYeÕ»vWÚ:óü±æBˆf´;ZíÌì~Þ¯—_žíWhËüf>¿ïcϹÐêàÞÒ=–¹BˆL"“q×cGðþ¯>‰Ã̓I#  ®D`ÃbjŠ„oK¥žD7÷d'þ ŽNáÆ_¹ý5ŒN†æ¹:š/£S¸éÇ;ðÅÿz%©®üv XU#¡¾Œq*¢ù2àµ~ƒ1{ED–Á…tˆÈJ^ÀõN àŸŠâtû .]µÀèRhŽ$#¯f!3„ZˆˆÈzì ¸§,çEo¢ùçëK3ŒÖ,-×u\0”äkï“§z=×Ãî”°D£ƒ{Ù2­É,Mg’ ®å*›$Ððk1Žá•7ºT÷ EcÝ2.¨P]dÎq@8œé“1šý³mÝÊJ<ôC†ÛÍàÖÞÐ \Ö äk¬ÈB³ÓZÑæhˆ†u‰2éÄÙ|óg;q²}$éc* êË$ÍÉ"™f·%ÂËC~ge$³`àÓgñzS¾ù¹ ø«÷®„ÝÎà³D¢qÜ÷Ô 4<Ö„©PrMÜŠòVTKš«ÑÜ!pª+`t¹Žw"² žy‘eø&ì5ºŽ\¶ÿxrK¶‘¹IìàžV2»]‘\Q%uᨠ~êÍxœ¯.=̰”òÚyìàn·%:×ÍdÌƸŸéeV-.UÝæO"(KÆóºÕÏKµ›â½ÎÌìv ¿üö{ðŽ‹k4÷“ mPÆ™~f›W6PÐÔg¸ÝbœêÇ#ÛΨnwÙ…¥¼ Nú£ìŽÄqÛïâú¯=•t¸ÝíÖÔJXYm®pû[U$º¹—x’»F7:ÂwîÞë¾²Ûöu‚·†ÌKQ€—ßèÂ{¾´ÿýÛI…Û…êË$¬©c¸h¾y ¼L'7鄿E‰æ¢DD–À+Dd5/]@.{üµv£K 4`÷ô2C×F""²Üõáç.ÑüLG.Á’Ìðž´|Q ÜÎÔï¾'p´»–¦Ò¹‘²×ŠE%𨤖¢ñDçj27·p¨¬—˜Žâ¬o<³YÛiǯ¿û>¬[Y9ë¾C~G»ã&ù><ŸBQ u@Æé¾äº×2Ün±˜Œoÿ|·æ>K+%Øx8- 4&iÊ`%D™w¨y¸i îzüHÒ“Þ ¬[dCq¾ù¯}9íÀE $,¯’T'³¼ÝYß¾ð/ãSßÚŠCÍ\íÆlZ»Æñ¹ï¿ˆø:û&“:Æí.®“°°TÀüÏZ"뛎ð$Õ`û} è‘eðSƒˆ¬æY£ Èe-]8ç5º š#Á@]Z™!ÔBDDÖc“8×#n¶v—DYbrŠ T=b& Ø$U‹KR>.ERaFK}Û±¶á”—²M¸te…êvvq·­ðfÓ†7“áÍsàÁ¼«5V5xÓThêJtsŸŽd ¸· ÇÝäuÆ10™Ükô#ïºÿÇn7‰ûž>–®1Õíe^Ò$;Óì¼nõm ¸S¶šÇðƒûöáÿü Ú’œì–çL„„/¨°Þ›ªÂD7÷TÞ;œÀÇ¿ù ¾ø_¯àpó ;º(ã™gñéï<‡÷|iû’>¶ª01!Cë|˜ˆÒ«¥oÚèrÝKF@D” .®CDVs @7€…F’«7÷cIÝì7jȼ$ÜÓŠKu‘ìà®O<.«·%"Ý&‚¤ë²€Y&»®]Z®+\ +(ÊÓþ<òº€™Îý.= IDATã ¸ÓyëWVb÷ÑÞ·ùC * xÞcvnÑà̯õ¦3ƒøô{Wd¸"k*òºðØ­Æ—oێכzfÝȯ`ÈGU¡ÀÂR *‹!¤M8øFeôO*I‡ð\N~ðÅ«ðÙ÷¯…4߀wñgKUW8¢ôjóãáÏ`Ó«-ó‡S:Ö.˪$”{-ü¤%² üü<ô¶Œ.#×1àND–€;YН±A©»æ¦­¾dt-¹ê‰ígñ©ë.4º š‰w£ÒJf[""Òw}8±Œ(ýEÁ8å=颥eºŽ „€¢<í}´:–me ‹Ö­ªTÝ6Ê`!¤[Æk½éÌ`æ É%.<øƒ áÑ&üô‘ÃIÉ& úã¨,(/(Êi Æe`|ZÁh@Á ?ù`;,[XŒ_~ë=X•DWzÊ E¾{Ï^„"1Õ}•IpñîoZiuõ=qvј ‡“ Èúb1?{¬ w=v$鱎Ç%°¼JœŸ›* Šóm8;(c8üçÉöüëÝ»ðŸ÷ïÇ'þl>÷¡ÕI­ìB© Gâx~Ï9<ôb3öŸè×õ=* —Kpòó’(ó$®e°ao]Q*xÊFDVÄ€»v@ÏÀj«ŠŒ.…t’x­=­ÌÒµ‘ˆˆ¬…+ªè‹ËF—@”u‘8—R×I–Íñž´vi¹®ãa‰~‹êòB`ÆçHW¿0м.]OÙcýJõ€{0¬@V`énž¹À«ÞlîÃT(†|7o'%Ë& |í³ëqÙê*|õǯadbö™Š’ºL*°I@I¾@©G Ä#R^À(Fƒ Æ‚ ƧS µ¿é3ï[‰|ñ*þÞMfÛ¾¼òF—êvK`AßpÓÍa\öÄ*oÉ8un—,¯È|aDiÔæÇ?ýd޵&·J“À¢R u%"+WøpØ€U5Fƒ :†eL¥0'<0ŃϟƃϟÆe««pÃWãúw.ËÉ 碵kokƦí­O±[û›¼n¥BsâͯŽ!6Ù0Øs¾Æ†$×(!"2^™""+Ú Àcp9ëÀÉ^Ü-ŒÜÓ‹w""ÒƒÜõ‰Çù¹K”nÓá¨Ñ%X–Y:¸¯^R »]B,–Zà>ž½~I§8†ÿSÇÚ†ñ®KkSz\Ê>eEnÔ×¢³oòO¶) )(Ìã¹™Ù% Ï LÏ5ÇÛ†qåšêÌfqïZW‹>/ýh;œHú¸¸ ”ÿéëvN»€Ó¸l‰¯v@–HˆÆDâ@$DbÊŒ!ÜdyÜüè«ïÄÇ®Yªÿ›Ð¼LGñ½{öj2;ƒ¦fPà«tr~ýH/îdY²¢à7[OâÖ I.ïVàX^%!?šð–zJòm˜TÐ5*Cc<=€ƒ§ðo÷íÅÿºnnøà*,YÀû«É Ebxv×9<übsJçRoç°‹Ë%TòC’ÈHn· mmA£ËÈuÏ]QªØÃ•ˆ,Çרð²Ñuä²Í¯µ]ÍÄîi%³Ý%éÀ€»>qvp'J»©ÐRp9Î,“]v +§|ÜT$¢œ×­¾íx[r)ûiuqŸœ½y5™€V'Ë#-C¬$»T—yðø}7}fœ©¶b?/&§ ûôŒ+87,£¥_FÛ Œ®} F ü!ýávI|òÏ–á•»?Ép»IÝñÐaô «‚jŠØ‘v>hLÔzU£«>‘™õñ¿oyÿvᄂÂí’–TH¸xan„Ûß$P]$°¡Þ†ú2 6·ØÆýaÜ»å8ÞýÅ'ðÙ[^Àó»Ï!”jZ>G OcëëíøÖ]»°ásãkw4ê· Ô–lXlc¸Èl7ï«+ à%£‹ "J;¸‘Umðq£‹ÈU;ö¡oh5…F—B:H Ô¥•YB-DDd-ü<Ö'.3àN”nÓ!vp×Ë,Ü`ÍÒrœ:7šòqÁˆ‚ÂYÂp^— ÒÁ½•wJذª[v´Í¸m$  ®„ç>fWàœœùµÞtf0ÃÕd»]Â?ß°7|`k£/µ f’‰›B»f)þé3ë°¬.õÉR”'ÛGpÿ3'T·;l@}9›šÌ§Ò|s*Û7bÌFI+£5é¥(À“¯µá»÷ì?8Ãò-3(ÌXQ%Áí˜çâLÌ& Kª‹lè•10¡@Ïðõ#=xýHv ëWUâ/ÀUkk°~e%\N}“á¬l"ƾýØs¬»öâLçØœ¿§ÓT TIp1Ed]üi°F_cß.½GDdr<#"«z‰»«¼;fYêÃõ×0ànEÌÓ¥îDD¤‡ÝÆd=Ì"Ê&ÓaÞ\ÒËL÷µËÊñø+-) …ÚíîÇØÁλrMµê¶7»J3\bn¯uÜÓ£¦Üƒ[¿üNüã§.ÁÆæím†u0¸þàkµË1ØnfqYÁ·¾Kó¼ã‚ væÛçUžp;+*¼¬(Øq¨Ÿ¸vYæ #JÑèdÿz÷n<¿[mÊÆ¨/“P["xCö<‡ XZ!aQ)08© oBžñ½a6јŒý'ú±ÿD?~ Àå´aÃ[ïëVV‘…oîé(œìÇîc½Øs´'Ú‡‘®Ó¡@u‘@i¾€à–ÈT\NZÎŒ.#×m5º""=xI™ˆ,Éר0PwÍMo¸ÒèZrÕSçpý5+.ƒt`ÇØôbÀˆˆô¤ì»A• ±îDé6â²èz™i,°vY¹®ãáÙ{xœ‰pÀL¡ƒî?;–`e})×¢£oæf`# Šy=ÂÌ¥ BÁH@QYûjváH{Žõaϱ>€ÛiÇåV᪵5¸êâ\º¼v ÞC‘žÄž£½Øs¬GZ†ÒzÞã´Õ…UìÖNdjvw>ârÈè2rݳF@D¤OñˆÈʶ‚wü|ЇÁ‘*˼F—B)’ض ­ÌÔµ‘ˆˆ¬ÃÆ gº„£q£K Ê:SÓìà®—™Æk—–Áa—Mq"?4ûÏ D"ÜPÙ÷DÛ0Þµ®6¥Ç¥ì#ðáw.ÁÝOqû0î¦'àu Lª¼Ö›Z†ðþõ®*»-«+ÆÝÿògøÏ|^;Ô—÷wáµCÝL¥÷³¹¼8ï¹l!®»bÞui-¼ùŽ´~š?CcÓ¸õªÛ%,­´^ØÑªJ4î¯ìF,.ÃnãïƒÌ'Šâßµ½Øœô1u%‹Ê$®œ¤â|â|H ˜TÐ?!#<ǹä¡H ¯éÁëGzy®Dà}e} TxQ[áE]¥ *¼(-tڱ܌ kÀîóºúÏÿ=àGGïdÊãÔd”žïÖ^ÂníD–Ð;Êë;åklh7º""=p'"+Û à?Œ."WÉ2pðT/>ô®F—B)b÷ô2S×F""²~ëްÓ4Qºõ¬¥N€XÜOŠ \øÄµËð‰k—!“±ÿd?^Þß…‡»ÑÞ31ã Zì6 ]P†?¿|!þüòEX³¬Œ /,ꇿÞ0¢º½®TBç+dLQž€Mâ3ä4'ƒnÄUg¾0" N àæ;v «ßŸÔþn°¢JBa?7ôpÚ…¥u%6ŒM)è›P0Lϸq:ÃΦìlêù“m.§ µçCﵕçÿ®ð`Áù|M¹N‡mNí $ìýþ? ³Oj|V¥“ËTI¨*ìÖNd!N§§ÛF—‘ëØ½ˆ,‹§}DdeÇtXdt!¹ê™×Ï1ànA‚7´ÒJNõ.#‡—6ƒP„܉ÒÜõ‹ËéïB7VW¦p]ÜKòµÇ‰nþ‰™Ç>Çt<&e§5KËQWUßÀ̪‘ ‚š"^“0³·0ók}ÿ‰þÌ“£ìv W_²W_²ÀFÄâ2F&B™ÂÀhý£SÂÈxN‡ •¥y¨(ÉGeÉþ.)tsŨ,ðú‘<µã¬êöªJó”]eH8ÇÿýÅÍ}–VJàeÞÌ+ñ¨Ü·¼Ö†[n¼’ÚÉp§ÎâkwìÀ©s£Iíï°Ë«$”zø¦2Ü`q¹„ú²Ä„ÏÑ€‚‰i™¾Ä5ægöçÀã(Ίò óĬ+Ž‘¹ Œ³iÁFì3º""½x*HDVÇ™†’eàÐÉ^£Ë qIâô’Mj!""kà o}B܉Òmd’”ô2[À}êJ]Çù§gÿ9òB5Dç `”Ï#:ïÃW/QÝ61­€sjÌÍíHü™‰¢¯¼Ñ•Ù‚ˆrÔÝ›Žâ\¯zÞŠâYV_¡ùQêUÿÿ>æãåý¬†èÅb2~öh>|óSI‡Û˼ëëm ·g€@¹W`Eµ„Ë—ØpÙb–UJ¨(pæx[Ê|'PS$°ªF•ذn‘„%‰I¼„Jdmv»':g^å2æy_co¬‘eñtˆ¬n€ ÑEä²­»;Œ.RÄîéÅ€;éÁ€»>ìàN”~ÃãÓF—`Yñ¸¹ÆuU¨(I½³²?4ûÏ!D¢‹žvq§7]º¢ ÊÕWúë“3X éQ¦ÞܶÁM¢ùÖÞ3Ÿ?~Du»].¨àxÒ(N[¢‹»šÇ_iÉ`5DÐÒ5†~óüø÷‡‹Ï~¾e“€ÕV×HpØ2P ý ·¨.XY-áŠ%6l¨ÿCà=Û'oÿÙ××Û°´RB¹7ûv¢\“—ŸhŒ× ö¬Ñͯ€‘¥ùÂ^2ºŽ\öì®nŒML]¥€÷ô’s…ZˆˆÈì6Çõ˜fÀ(íÇØy[/³up€õ+Sïâ“‘TWm¯K}ÛáæÁ”—²“Àǯ]¦º}Я€ ²˜[™FpsgS‚¡h«!Ê-Šüß_ìÖ -.gÕhU…êôa`”÷K(sⲂ_l:ŠÜ´%éI§Åù‰®í•¼Wd&yÎ?„¾¯¼ xϖзËT,¯b÷z¢\38Ép»Áb¶]Ñ\ðŽ:eƒ­FËb²ŒC§z.ƒR ^´L'3†ZˆˆÈüØÁ]vp'J/@ÿ;¸ëeƱÀúU©Ü亸{ÝêcɽÇût=.e§¿¾þBÕÉ|ŠôŽó·™䩇¨"Ñ8ù2[Qyºñ,vU¿Ö^à¨.âµ]£•yì*¢`óöÖÌD9ë¬oŸü—­¸õIuÇ•Dbˆ5µ\ ›^ž¨)XUó‡Àû… $,­PW"PQ Pè6G@Ün¼.r¯@]‰ÀÒJ ÕJØPoÃ;–ÙpùVTK¨*|îå›Í†£ËÈu¯ûÆ.‚ˆh.xúHDÙà9$îËóÊ®AžßÓ‰ë®RïÎEæÂîé%›0ÔBDDæÇîú°ƒ;QzMMGá2Áºe[À]«)æ©o?xz¡H n3¤+Èp5å|ü𥨤ðëŸP°°àé9 ¥É™ßã¶íëć®^’Ù¢ˆrÀD ŒüjŸêv`Y%¯ëš‰NĽã3¿O>þJ þñS—€}fh¾ÈŠ‚_?}?úÝ„#ñ¤ŽñºVTKÈwÎsq4oòœ@žóÍ7–?~ƒQ Â1%ñwôü×çÿE™†¯o¾O ­‰¯öD8ÝíÜ—pÛ_󼞈f’ïñ 3ºŒ\Çf¡Ddy¼ã@D–çkl¬»æ¦ý6]K®ÚÒØ‰ï}qÅyF—BI`÷ôbÀˆˆô°³ƒ». ¸¥×„?lt –›o,pÉò ØmbñÔ&.øC³ï“çH,-?Ó[q4&ãÐéA\}É‚”—²×ßr­jÀ=&ý“ j‹y}¬ʼê÷WÞèB,&ó|–(Í~ôÛƒW_YgA‰€ÇÅ÷M³¨*T¸ŸõM`߉>\µ¶&ÃUQ.èì›Ä×ï܉7Nö'µ¿ÀÂR K']d1!þ<Ë¿þÑ>ìGD™60ßu³ô¬Ñͯ@Q¶àÌCÅdM§¸¹UvpO«¸ÌŽ—DD”:AºL…p'J§‰@©fReÆîy.;V-.Iù¸`XA2™ø".î»õ¦ü¸”½V-.ŵêT·÷ŽÉ3v‘$s(ÎP»|4Œ`_’¡:"JÎáæAüþÅÓªÛ]v`Q)Çfâq x5&übÓÑ VC¹@VüöÙSxïWžL:Üîq \²P¢R†Û‰áv"Ê,I’p²Ãot¹îŒ¯±aæÎDD«!D”-p7Ø û:.’Ä|{z™1ÔBDDæçàÚ½º0àN”^ãìà>'Ñ»¤gÊúUUºŽó‡fÛå«(÷eÀþØ?|òbÕmáT;ß’ñ$”xÔ_ïÛövd¬¢l‹Ëø×»wAÑxK¼ B‡æSY¨þ>¹ã'ÛG2X e3߀Ÿ½åÜòÿö$µ²°°4nךˆADD4_¼^/‚á¸Ñeä:vo'¢¬ÀË!D”-N`ÂÚ@›_;Ýÿ¬@bÂ=­d܉ˆH;;¸ë€;QzMr 7WŠVÍ ëWVê:ΟÄÓ¡X#à~´u騮ǦìôŽ‹`íÒrÕí¾QQÞï6­2€ûKû:5øD”¼ßl=‰SçFU·—zʼ¼žkF•…BsâÁ/7Ë\1”•xèÅf\÷å'±;ÉɤùNà’…êË$6;"""ÃŒMqÀhlJDYwÔ‰(+øðÍP‘˜ŒÃ§ûŒ.ƒ’ q-Ê´bÀˆˆô°³ýž.ƒ“DéÄ€ûÜ™q8°aµÞ€ûì?ŒË¸3o‹Åe8Ù¯ë±); |é//QÝ“îQs®„@‰P­Ú¤Þá N´g´¢lÔ;ÄHu»$€¥•;š•]jŠÔ¯µoÝÙŽ®~+¢lÒÕïÇç¾ÿ"¾ýó]&y-¤®DàÒE6xݼDDDÆBàxGÀè2rÝ8€=FAD”¼*BDÙ„wƒ½´¯Ëè( ‚m;Ò*nÆD ™;¸ë˜fw¢teÀ}ÎÌ8áuqM!J Ý)7™DÀÐîâ¾ç8'¾ÓûÐÕ‹qÉò Õí} Øøßœì6 0Oýõ¾m/Ó$š«ïß³Ws•ªEe\ö D)[P¢Þ%[Vܳåxf "Ë‹Dã¸ë±#xÏ—6¡ñ°/©còÀÅ %,.g×v""2^A—×ñ÷‚¯±W[ˆ(+ðŽ:e“Fœ j Ç_kG`*lt4 ÁîieÆ@ ™;¸ë`Ž(­†Ç§.ÁòÅœãõ«Rïâ‹#© q‘Fàu÷ÑÞ”—²›$¾û·WªnW c˜]Ü̫ͪpßÇ€;Ñ\¼üF^ÜÛ¡º=ß)P[Ìë¸fç´•…ê¿§Ç^>ÃsnJÚžc}xßWŸÄmD8Oê˜Åëêm(d×v""2‰‰?“L€ÍA‰(kðŽ:e _cCÀ6£ëÈe¡pGšÙ­ÍìÛx¤ ;¸‘ ¸ë3‰srQ ŒN]‚å™õ=iýÊÔîàO¢‹»VÀýÄÙaL8ñþØ•kªñþõªÛG &¦ÍùZÊuZ÷æŽQtöMf°¢ì1Šá»¿Ü£¹Ï²Jö)±†ºõñ}8gwšÕðø4núñ|ú;Ïá¬o"©cÜ`m„ *صˆˆÌC“ìIi°8€.‚ˆ(]xGˆ²Í³Fë^9Ðmt ”»W<ÓŬ""27Üõ G“ëbFDÚdYAÇ@Ðè2,O΢îàO"dì´yΙ·) °ÿD¿®Ç¦ìö¿¹Bóü§mP‡×æã²^—ú5¤MÛ[3X Qöøïß@Ïzð§ºH PcB™‹Û”kLúÍÖ“èáy7ý©¸¬àÁçOãÝÿ¶ìhKú¸š"u‹lšO‰ˆˆŒàõz0à*¬Ûåkl3º"¢táu"Ê6Ïàí0=òR¦B´˜;¸§;¸‘v;‡ãz…#1£K Ê c“ÓˆÆe£Ë°<³Nx½te…®qŸ?”Ü~ÅašÝÇzS~\Ê~ÔᆮRÝ>ºFøždF¥¡Í߿ЌhŒ¿7¢Tì;чßl=©ºÝa—q¼h5u¥êï•áH?{´)ƒÕ?;Œ}ã|ç»áF’:ÆeÖÔJXZ)}ˆˆÈŒ›Ñ%›‚Q–áЇˆ²Š¯±aÀ>£ëÈeSá8Ž6÷]ÍÂ&ñ ]Ìh!""scwýp'JÁÑ)£KÈ ŠI;¸{ܬXT’òqÁ°‚dæ=嫇¸öã5šÙ͵Þ|‡êvߘÈœ¯©\¦Õ•xx|/ì9—Ájˆ¬m*Ã7öºæ>KÊ%Ø™ ²¯K Ä£þ~ùȶ38×;‘ÁŠÈ¬SQ|ÿÞ½¸þæ§q´u(éãjŠÖÕÛP¬qNDDd,S]ê«QÆl5º"¢tâu"ÊF[Œ. ×mÛßit 4 vpOŸ˜ÌNeDD”:»ŸÅz…#q£K Ê #¼á”fžðº~UeÊÇ(áÙ¦"îÍ£ŸNù±)û•¹ñõÏnÐܧu@†‰_V9)ß©ýšàÙS¬†ÈÚnûÝAtöMªn/ʨ,äXѪêËÔwqYÁ8ƒÕÙ( °õõv\óOàþgNBNr¢¬×%péB K+$p1@""2³‚F&“[•„æM€£‹ "J'ƒˆ(m6º€\÷ûmmð“\ל ac¨.mÌh!""óbwýBìàN”ýÃA£KÈ q6踀?‰á¼Ãx\êãʽÇÙÅfvãG/Ò|nNE€®N$7›šbõ×ûS8qv$ƒÕYÓ'ûqÿÖªÛ%,¯â8Ñʼ.Šõ÷ËgvžÅÉv¾_梖®1Üð½ð¥mOz%-›,­pÉ" ^7ïç‘ùM†y.kOûÌ{±’ˆH~ºQÖñ56´`+ …#q¼q¢Çè2H;¸§™-DDd^6Üu 3àN”½ÃìàžJ’°NoÀ}:¹Ÿ©(O}ÛÞc ¸ÓÌl’Ào~7œ›ê>¾1þy_[¹¨Ì#ಫoÿísìâN¤e:Ã×ïÜ ­Ó†%åÜŽÌÕDócQ™­+ï?úÝÁŒÕBÆó ðõŸ6âº/oÆÎ¦äï™Ul¨·¡¦Xh>ŸˆˆˆÌBcçx­ÑØ ”ˆ²ï¨Q¶Údt¹nËŽv£K ¸§îDD¤;¸ë Ç.(+tõó¦S:˜yE§euÅ(.p¥|Üd’Áââ|õqåk‡}š!>ÊmËêŠñÏ7lÐܧ¹OF”ù¦!P]¤~þºeGÆýá VDd-·ýî :û&U·å Í•È:ò@U‘Æ9ÒÁnì?ÑŸÁŠÈ#!üà¾}x÷ǯ¶&}^œçÖÔJXY-Á©1±ŒˆˆÈl àŸŠ]F®ë°ßè"ˆˆÒwÔ‰([qf¢Á¶îîÄàfÅ€{ú˜9ÐBDDæÅ€»~¡0;¸Í•à\¿ßè2²‚lò÷¥+*R>&BIÜ“,ÌSWúühîMù±)wüÝ'ÖbÝJõUÂ1àL¿Ì‰&R]$ T^öáH¿Ò’Ù‚ˆ,âÀ©~üú™ªÛ%,¯âø0›,*• uùýÖÞàç[– LGñÓ‡ãê¿} ¿zú¢19©ã$Ô—IX·È¦9‰”ˆˆÈ¬†ƒ<¹1;ƆäN>ˆˆ,„WLˆ(+ùZ3ºŽ\I;²á IDAT&ËÀÞc>£Ë  Õ¥;¸‘ü,Ö/81º"Ëó„8Y$d“ß6Ú°ªJ×qþ$º¸Û%íûKû:u=6å›$ð“›ß §Ã¦ºÏø”‚Γ¿ÈrˆÃ”{Õ_ó¿}½Ít8†¯ÿt§f˜yq¹·#s5ÑüsÚù5â‰W9)(›D¢qÜÿÌI¼ó ᎇ#˜ÌlÑóJòÖ×Û°°ThNŒ ""2+»Í†cíl¤alJDY‰wÔ‰(›m2º€\÷ðK­F—@*ØÁ=}x󖈈ô°1à®Ûx lt D–784º„¬aöîëW©wÈÖ’LÀÊ<êcËm{p'mËã›7lÐÜÇ7¦`$`î×Y.Ñ lvõû±ã›]½ÕíDGߤêöÂ<¡ùº"ëª+‘`×öÿðWû146¹‚h^Äe›¶·âš¿ß¿w/F&BIë´«j$\TËI.DDdmy/B‘¸ÑeäºA»Œ.‚ˆh>ðŽ:e3ÎP4Øžãèèá’äfÄ€{úÄã¼ÑNDD©s:8×kÜÏ€;Ñ\1àž>ŠÉ'¼®_Y©kü7™dÞªL£›óñ³Ãèæs´ýý'×âº+iîÓ2 ƒ ¸˜C[ÀëRÝ?ðìÉ VCdnN àWOŸPÝ. `EÇ…ÙÊnjKÔ¿0¾ïÞ VDé¤(ÀËotáý_}_»£¾Á@ÒÇ Ô–l¨·i®ŒBDDd½ã\%Òžò56p–e%^9!¢¬åkl8à´ÑuäºÝMìÜdFîiÃîDD¤‡Ëi7ºË›L¾#ͬ'…i3{wo¾.)Kù¸@XALž}?·Èwªoi»¸“6Iüì×¢¾¦PuŸ¸ œê#Ê[µ¦P£ÑmzÇ!Ÿf·j¢\ŠÄð;wBë4aq9»6g»Å.¡ÿÖ×Ûñò~ž+YÉt8†‡·5ã½_ÙŒøÎtŽ¥t|ea"ؾ¤\ö#"¢làt:p²Óotl2º"¢ù¡e;žÈìþçÏ@1ù ÿ\ÄîéÀ;éáÖºËMšFp'š³6_jA R'[`<°qmµ®ãüÓÉýlZ]Üp§dzœ¸ïÿ^·ÆÀé(p²GF<‰‰4¿* ì6õí¿{îTæŠ!2©Û<„s½ªÛ óhL¡ì`“€e•Ú·âÿõîÝð¹L‰Ùõ pëpÅ_?‚oݵ+å`{™G`}½„UœØBDDÙÅáÊG,fþkcYn À£‹ "š/ ¸Q¶cÀÝ`-]8Ý>htô6 ¸§OŒw׉ˆH»M‚ËÁ!¹Ã ¸ÍÕ©ÜÓÅìÜ`ãš]ÇM$p/õ¨/÷ïÃ$C[”„Õ‹KqûMïÒÜ'VpªW†æ•d5IÕ…ê¯ûG_nÁTˆKÔSî:xz÷=u\u»$€åU æŠ@Eú{æÀènýí VDÉRà“ýø‡[_ÅÕû~±é(ÆýᔾGažÀÅ %¬^ !ßÉ{2DD”}:‡¢F—@ÀÓ¾Æþ"ˆ(kñ e»ãZ."×½v Ûèèm$ÜÓ†܉ˆH¯Â|§Ñ%XÒàxüô%ÒÏ £wdÚè2²†:¸_¹¦’H} 8‘äÓ¤À- Öx;—±×(I¿v)nüèEšûLL+8Ó'ÃsK²Zu‘ú­%0‚'^iÉ`5DæŠÄð;wj¾G-.—ÇÎ9å‚ •/|þ4¶¾Þž¹‚HS8ǯ´àC7oÁ§¾õ,žÛ}.å{—ÀE $\\'¡ÐÍ{1DD”òÜ.œñù.ƒ€ÍF@D4Ÿp'¢¬æklPÀ.ÿÙfD¢q£Ë ·`÷ôaÀˆˆô*ÈSI’¦pTF(Ì® Dzu÷O]BV±BÀ½ÈëªÅ%))HvÁ*­.î/íïLù±)w}÷Æ+qåšjÍ}F‚ Ú¹šš‘Üí×ý/6E4ÆßåžÿþÚ{&T·æ Ôóºl®qØ!w-7ýx^;ÈIFò pûïáÊ¿y_¿s'NœIù{¸ÀÊj ëI(Ñøœ$""Ê Ž7žÀËFAD4Ÿp'¢\À€»ÁÇC8v¦Ïè2è-ØÁ=}p'""½ òÙ¶O/ µeÁ‰è:zÕCW”:Ù"wò6®­IùÀd(¹Ÿ¯Ì«>ÆÜ~ ›“Þ)iv»„_ßò^¬Z\ª¹ßÀ¤‚³C PiFH·w8ˆÍÛ¹¨&å–C̓¸oË Õí’–WIàUÙÜTQ 4ϱ¸Œ/þ׫xãd«¢³¾ Üõø|èæ§pÕ¢áÑ&ŒL„Rþ>°´R†z* ø*'"¢ÜÐÚÃ"M`«¯±7Kˆ(«1àND¹  À9£‹Èu/îeÇ63a÷ô‰Ç­h!""óñ¸p×k2Èk¶Dzµ÷Œ]BV±Bwظ&õ€;LL'÷óå ØT®4CQì9ÆI"¯ ýðXT] ¹_߸‚–~™ã Rœ/àq©__úùGKv"‹ EbøÆšßêË%äq˜Ó–UJªçK@âyôùlÓÕ9œ’£(À‰³#¸ý÷‡ðž/mµÿðnûÝAoÖõýòÀÒ —-¶¡¦H@ð¶ å'SF—AÀf£ "šo ¸QÖó56(`wÃ=øb ‚S "™…MëJ:¥„܉ˆH/Ó º1àN¤_sç˜Ñ%d«tp¿rM5$‰›É$ïUJ(ÉWÿþÛöu¤üØ”Û*KóñÈ|%yšû úœî“Á¡¹1–¨¿î;û&ñÌÎö VCdœŸ1™ÝȈˆHŸ|·Ýè,k2À€;‘‘hg|“F—‘U¬ÒÁ½´Ð勊S>ÎVlæ2¯ú8ó¥ý]–™ @汨ºýûQèѾq>Tp¢GFŒÃóŒ++ÈÓøõÜõؾö)ënĽOWÝ. `y•^%¨*¨/Ó¾=?2ÂǾù ¾ó‹Ý˜ F2TYöˆÅdoÆïž;…¯ÝшËþÏÃøä¿lÅ}O‡oÀ¯ûûÚ$ ¦X`C½ ÕJ(ñðUMDD¹ëT7»·›Àó¾Æþ"ˆ(ëñn:劺,4º\öÌÎv\{ù£Ë îi£(€ð&¥ŒÜõ›`ÀH—ÞA¿eÙVa¥ÿŸ×ÖàLŠüð‡ktgS‰G@ˆÄ1o78:…c­Ã¸tEEJO´zq)øþûñÙ[^@(SÝorZÁqŸŒ5µ¶ ˜ã€…%Zfž]ÐæÇó»;pý;y=²S8Ç7îÜ©9‘£¾LÒœB¹ga©@LèSÞ( ðàó§ñžüÛßmÄGß½:ãÉzŠô úÑÔ2„¦3ƒh:3„ãg‡ŽÄÓönPS,¡ªPÀÎÖDDDðz=èoe ØltDD™Àaå_cƒvq7Ü–ÆN .ƒØx5<­ …ZˆˆÈ<ò\œs®×¸Ÿw"=:û&Œ.!ëX©3ñÆ55ºŽ›˜Nîg´K@QžúXsÛÞ]Otù…U¸ÿ{ïõÜ)Vp´;Ž`Ø:¯ËlPQ àÖ˜·ÙðhÓŒ_ˆ²ÁO:„6߸êö·À‚^‡¥?µ¤<˜žÍðø4¾rûkøì-ÏãŽLGç¿8“ Gâhï™ÀŽC>ÜõØÜøÃ—°þsᪿ} _úÑvÜ÷Ô <=¶p{q¾À… $lXlCm1ÃíDDDo Fy_Þ3º"¢Là§å’M¾ft¹,&ËØẇë¯Yit)9ÜÓKVp¡a""JU¾Vˆ41àN¤OKרÑ%dKup_S­Úa]ËÄtòû–yƧf~€÷uâ[Ÿ¿<µ':ï]—ÖâÑÿüþÏ¿mÓ\É%ŽvËX^%¡¢€ãôL¨+‘Ð68s÷Ó£xåN¼÷Êú WF4¿šÎ âž'«n—°¢ŠW Iݲ* qYÆp`ö“³]G{±ëh/v W­­ÁuW,ÂuW,ª‚ Tš¡H ¾ÁzèÀ7èËß~ ¥pRªS¾(ó Tä;ùê%""z;!Ntø.ƒ€—| üEQN`ÀˆrÉ>½]H.{ä•VÜMÀÆ€{Zɲp t""JQž›Cr½F&CF—@dI‡N]BÖ±R÷òâ<,­-Öì4;H¬$‚z³)õ œšy[[÷8NwŒbõâÒ”ŸèMëWUâÉÛ®Çgoy£SªûÉ p¦_†?$°¤\±›•…Ý£@86óöŸ=z×]QÏßep$ޝ߹Só< ¾LBž3ƒE‘å+ª%È}2FƒÉSFc2v6õ`gS¾wÏ^,_TŒËWWcA…5åÔ”yP]žøÚ›—ÙIõ²¢ ŽÃ?Ád0‚ÀTþ©è[¾~óßÿæŸJ|= £w(ˆáñù°ÏÄë(ó ”{_³DDD³((ðb,Úu%š›Œ.€ˆ(Sx7ˆr†¯±A®»æ¦Í¾jt-¹lgS?ºûƱ°¦ØèRr;¸§—•º6‘y仨Á]¯‘ ܉R5ᡵ—}ÒÍjc«ÖÖ¤pW”DȽ(oöq¤Ëž Â3ÿÙ¼½·ÜxeJOôV+•à©Û?‚¿ºåtôMjîÛ;® –±ªF‚““Òç•$€Ú íC3wq?Ú:„×ôàÝëj3\Ñüøé#‡ÑÖ­þyZàXPÂë¯4;I«k$ôŒ+è‘‘ê©ek×8Z»f~.zó¨)÷ ºÌƒ<—6IÀn“ I¶ó_K‰¯mvID¢q„¢q„Â1„£q„#çÿDãGb½å¿C‘‘8¢±™?̨0/h/ó ¸˜– ""JÚØÏqM `«ÑEe ‡lD”k6wÃí>ÒÏ0àn(ÜÓËJ]‰ˆÈ<ܼ‹ªÛîD);Ó1bt YÉj÷k«ñà §S>nb*¹€;”¨Ü·ì8‹ýë+¸ªÍI]U¶ÜþÜð½q²]û½mrZÁ‘®8VVKI?‡IŸê¢D÷h|æíw>Ò„w]ZË.îdyGZ†ðËMÇT·KXQ%OuJ–@]‰@¹×†³C2Æ’ìæ>›ÀTT3ŸK„ŠÎ‡ÚK½‚߈ˆˆt°Ù$4µkO4§ŒxÕר0ftDD™"]Q†í0`t¹îçZÀ<°±&H/«…ZˆˆÈòÜ ¸ë52FœŸ¿D)9qvØè²’ÕÆ×Ôè —NL'¿oEú ŽNa÷ÑÞÔ z›òâ<×¥|œ?¤$ vÙâ|õ1çæí­)?>ÑL lP[¬~Ûi×Ñ^N¸"Ë:Ú:„_l:¦º]Àò* ¼êJé`“€%宼 Ô®*päxçq›ä;J=5ÅË*%¬[$aãRÖÖIX\.¡Ì+Øýžˆˆh8v?7it4ú†Œ.‚ˆ(“p'¢\´ÀˆÑEäº_?{Ñ—°2 ;¸§—Õº6‘9¸pŸ“¾!¿Ñ%YFK'‡ÀóÅŠ÷«ÖÖè:n"…yEe^õŽ£Óá^ØÓ¡«"5|Çb<{çǰ¬®8©ý{Æ4uÅ11m½×°ÙÕ Ø5î<Ýõ»¸“õL…b¸ù'š×•IÈwf°(Ê 6)q^µ¼*v¿t¡„E¥^Wö]ß{€}I¹„U5.]$aã6\µÔ†õõ.\ ai…„ê"KpR Q8ó<ˆÆd£Ë `³Ñeï¦QÎñ56Äꮹi €/]K.ëžÂÑæ>\¶¦ÎèRrîé%s7=C£K ²Œ“g‡.!kYq²ëÆ55Hµô‰i “Œ½ÆòÏü ›_mÅ_¼gyjÍbY]1¶Þñ1|í§xqoǬûOG€ã>Åù‹Ë¼n^+I»”¹wÎüúõ@7ŽŸÆÚ¥å®ŒH¿ïݳm¾qÕínÚb¾‡ÐüóºŸW‹Ê€h†Db@8Db Âoù:šÁþB6)±Š$_Û¤Äd'›Ømçÿ–ÄùmøÃ¶óû:l‰ýˆˆˆÈœÎ DŒ.¶]Q¦ñn:åªM`ÀÝpϼ~ŽwƒØo¸¤“C-DDd<7×Íž“®~.‰J”¬C̓F—µ¬ØÁ½¦Üƒ…UèêOm%ŒÉiŠ$;œ¬*T¸ï>Ö‹¾á jÊ=)Õ@4o¾÷~ç:<ðìIü×o ‰ÍzÌø”‚#S ʼõeùN^3™«Úb ½ãqÄUÜõØÜûë2[‘NO7žÅc/·¨nX^%%ýùH”.PœÿÖ'Þ? eˆÄ€h\Á›§¬Š(pþïÿùï·}ýfXý­„H„ÑÅ ÿNDDDÙË“Ÿ‡Ö66›1=¾Æ†^£‹ "Ê4…"‰ˆ²ÚvcF‘ëÚ֊щ)£ËÈIìàž^ŠC-DDd<›M‚×Í»^çzp'JƸ?„“êGin¬p]ÜS%+€?œüÏ[”/ 6—KQ€§Ϧ\Q2„þæ#áå»?‰Ë/¬Nú¸‘€‚Ã2Zúe„¢óX`°Û€š"õkO/ìéÀ™N^š%óëì›Ä·¾KsŸú2 ùÎ D”InGb…¢¼ÄŸâ|’|@©G Ì+P~þOE@åù?åÞÄöâ|¼D×xKÀí\öD¸Þ&1ÜNDD” "p¦¼ Í‹MF@Dd܉('ù¢ž0ºŽ\‰ÉØÕÔet9‰÷ôŠ[4ÔBDDÆ«.Í3ºËjëõ#®Ö”ˆþÇáS}F—Õ¬ºšÓU§p€Tæ¨ êcÏM¯¶ò)Í«Å5…xâ¿?ŒïÿÝF¸œ¶¤ô+8ÔGÛ Œ$À“ŠÚ Z—ŸîzüHæŠ!Ò!“ñåÛ^C`Z}ÆKaž@m1¯³QvBàè9vo7ÀãFADd܉(—=dtüæÙf£KÈI ¸§—UC-DDd¼ŠbÜõŠË †Æ¸Ñlvé1º„¬&[tžžî01ÚØ§R#àÞÒ5†“í#ºê J–MøÂÇÖ`[Ã'±aUeÒÇ) Ð?¡à`Gç†eDãóXd–rØ€j.î[w¶£½g"ƒ¥æ¶âhëêv»¬¬–ØÁšˆˆˆˆ²–·À‹ÑɈÑe°ÃרÀ‹¼D”“p'¢\¶ @·ÑE亃ÍÃhn4ºŒœ#ñÎKZ)ìàNDD:•¹.ÁÒú†Ø=†HKp:‚]'Œ.#«Å-šp¯«ô¢®Ò›òqþ’R×uKÀãRnÞÞšr Dz,­+ÂæÛ>‚ï}áJxœI'+@ÏX"èÞ9"#fÍ—¼ajKÔÿ²¢àçOÍlADIÚqȇÿ·ù˜æ>Ë«$¸ì*ˆˆˆˆˆÈC~£+ ó6º""£0àND9Ëר ƒ]ÜMá¥}F—sØÁ=½ØÁˆˆô*-dÀ}.zx…HÓ‘æÄ9s^Éþÿ«§‹{\áôuqªñ,bq&†)3l’Àß}|-öþúÓøÊ_^‚¼’©qèUpð\Ý£ ±y,4‹¸ì@U¡ú{À“Û[áàù™Ëàèn¾c‡æ>5Åe^^_%"""¢ìåt8pô,WÝ2(€ÍFADd܉(×1àn÷>}S¡¨ÑeäîieåP «„÷9a ŠHÛž£\¹v¾Yy,°qmêw˜˜Nmÿ €ûðø4v6ñyJ™Uäuá[Ÿ¿{~ýiÜøÑ‹à°'›$&#2œ‹ã¸OFÿ„‚X|‹Íu%ÔÞⲂ»7±‹;™‡¬(¸ùŽFŒL„T÷ñ¸–”óö*e7‡;Ѹu¯{e‘ç} cFADd^!¢œækl8@{­QšwÁÞ8Þmt9E’x NìàNDDz•0à>½“F—@dZáH ;Žô]FÖ³òXàêK@è˜û<>•ÚÏì´%ùê´y{[êE¥Ayq~ðÅ«ðú}ÿ ŸyßÊ”›LL+h”±ÿ\§ûd XxÎ˼q;€J.î½Ü‚¾á`+"R÷ËMÇðúõ‰W’VVK`ï""""Êv-½ê“>)£6º""#1ÝFDÄ.î¦ðÈË­F—SØÁ=½¬Üµ‘ˆˆŒUTà2ºKké™?…‰fv¼u¡(Û Ï·¸…Çu•^,®)Jù¸ÉéÔC¼ZáÖmû:0î§\QºÔVxqûMïÂö_þ>vÍÒ”W`$  ¹OÆþö8ZdŒO)ÎõO]Ï]‘‘p'"xÏÉh/î놯Üè2r†¤§M©²r×F""2V‘—÷¹˜F1`(’h&ûŽ÷]BN°úd×w¯¯MùYI„ÜSQæ°©\‰Gâxìå–”ë J· j‹ðóþ3¼ôóOâ½WÖëúq˜Tp¢GÆsqœ– [û}"òœ@Eúµ¨ß¿xÃãÓ¬ˆèM#øÊmÛ5'®UTiLØ"""""ÊÓq‡Ñ%PÂ_cgQNcÀˆrž¯±¡ÀN£ëÈu² ¼v°Óè2r†ÄîieõP §÷9ëö]‘é„"1¼r°Çè2r‚Õ'»^³.õ€;ŒO¥ösK(÷ªCx»áSvY½¸÷÷½xúÇÅ;/Y ûûDb@Ϙ‚¦.‡;ãð*˜Š¤±P‹YXªþŽÄqïvq'c( ð­»^‡o0 ºÛ‘èÞNDDDD”í$IÂÑöI£Ë „‡.€ˆÈh¼CD”ðÑpÏS§‹ËF—‘$ž¤•bñP §ÀÀû\uõñb;ÑÛí?ÖÿtÔè2r‚Õ'»¾ã’°ÛS ŽéèU]¤nõ øñê]©S¢y´~U%ùÏáÑÿü.[]5§ï5:FA÷}gã8Ù#£kDÆØ”‚XŽ\ Ëw ”iLtùís§0æçÊ<”y¼ÔŒgwSÝ.°²Z‚ŽK"""""Ëñx½˜ÆŒ.ƒ€!¯]‘Ñx9†ˆ(a€î¡dýAmî5ºŒœ vpO'v$""½ì6 e… ¹ÏÅÑ–!£K 2À3;Ï]FΰzÀÝãv`ýÊÊ” †Dâ©SàðºÕÇ¢÷o=™rD™põ% °åöàÕ_| _ùËKP[áÓ÷‹ÉÀØ”‚®Q'{dì;Ç¡Î8ZdôO(†XûEV÷©P ¿~úD«!ZºÆð½{öjîS_&¡@ã󋈈ˆˆ(›ôçÈ,ló{ÜרÀ&D”óp'"àklðœÑuðôNõn9”>’Ä›2édõP «ª8Ïè,mÏÉ~~½EWï8Žœ5ºŒœ‘ ï?׬«ÕuÜøTê?û‚bõ±è8Ó9¦«¢LX±¨ßúüåØsÿ§±ùG×ã`м降8&´ ÊhêJ„ÞOôÈè‘1TMqB‰Yy]¥í‰.þ {Pf„"1üãoGXcÆVI¾@] ¯£Qnp»œ8ÞÁSMâa£ "2܉ˆþà!£ à¡m­бÖ9¥„÷ôʆP §¢Ømt –6Œ¢³wÜè2ˆL㥽œ4œIÙ°šÓ»××é:n<˜úÏ^îpØÔ·?ð,»¸“ùIBàŠ‹ªñß_y'?øYüú–÷âÃW/SëÉ¢¸œ˜DÒ=ªàT¯Œýíq숣¹Oƹ!=c †ü &¦LGû[…Vw0‚ž=•Áj(—ý÷1¤‹ IDATð¾ýhéRŸXå°+ªy•ˆˆˆˆr‡pä!·þµ®,Ð@{©)"¢a7º""yÀ€"£ Ée‘˜Œ]M]øèµ«Œ.%«I‚÷t’ô‰ˆH¿²"ÜçêÄÙ!,©+1º "ÃM‡¢Øº§Óè2rJ6Ü/Y^âÆýᔎÓÑÁ]@u‘@÷èÌÇnzµ ßþüåiëŠM4ߜ޷±ïÛX0‚ç÷t`ËŽ6ì9Ö‹t_*EPôÍoú§ßÜ&N;ಠ8m‰¯vqþïÄ¿;l‰×¡‘ ÜÅùBuˆûž:Ž?vg¶÷Íî¦ífS© ½·€ zõŠå*¢?®xÅ{ ¢^  ØEŠèP („ÞB€@B¨ I ½÷žLÚf{/S~,Ãf§ìÎÌ÷ÌÌëùxð“óÝy{vgÏ|¿çs>߃-AÕµUßTc{PMíAµtÕÚ%µwK=R§OêöI=~ɰôÏçz,õþþˆìL©¦ùÈ¿:»ý*)Èá÷âÆ{ EßþÕëêîñ÷{LU©¥áÅto@ú((Èײ­m¦c ×ÿ4ï\xÐtp:¸Àáž”t•éénɆZmØV£cÇ 5%eÑÁ=¶èàŒÒ":¸Ö¢ ÕÝãW-‘Æ‚’^~w«éi'Uæ“O©ÒÌyÛ£ר.åGÙl=+C*/°t°åÈçî‘Yëô__š$—é6ÓÀ /Ë×÷¿|‚¾ÿå´iWƒ^[°CK6ÔhÙ†5µF·[B¬õø{ÿ9RøC"ûÝf[½ã{ÿ±ä:ìKö?ÿÛ²ûs—-ådöãÉ”VéÊϧœ,na!¶|¾€®»c®ZÚºû=¦0ÇÒè2ŠÛ^Z»™9Ä*¯Ç½Ötp ®Np8¤½’’»ýZ xヸǑM¡@L©QÔ0£¤÷Áêê hó®zM_a: `Ì–uZ³#ºÜ¼T™ L>µR–ÕÛ: íAU–F?¿YÒ»÷@‹Þ^´KŸ>›9Ž®.ÕÑÕ¥’zßcÛö4iÙÆ-ßP£¥hÃŽ†¤}X&”1,˜ÿ§ÚÆ=ýúF}ç èãÏO-ÓÒ 5ýþ½Ë–Žnxw ¹\¶–lm2½ž2œ„ð/¼·_ÒÓ¦s@zpÆzµ÷ׯ ƒF}{lS¤¨`Ücc實#F=ûÆÓÒ’?Eæ•WYõ¸æŽ r s,d÷?1}øU!5Y–4¾ªX_ûÔQúõçéõ{¾¬uÓþŸžûã¥úé•gè’³F«¬˜Ï†’tÿó«ÔÝ[9Äļ•{uï´!9j˜­œÌ"/¿@mÌ¿âÓÀIèà}=!éG¦C¤»¦¶n-Z½[1Ît””dQáS)RÓ0dxyé)áí%^]þ¹IâSÒÑÖÝõš»bŸéi)U:¸KÒäSª´Õ]·®@°·È½$o`]Ü78òù›¿r¯6íjø¨ë5Êòs2uÎ #tÎ #$õvyß} EË6ÔhÙÆÞ.ïë¶ÕËçNšXûëÚ´tCÍGçŒÚÆ]çÜ;• /¶T^ÀléÇ[Oq»CÌózÜ;M‡'¡ÀúZ)i¤ãMIwO¿¹™÷8±)p©T*j$^qaŽ s3ÕÒÁî5ƒ±ã@«¶ínÐøQC"ý<ýÚzÓÒV*Í&ŸR©©èœÞÐ>°÷òBKÛk¥þ4O}e­þxíùQ] ÙY–T=¼PÕà õ¥‹ÆK’:»}Ú¼«QûëÚ´¿¾]êÚu ¾÷Ÿýµm:Pß®úæNÃÉcoýöz Ü1h`P?üË»:ØÐÑï1yYÒ¸ 6½@úÉÍÉÖ‚5-¦c ×S¦€ÓPàãõ¸ƒU^ÿ¤¤ß›Î’î^û`·¼ûU5¼Ät””c[¸Ç’?^]Ô±eI:ºªHK7יޒô¬ðRàŽ´C÷v³ü)Tà~î‰#•™a«ÇÝü¦±}`¯g[½Ýrw×ùNŸ³E?»ò d쀒“•¡&”ë„ åýÓÝãWMCGoá{]›öTߦuíÚ_ß®ýumjmOž‡*'/3)`ÊôUš»dw¿o[Ò1ÃmÑé(èÊQ 8ÀÅÄ’OÒ4Ó!Ài(p€#{J¸Hs—ìÒ·?O{¬ÑÁ=¶R©k#ÀŒ1#(p…×îÒ—Nâ³Ò ÝÛÍJ¥¹@^N†N;v˜>XÝm]Auû¤¬¬4(¶åmð+x„ÓØÑåÓ³7èÚ¯ýÒPV¦KUC T5´ äqÝ>µ¶÷¨­£Gm>µut«­Ã§Ö޵wöüËßõôþYGï¿Û:ù×?ïîo†A:ãøá:ýøaqùÚHs—ìÖm.y̸ [ùÙÌžÖ좸Ý!Þðzܵ¦C€ÓPàGàõ¸wT]xý|Iç™Î’îxi­.ÿì$e¸Ø"6–èà[#Uc…ªa…¦#¤„ý Ú¸£NÇë¿»)JèÞnž/Åvsš|jeÔî’ÔØÔТèç™YRY¥Ú–#Ï©xa•þó Ç+?'3ê¯ àÈr²2”“•¡ò’ܘ|=Ÿ/ ¶Î‹åÛPßÙóÑŸ÷Éû>,˜ï-¬ÿx1ýˆŠ|]pr¥~þŸg°~…AÙ¶§I×Þ1÷ˆQýSy¥áÅüœ =jÿæFÓ1Ðë)ÓÀ‰(p€þ=) ÜÛ¹¿M+7ìÕi«LGI)t5­TêÚ0£r(î±2oÅn Ü‘6èÞn^ªÍ.<¥J·?¶$êq ,p—¤‘%ý¸7´téÑ™ëtÍWéâ8UF†­â‚ld›Ž|¤µ½Gßýí›jiëî÷˜ì iÂ0šª }Õ´¦ÖºVë4Ãtp"Vn Ó$ùL‡€ô¢g«é)ÇE{L¥ZQ ñF”˜Ž2^_¸[>juTŽdÓŽ:º·;@ªÍN˜P®!E9Qkløy(ʱT˜ÓÿuÊôUjëìðפ—@0¨ë-Þþ;QZ–tÌ[Ü%@šÊÉÎÒŠmͦc × ¯ÇÝj:8K7ЯÇ]+i¶éž|m«Ôµ˜Ž‘Rèà[P{Š!ù\Ÿc¤¡µ[«60ˆ+ ¨{Ÿ[n:Ôû½H%–%wÒȨÇõø¥¶®Ÿ‹ê²þ¯ÿìâ@$îzr™Þ\´+ä1ã+l…x¸ Hy™¹òùRk]+‰=e:8îÚ“¦@òz{áÓ1RŠeq'–4‰ Rf†­±Ãèâ+/{¶˜ŽÄÕ[ïoÓÚýw%Eâ¤Z»$]xjÕ€Æ5´ü5KóBwqà…Õtq„5kþv¹Ÿ ýàðbKËY@:³´zÇ rK ’^7œŠwíIlä÷N_«ŸßtŒ”A‡ØØ ¤`Q ñÆ,2!e¼·ú€¼Ø^©©±¥S{qéøP*Î&ŸR©<ÝØ>¸sª‹{}s§›µ~P_ÚÖï¨×ö„<¦(×Òø n ½è@C§éèõ¼×ãî6œŠUÁëq·KzÁtH»´jÑj¯é)æƒ{L‚©WÔH¼êá…¦#¤”WßÛj:½²Z-t²vŠTìà>¢<_ã«J¢×ÜÔ`NG¸.îS¦¯¢‹;àˆê›;uÕoßTG—¯ßc²3¤ãFØzˆ H%ûSo=+‰=j:8îÞc¦ ×ã³7˜Ž2èà[©XÔH¼ªa¸ÇÒKó¶«¥Æ'H-ë·ÕjÆü¦cà_¤bwIºð”ª¨Ç‚RS]܉åóô?·½-ï–~±-鸑¶2] 8PnN¶Vmg÷S‡Ø$iéàd¸@xs%í0Ò¬»µcO½é)î±LG¤€å¦#¤”®ž€æ.Úa:3>@÷<»Ìt |Lª>ì:ùÔÊklÜù ‹; Á tË”Z°j_ÈãŽf« ›õP àÊIÙõ¬$ôˆ×ãæ›!Pàax=©¦s ×ìùÛLGH tp-±0¼œî±öÜœÍòùy ©aö¼-Ú襻’Ó¤ê\àœF(kmnÚÿÚtqDê¯Ï,ד¯…Þõ³ªÔRE!k¡€eYZ¾­Õt ô HzÌtp: Ü 2HJÍ»ÖIæ¾éëÔÖÑm:FÒ£ƒ{lR´¨X…ùY3Œ.î±´¯¾C‹Wï1´]ûštÿ kLÇÀøSô!šÜì qü°¨ÇµwÕíÜkÓʼngÞØ¨»ž\ò˜ÒÛ[–tüH[yY 8\·²Å¦äŽñ”×ãî4’î!¯ÇÝ%é Ó9Ðë%EƒaÑÁ=¦(pÄÊðŠ•e›Ž‘r4têµù|~Dr©kl×m/1a¤r»4°.î`o‘û`…ëâ~ï´:Pß>è×$‡ƒ úÖ/_S}sè:c†Û*Îeíø'Û¶µ|+ÝÛdªé,(p€èýñ‘E1y€³µvôèÊ_½®ÝZB7®ÂVyëžÀ¿Ê/(TS;œ:ÄIKM‡€dA;DÁëq¯6¡ÛÐ;‹w˜Ž‘´l>Äܱt„rÓRRKG^š³Ñt "/¼µA‹64Hõ÷Ó¦’Âèw‰U{¸.îÓçlѲ 51y-€3utùô_¿{S«·Ö†<®²ÔÒÈŠÛ€Û^C ™êõ¸S{Abˆò6ˆ]ÜâÞékå÷LÇHJtp- ܱtô˜2ÓRÖSomVM=»ÁÙ®Þ£)3ÖšŽùý©=pÙ–>qÚ¨¨Çuû¤Ö®Øœ›q¡ç¯·>ø¾ìª)©½Ó§+õºæ¯Üò¸ŠBKc˹å |\~~®6zCï„„„ñIzÂtH&¬ö@ôž’Ôi:¤-Þf-[·ÇtŒ¤dÛ¸ÇRªwm$Võˆbåçd˜Ž‘’º}ýmÚr)„„CmÙU¯_?´Ðt D!æ—œU= qõ­±97…9–†ö?‡]±é ^˜»%&¯p޶Î}ûÖ×ôþê}!+ɳtô0nwGÒîËËáŽ1Ëëq³!Dˆ’×ãn”ô‚éèõô››MGHJÜcŠî€XrÙ–N?ºÜtŒ”õîªýzwé.Ó1€>jêÚtÓßæ««‡]ª’‰?ú߯‹N­RFFôËȱÜ0cL¹-Wˆ˜ºH­l· ©¢µ£GßþåkZ´vÈãò³-7ÂK@_.—K˶4™ŽC¦šɆw˜‡M@¯éïlÓžLÊ¢E÷ØJ‡®€Ä:ñ¨ ÓRÚ_ž]¡ú¦Ó1€´¶wë—Sæ©®¹ËtDÉçOý¹@a~–Κ8<êq­]Auûb“!+CUÚÿRöÁ†Ýû܊ؼÀ¨Öö}ë³µxÝÇegHG†~ Hg¹ùjëô›Ž^5’^5’ Ë>00s%í0R ½þþ6Ó1’ŽM[£˜¢ƒ; ÖŽ[f:BJknïÑÏ/Wp8A/ Û¦~ Í{[LGÁøÒd.ð©3ª4®¾-vçgd©¥œÌþÿþÁWkç¾æ˜½ ñZÚºõÍ_ÌÖÒ 5!ËÎN¨r)+#AÁ€$´e?Í4ä ¯ÇÍöƒ% Ü`¼w@lä÷=¿V]1j —&èà[¸bmle‰\\¯ãê­e{õþŠÝ¦c ̓AM™¶Lï¯ ]Äç ‚iñ°Ì%gUk ÏIDzÀݶ¤±åý/g÷øúíC cöz€ÄjnëÖå·ÌÖò‘·‡zè HwyÚ²§Ít B} î0pHiqÛñj;õÁÊ]¦c$ ÜcËO; Ʋ³2tÊ„!¦c¤¼??½\M­t±AIOÏ^«—æí0ƒ ¦þ|`̈"¯,‰z\c{P±œ.•X*Éë>ûú;õÞŠ=±{A@B4¶té7¿ª•›†<.'“âv -]lwä K¼÷Ó! Qàäõ¸wIzÓtôš:sƒéIÅHë=ô‹î€x8é¨ ÓR^Ck·ÜO/Q ŠSá,AIOÌ\­‡f1IÁ4™\|VuÔcÁÞ"÷XWz>û«?ψékâ§¡¥K—ßòªVo© yÅí@d232´lk³é8äÓ YQàƒóéè5gÙ^m޺ñèàS~Šâqpü¸rÓÒÂ;+öiú›ëMÇ@ ƒzìåUzdöFÓQ#éòÌ%gF_à.Iõm±=?yY–F”ô?§Ý´«AOÌæáHõÍúÆM³´fk]ÈãþYÜžMJ ¬¬¼|utùMÇ@¯nIO›ÉŠwœ’êM‡@¯WÞÛf:BÒ°$ÑÄ=vèàˆ‡ ÕCLGHSf¬Ó²uûLÇ@ƒzø¥•zìõM¦£ †Òe>púñÃTZ˜õ¸X¸KÒè!¶2B¬lßùÄRÕ6vÄüu±S×Ô©¯ßôªÖm½¼ž›%Hq;±µ»Xq—¼75E0@¸À x=î.IO˜Î^¼´NÍ­¦c$ ›±âO“‚@bäeéØQŦc¤ß<¼Hûk[MÇ@ ƒúûôzê­-¦£ ÆÒe:`[–>qú¨¨Çuû¤ÖÎØž¤ —4º¬ÿ9mSk—nþÛ¥Is}H:µúúM³´aGøâö*]Ê¢¸ˆHaQ¡¼)pw©¦@2£² ïaÓЫ½Ë/Ï’¦c$ —M ÷Xñû¦#RÔy'Ž0!m´tôè7_ Î.Ÿé(HA`PL[¦gçn5qL— wIŸY= qñèâ>¼ØR^VÿóÚWço×+ïñž§ñhÑW6Sw6„<./K:¡Šâv {¸oí {$½i:$3 Ü`¼÷JIKMç@¯û_X›6ÛÖËE{¬ÐÁ/çœXi:BZÙèmÖ½Ï,U–¿ˆ¡Ÿ_÷>½DÏ{¶›Ž‚8 ¤ÑïŒOœ6J™Ñ/)×·Å>‹eIã*BÏkoþÛl k8źíõú÷ÿ{E[½M!Ë˲z‹Û] ¤€¼¼\­ÞÞl:yÌëqûM‡€dF;Ä]ÜbͶ-Yë5#)ÐÁ=vx¨/cªJ5zh¾éieö¢ÝzzöZquG,4µvé–ûÞÕŒù;MGA¥Ó¯y™:kâð¨Çµv 2Jò,Uö?·mléÒÏï›§4zkÁª}úÊO_QM}{Èãò³-Pe+“âv *þ,Ö@œåÓ ÙQà±ñ”¤NÓ!ÐëáWÖ™Ž(pt*h$–%éâ3F™Ž‘všµA3æl4In×¾&]ÇÛZ²©ÎtÄY0ÍæŸU= q mñ9Oã+BA¾þÁNÍðlËk"óÊ{Ûô­_ÎVk{OÈãò³-Mª¤¸ˆVfF†–l½Sj¾×ãÞd:$; Ü ¼w£¤Lç@¯Y vkËÎZÓ1/ÃÅÇ€X¡ƒ; žÎ9±Òt„´tÏôÕz}‘˜eëöéÚ;æÈ[ºC)RC ÍZc]ræhYx^º.Nî.iÂÐÐóÛ[¦,Û1S_Y«koŸ£_ äqÙ–N ¸ÌÜutùMÇÀ!SM€T@eÄÎæàés6›Žàxtp:¸âiLU©ª+òMÇHK·?¹\ž%;MÇ@ Jzyî&ýß}óÕÎ ¥´‘n¼V/Ôøª’¨Ç5µå]Û8`e–* ûŸã6µvég÷Íg›nH `PºíÑÅúåï‡ýý[”kiR•­ ŠÛ€°´r{›é8¤]Òs¦C@* Àbg®¤¦C ×ƒ3Öë`}«éŽF{ìPàˆ'KÒ%gŽ2#mýö‘ÅZ¸zéH=>¿î}z‰þúü*ÓQ`éÖÁ]’.9³:ê1 ÔÔ¿s5¾ÂVVˆÂÈ7îÔ‹ïl‰ÛëñùúáÝÝ7meØcË ,Mª´•ÁK`@ ‹ u ¡Ót ò´×ãn1RËE#^; ¶rŒn_@¯-Øj:†£Qà;éÖ±xçœXi:BÚ ¥_<ø–­Ûg: loM‹þïîwôÒ¼¦£À€tœ\rVôî’Tß¿s•á’& ½Üý‹) t ¾=nR{§OWýîM=Á›Ã‹-;ÂË”ÀÀí8è3‡›b:¤ Ü ¶¦JŠÓ†ÛˆÖ_žY­öÎÓ1ËåâÎQ¬ÐÁocªJU]‘o:FÚò‚úÉýó5gávÓQà0Á`Po¾¿MßûÃ[Z½£ÁtLÃî§7L¥…ÙQ«oï¹’oihaÿsÝæ¶nýìÞyJÃo$D]S§þãç³4wÉî°ÇŽ.³5a¨-V(€+(ÈÓ†Ý4 w¥^{‰é*(p€òzÜ»%½b:zÕ4vê½%;LÇp,:¸Çî€x³$]ræ(Ó1ÒZ0(ýþ±¥zöõuiYÌŠ¾šZ»ô‡‡è¶'–©³Ço: JÇî¶eé“gD]êöK­ñ=_ã†ÚÊÊèÿïßZ´+¢®Â€èìÚߢËþï­Ü|0챆Ú5„µI`°š:]<Èï,to€¢Àbï~ÓpÈ=ϯIËbƒHPà;>?7âïœ+MG€¤_^§ûŸ]Êõ?ͭذ_Wÿþ ÍY¾Ït8@ Mï"~æì1W×ßó•a÷N†rëƒïk_m[\s@:Y³µNÿþã—µ}oSÈãlK:~¤­áŬKƒ••©%››MÇÀ!Í’ž1RIˆ^6€zKÒIL´rK–­Û£Ó'U™Žâ86î1Ó㨽³Çt ˆ¹ —­¬L—éøÐ˜ªRUWäk×A òL{ὪmêÔO®We%y¦ã Ön©‘ûÙåÚ²·Åt8Lº¸çdeè§Ò¬ùÛ£×Ñ-µw•—ß9é¸ [í~u÷S¿dýý~ê"Ýú½³ãšRU0(ýmúJÝöèb…ÛÌ$;CšXéR^Vlx IDATb²©Î¶m-ÛJ-µÃ<`:¤ÚÓ@|<"‰Geâåy;µeW­éŽãrñ1Z \•îì+MGÀ¿X»³QWÿá--]·ÏtÄQCs‡þüø"]÷»·ãˆÒùzyéùc4®¶%þç,ÖŽzÞûkôÊ{ÛâžRMg·O×ß5W|$|q{^–¥“FQÜÄR~A¡ZºMÇÀ!ó½÷jÓ! ÕPÙqàõ¸ë%=m:yqîfÓÇeÑÁš?M;Ò:ÙØÊUW䛎ÑØÖ­ŸÜ7_S_Z©ŸßtÄßЫïmÖ•¿~]³>Øe:,];¸KҧΨVNVô›„Ö&¨ÁXi¾¥aE¡ç¾ÿ÷×÷´ywcb@ ØWÛ¦¯üt¦^zgkØc‹s-8ÊÖ.Bؼâv‡™b:¤" Ü ~î7‡Lyq½jØ¢ë_¹l Ü¡¥sÁžSY–¥KÎe:Žà‰77ëÇwÏÕ¾ƒ|æLwÔê†;ßÖ]ϬT[§Ït8\:wpÏËÉÐäS£ß]¤½;¨ö݇Wa+/«ÿùo[g®þÃ[jëìIL HbK7Ôès?xI«6‡ß-³¼ÀÒÄJ[܉bª°°@[ö²í õ’ž7RËJ'^{‰¤%¦s W·/ ×ç³íø¿²)p„A»3sR•éèÇšºúojÞ²]âÝ“œšZ:uß3KtÍïhý®&Óq$Ó Ìºô¼±Wך˜ß”.[:n„-Wˆ•ð-»õ÷<¥ñ³ ÖsomÒ×~6SµaYb阶X~b¯¶Ú3Õëqwš©ˆwˆ/º¸;ÈÝÏ®RÙ>Bw@8éÜ‘ÖÉÆT–è´£ÊLÇ@?Ú»üºõ¡EºëÑ…ªo _üghmïÖ3³×êŠ_ÎÖ ïí0I&ݯ—Ÿ>k´²2]Q«MP»$åfIG ½þò»[õÈ̵ JÉÃçèW~ ýå]õøB?ÕeYÒ„¡¶ÆUØb刽œœl-ßBc‡yÐtHU¸@|=+©Átô:ÐЩ÷–î0Ã1èà‡îÎdIúêÅG›Ž0f/Ú­+ýšf¾»Y~š·wv°ŽÎMkƒ¾õËÙúûÌõêèö›Ž„$”î×Ë‚¼L]pòȨǵuÕ‘ÀgÐË ,U–†žÿæ µtCM‚€ó5¶téÿÝúºzyMØc3]Ò •¶†³æÄ‹ßΑϟÞkQó¶×ãÞd:¤* Ü ޼w»¤©¦sà{Ÿ_­`šw×û':¸Âñ§yÁž“vüHUW䛎0Ú»üºûÙ•úßÛßÒúmµ¦ãà_tvûôò;›ô­_ÎÖý/®QK"«l‘r‚\/uéyc4®.]Ü%iL™­¢ÜþçÂ>@ÿýÇ·UÛȰyW£>ÿÃzoÅž°Çæg[:¹Úòw,€Áq¹\Z²¹Åt nŠéÊ(p€øã­ƒ,ß\¯¥kÃß”Itp„C»s¹lK߸„.îÉb£·Y×ÝõŽÜO-Vcs§é8i­»Ç¯×æmÑ•·ÎÖ_§­Rc[·éHIåâÓ¢ïÒwîÝúÀûQŸ—ZÃî’4n¨­n@u­ýgsáNÝò·úãµç‹i5€dñÖ¢]ºñn[ºÂkYÒØr[# ÿNÒ••§Înš8ÌÓ Pà‰÷„¤Û%˜‚^÷M[­sNv7¦íêò ˆ:Ò&— N­ÖW«¾¥Ût$Xs{ÞX²Go,ÙóÑŸ•ekÒ˜RU]ª±•ŪV¤!E¹ÊÍÍ4RøÞÙíScs§6´kç¾&mó6jÃÎmÞÛÂï‡)ÌÍÔÿ|í”#þœðì‘ñ3|¸¡CòtÚqCµxݨÆ5uÕã—2 v ¶$3ÜÖš=5wôÿ}}òµ ^–¯\~JâÂÀôøúã#‹õ÷—VGt|N¦tìp[9\ó“\.—–ln6‡Û"iŽéN(p€ózÜ-U^ÿ˜¤kLgA¯wWî׊ {tÊq•¦£$î€püì%•¬L—þã“4eÆ:ÓQàuÍ]ò¬Ú/Ϫý‡ýy^¶KUåù^–§¡¥¹ª(ÍSYq®J‹r”åRf†KY™ÿü·­Ì —23]Êʰ%ËRO_=>¿º{êþè¿ý»©µKuªmìPMC»ö×uhO]›šÚz Dë§ß>Me%yGü;æGF÷¾>wÞØ¨ Ü%©®5¨áÅfÎlK:~„­U^¿ÚC<3vדK5lHž.ÿÌ1‰ Qع¯Y×Þ>W+7ŒèøòK†ÙÊ`ÇÀ¸œ¼5µÑ½ÝaðzÜl= D;˜ñ7Qàî(¼¸FSÒ¬ÀÝEq :Ò&ŸK/8JÓænU]s—é(p¨ö.¿6íiÖ¦=tÿA__¾`ŒÎ>©ªß¿§ÀýÈü~®—wéycõÛ,Œºø¿Öî’”á’&Vº´r·_ݾþûÙ½óTVœ£OŸ=:qá Œ@0¨Çf­×¦.RGWˆ_b²-i\…íˆß¿$˲´r{›é8\·¤GL‡€tC0Àëq¯‘ô®é8dÖ‚ÝZ¿5úîrÉŒâ@8tpO>y¹™ºæË'˜Ž ^ «.;Y¡f ¶ÅâHèàÞ׈ò|ttEÔãšÚƒêñÇ!ÐdgHG†îdõý?¾­WçoO\0a×þ}ýç¯êSDTÜž›%4ŠâvÀI µ¿&63Íëqךé†w0ç~Óp¸©3×™ŽPtp„ã§`/)M>}´NWj:€$â²-Ýô³”›z³G‹9ıãÉ‘}îÜ1Q JªosÎùÌ϶tÜH[¡žíðùºæOsôâ;[ >¦·kû:]rÝt}°f_Dc†Y:y”KùÙ\ß'Ù°‡âvr›éˆw0çEIéÕ2Üáž}{«¶í®3#aè¾'àwN"g[–®ùÚ)¦cH"ÿûÕ4¶*üƒ1sˆ#¢ÀýÈ.=lÈÂðþÔ¶8ë|çZ:fxèet ¨îzGϼ±1A©àï]~ó«ºùo ÔÞ¾k»Ë–Žfë¨a¶\Ü%¥¨¨PÛ÷·›ŽÃ}àõ¸™鈥+0ÄëqwKú‡é8$žN£›Ñ6Ýaø)ØKZª‡è² ƘŽ œ?i˜.|TDÇZbq$v<9¢Qà 5i\yÔã;‚òâhÊ ,«½” Jÿç~O¦ÙîpÌ ¥Çg¯×Å×¾ «"ëÚžŸÝÛµ}h×sÀ‰vÖùMG@_1Òî`Ö’˜¡8È?flОM¦c$…)€pü‡U—!*ßúÜ$åçd˜ŽÀÁ†féWœÕîNÌ#ú ƒ{ÿ>ÁبǃR]«óÎéÈK£†„ÿù¿eÊ=ðÂê$μ5­úæ-¯ê¦ûæ«­³'¢1#K,4ÊVnVœÃ‚‚|­ÛÙb:·GÒ ¦C@º¢À òzÜ»%=o:ñšþö&Ó1‚w@8tpOn%E9ºú‹MÇà`?¿ò •åF5ÆÅ<¢ Üû÷ÅÉã£z€âŸ¶8óœŽ.³5º,ü’úï^(÷3Ë@º ¥'_Û ‹¯™®y+÷F4&'S:±ÊÖ¸ [\Æçªk·ÅFŽsŸ×ãŽì©b@ÌQàæÝm:ç~~jZMLj»Ò îÉï3ç×ø…¦cp +.ž Sõ8 Üû¢À½UC tÚqâרT·C÷»5ÄÒØòðËêw<±T·?¶„ÓbfÏÁV]ñËÙúÙ½ó¢êÚ~JµKE¹\¿'ËËËѲÍé±Ó|é”ô éÎ(pü÷BI LçÀ!]Ý~½üÎfÓ1âŽî€pü~*²’]f†­k¿v’鿤q¥úÖçOÐX—‹yÄǨ`é²OŒиZ‡vq—¤ÊRKã+Â/­ßóÜ ýæPä`PÁ ž~}£.¾fºÞ[¾'¢19™Ò vmwq'p¼v_M‡œç ¯Ç]g:¤3–µÀèâî0w>½JM-¦cÄî€pXLM '3\Ÿ:e¤é¢¢8G7÷\eeº4>ƒ*¹>¸^†ö…óÇ)3#úŸ›šfgŸ×%–Žþÿ×?f¬ÑÍ÷ÏçA²v[¾ò“™úÉ=冀#²®í#>ìÚ^L×v )dgejÑ&º·;Ð_M€tÇ)p†—$í0‡´´÷höü­¦cÄ•mq“ {©Á’tÕ—NT&E©@ÚsÙ–~sõ9*+ÉÔ×Àá\/C*)ÌÖE§Šz\kWPÝqCÊ,3ÜV¸wÅã³×ëºÛ窳ۗ\’_s[·~ùÀûúÜ /iÉúÉÎ&UÚO×v ©3òÔÝ0‡{Ûëq¯1ÒK\à^Û'žþtœ;žX¡v§ßM—‹Â@h¸§Žáåºò³Ç˜ŽÀ°Ÿ^qªŽS6¨¯A{_\/ûì¢ñWÓâü›»…–Ža+Ü3䯼·M_ùéLí¯kKL0I)”¦ÏÙ¢ ¿?MS_YñîË-:Ú¥’<®Ó@2ÉÈÈТMͦc /êwÀ(pçxXR‹é8¤¦±So-Üf:FÜÐÁŽ?àü¢2Dî²O£á¥ïÚ ¹}ýãõɳÇúëPàÞÜÃûôY£U—õ¸ƒ-ÉqnË ,A‘ûªÍµºôÆZ¹ù`b‚H*vÔë+?©üùÕ6vD4æŸ]Û' ¥k;Œ²r ÔÚÁŽo³UÒ,Ó!¸€cx=îfI7‡»óÉêîIÍ ¥Ma :Ò¦–œì ]÷ÕMÇ`ÀG—ë;_:I±˜PàÞîáeg¹ôÙsÆD=®³GjéLŽó;$ßÒÄ‘¶Â½EjêÛõ•ŸÎÔ ÏÖÄàx­í=úõß?п]ÿ¢¯Ûñ8º¶ÉͲ,-ßÖj:úr{=n:@€PàÎr$>(;Èö}­ò,Ùa:F\ÐÁŽßŸeˆÜÙ'ÒΩ6@’«Ÿ]u¶23b³ H{_ ×ËH\vÑ„«I’.î’T’gibeø.Ê]Ý~]wÇ\Ýþø~~€4 J/¾³E“¿ÿœþ1cMÄçdJéÚ$½‚Â"lê2‡k‘ôˆé€^,}€ƒx=î’¦›ÎÃýùé•òûSï¹:¸ÂñQàžr,IWõšo: €Èδõ›ïŸ«’œ˜}M ÜûbǓȜwòH ’õ¸Ú– ’©¼8×Ò¤J[™®ðÇÞóì ]ýû·ÔÖÙÿ`eãÎ}íç3uýïè`CGDclKªÒÛµ½”®í@Ò[»»Ótôõ°×ãn6Ћwpž?›€Ã­ÙÖ ÷Wî2#æ(p„CÁ^jÊËÉÔÍWÅg üüÿ®qU¥1ýšüîè+Àõ2"¶eéß'‹z\_jlO®s\˜céäj—ò³Ã¿_^ÿ`§.ûñ+òÖ°%9Z;zôÛ‡ê3ÿû‚®Ùñ¸ÒüÞÂöê2[\Š€äWXT¤]5í¦càpAI÷˜8„wp¯Çý¤LçÀáî™¶:©:ÆE¶¸ÍH½LÐkü¨!ºîË“LÇGß½ôX]pjuÌ¿®Ëf9ñã(pÜeMиš–ä;ÇÙÒ‰U¶Ê ÂϽ×ï¨×ço|I‹×E^ì ¹ø|=>{½&_ýœ|quÄggHǰ5q¤­œÌ8‡0›÷±››ÍôzÜ[M‡Â)p&º¸;̂մl×tŒ˜¢ó" œ`°·]RÓ.:ZçMf:€8øÊ䱺ü³ãòµ]Ì#ú`Ç“È0¡\㫊£W×”? Ÿ»sÙ½…©£†„ßÔ5uê?nzUϾ¹)É$J0(Íœ·]Ÿ¼fºnºo¾6tD4β¤QC,6Æу2’GQQ¡¶ìe'7ú‹é€ÃQàÎô¢¤¦CàpS^\c:BLQàˆD¢½”e[–n¼ât )Ì2@ ]|êH}ÿk§ÊŠÓŽM¶‹yÄÇÑÁ=:éâJõmÉ{žG—Ù:v¸­pÓpŸ/ ÿõ]Ýp×;jiëNL8q3å^}þ‡/én{[Û÷6E<®$ÏÒ©Õ.. ÿ{@òÙrÀg:úZ#i®é€ÃQàäõ¸}’ܦsàp¯}àÕÚ-©³]¸§‚@j “·˜ á•åê7WŸCGf Eœqt¹~øí3ãúžÎà÷E`¶7貋&h ÓÑš–äþLR^héÄ*[Yá}aî]rÝ Z¸&uÖ €t²fk®øÅl}ãæWµjsmÄã²3zw}˜Ti+—gP€”TTT¨M^º·;Ð_½wr/>@ ¢Àœë!I-¦Càp½¼Ît„˜¡  ºÒ¦¾ãÆUèæ+O7À SU¤[¾w®²#©žv‚êËïçZêá…:嘡Qkl ªÇ‡@ TcéäQ.ä„í9ت¯ý|¦þôèbõøxˆH;÷5ëÚÛçê³7¼¨w—ï‰xœeIUC,:Ú¥²®³@*ÛVC÷vª“ô¤é€¾(p‡òzÜMê-r‡ƒL›³M[vFÞyÉÉ(LD‚îéáÂÓGë»—k:€ª*ÏÓ﮹@yño÷ʃ²}ùy,j—]4!ê1AIµIÞÅ]’²2¤«lU†/ƒÒ½ÓVêßô²¶xÀ@Ô6vè–) tÑ?¯—ßÝÕØ’¹2êq-AuöÄ!!UC,?ÒV†+ü±Ý>Ýtÿ|}ç7¯«¶‘¦b€IÝ>=ôò÷_Ïê/O/W{§/â±ÙÒQÃl2Ú¥²|®©@º(,,Ðú]-¦c ¯ç½·×tÀ‘QàÎw·é8\ ýcÆjÓ1Â@$‚´ M+ÙYúÅ÷ÎUeYžé(ÂÈtÙúýŸ«ñ£JúºÌ#ú¢ƒûÀ\vÑ„K•.îÿ4$ßÒ©Õ.•æEöÞz{ñn]|ít½¹hWœ“ø¸–¶nÝ;m¥Î¹êYýêÁTßÜñØ [[në´1. +²ÄÕH/»ê#ßñ õWÓý£Àœï}I M‡Àáž|c«6í8h:Æ Ø·ÒáQ´—~J stÛu¨¢8ÇtýÈδuûµçéÄ£‡%üµ]¸÷A÷ùÌ9£•Ÿ“õ¸ƒ-©wC8+CšXik\…­HÞbuMºê7oèç÷ÍSK[wüi®¶±Czt±ÎüÎÓúÓ£‹£ÚEÁ¶¤ªRK§u©²ÔŠè= µhÝNº·;Ð"¯Çýé€þQàçõ¸ƒ¢‹»#ýý¥äîânó)ÜÓÒÈ¡…ºë†É*/Ê6ÀÇäf¹tÇuçëÄc_Ü.ÑÁýHxl`r³3ôé³GG=®£[jíLÍs>²ÄÒÉÕ¶ò³#{Ÿ=1{ƒ&šžŸ³™Ïl@xkZõ‹) töUÏèÞi+ÕÚÞñXKÒðbK§qiL¹­ Öဴµ§!(¦íŽD÷vp8–Ô 9L—ÄÞÓóÌ[Û´a[éFwEÇ¡® IDAT@$©×$ªV¤»n¸PC ³LGð¡üœ Ýyýš8a¨± tpï‹îwÙEã4®¦%uÏy^–¥“FÙª*ì½VÛØ¡ÿìÑW~2Sk¶ÖÅ96ïnÔöè‚ï=§Gf®SW·?ªñå–NíÒ„¡¶²2â@R((È×êͦc ¯½’ž7î¼·O’Ûtôõà‹ÉÛÅ΋€HÐ 4½U ï-r/- È0­07S¾a²Ž[n4‡m±œøq~®•6ùÔ*•—äF=®¶%¨T>ë¶%)·uB•­ì‹c—¬? ÏýàEÝtß|5´tÅ7 ¢Vn>¨ïýþ-}êšçõüœÍòù£{Ú·8·÷•cGØÊåã3IûšE÷vgºÇëqw›;R<þ!©ÕtnÚÜíZ¿õ€éBw@$‚t¥M{Õ#Šu× “U’O•`JI~–îþÁdM¨b:Š\.æðs­(—méóçz\·_jjOýó^œké”Ñ.UFö¾ ¥Çg¯×䫟Ó³7°»`Pš¿r¯¾yËl}þÆzíýQŸäg[šXÙûPJa×I½ ò´jÝÛ¨EÒÓ!áQàIÂëq7IzÈtô5å…äìâNw@$èàI=²DwÝ0YÅù™¦£igHa–î¾ñB­*5ERoA2ç D×á‡»ì¢ WÓ’ŸQ2lé˜á¶ŽnËáj~cK—~~ß<}áÆZº¡&¾$Õã è•÷¶éßü²¾qó«zoÅž¨¿FaŽ¥ãGÚ:¥ÚVi×G‡«i±éÞîLx=îFÓ!áQàÉÅ-¥ô.ÜIéϭݲßtŒ¨QàˆD€ÎŸøÐ˜Ê¹ô U–噎¤ŠâÝ}ãEªQl:ÊG˜GôŵrpN=v¨ÆŒ(Šz\]kPétê+ -:ÚUíê­µúÒ_Öïöè`CGÓÉcom›îxb©ÎüϧuÍŸæhùÆè)ͳtB•­“FÙ’Ïu@_ùùyZ¾µÉt ôÕ#é/¦C"C;$¯Ç½MÒ‹¦s ¯ûŸO¾.î¶Å 8@xtpÇ¿ªV¤¿þøš4¦Ät åUWäëî/TÕ°è ã‰yD_þtª²Ž“¯~ê¨¨Çø½Eîé$;CšXi븑¶r¢ØTeÚÛ›5ùûÏiÊôUjïôÅ/ àP`Pï.ߣïþîMógä~f¹j£裼ÀÒÉÕ¶&VÚ*Îåz ÛèÞîPOx=îè·ðA;$Ÿ»L@_/ÏÛ©Õ›ö™Ž:/"AWZ|\iQ®n»þ"]xâpÓQ€”uÚQeúË?©…¦£ôÁ<¢/ Üï?.>Z®ülíoJÏs_–ßÛͽºÌV¤§­µ½G¿ŸºHç\õŒî›¶R­=ñ 8@CK—|qµ&_=MWüb¶Þø`gÔðZ–4¬ÈÒi£]:v„­‚l®ƒBËÏÏÓò-tow¨;LDŽwH2^{¤÷Lç@_÷=¿Êt„¨Xt^D€wInv†nþ¯sõÕ ÇšŽ¤œKÏ¥ß];YÅÙ¦£Ñ@ŠSßϵr°F”çëü“+£×ÔTgšÖiÛ–T=¤·Ð½¬ ò÷e}s§n{t±Î¹ª·‹uK[wS‰ J+6ÔïöèŒ+ŸÒoZ¨ûš£þ:¶%,±tú—Žf+7+a¤¤úÝÛée¯Ç½Þt@äþ?{wW]ïü}fÉL2™IštoÚ¦è^v ¢T *²©àv]®×åz½Õ‹â½÷'n¸àr½ÀE\pC\®²ŒJ(Ýwº¦=m“&Í2Éd›åüþz)M›9M&ß3ÉëùxôÑ oû’&mæÌç|NÀtà¤Ü&é5¦#p´ÇžÝ¯õÛêŒ9SM§ä…Í‹€|¸Ýpˆ±Ãï÷éÃ7œ£‰U}ÿW›Lç£ÂÞ4O7^1ßÓ7£ò:âXlpo[6G‰5¶ësÉœfVÝ=.á 4oŠO­]Žv7åÔç¼z[G¯¾ñÀjýàWõþ«èýW/TeÔ›7ÖùèîÍè7‰]ºÿ±­Ú¸«ù¤ž€OšRiij¥OAÿ0"‘R=»žííõ5Ówp€âôGIë$i:GûîCôÃ[ŠdÀÝÃC3ï`ƒ;NÄ’ôæËçjRU™¾rÿ êMçL'EÉï³tË{ÏÕÅçÌ42(^G‹÷áqå3U «%ÙãêÜᤣÕý'eãÊ,=ïmŽö·ä”Íó¯äŽTŸ¾ý³µúѯ7é½WÍ×®[¤ªX¸°±À0qiÃÎ&ýòÉzøñJá‰%ij¥OS*,ùÇî=3†¨µ;Àâ oZa'âÏšŽ¸Ãe:(Bv";<æÏÙZ»õ éŒ¼°y.Ä"¯>{†~ðï—é”Éå¦S€¢S ꎻ¸(†Û%^G „÷áøtíkg»>×›‘Úºø=$Ë’jÆY:g¦_¢î>W;»ÓúîCëuá?þ\_¾÷y5·u¨º]v»¾ù“Õºøƒ¿ÐUÿöÝóÛÍ'=Ü^YfiîŸÎ«õ«fÃíN^YY©Vï`{»G}ÝtÀ=.Õ@ñzDÒÓ8VüÁu¦òÂæE@>ØàŽ|͘R¡;n¾LWžWc:(µ“Êõ½›/Õ¼S&˜NÉîÇÊæxzÅpyÛ²9:™—ªí|½òr%iÎdŸÕøTv÷´«'£<²Aþãƒúì]+µc_[*wޤôÃ_oÔ>þk½öÃéÛ?[«½‡’'õs|ÒÔJKgÏôká4ŸÆ—['õg¼\²7È"oÚ"é1Ó÷¦'ÇNij5K—MÒL·àhyá Vo9 sæO3rB ¦òá°Á.”…ƒúä{–hÁìñºýë¹A8‹LÔÍïY¢h$d:Å?¯#ŽÁ—Ãg^m•ί;›];’r”ÎJAŠTE©¥3§[jír´ïˆ£Žžü?V{ú2º÷Ñͺ÷ÑÍ:oþ$½ãʹzãE³Tâ-ŒœöÎ^ýþ™½úub§Vn<¤¡¾4)Yš\aiB”Mí†WYYXOlâ&qú†ˆ³¡ŠW£ ¸ýXÒ$y{’z Šÿ|½îûÂ4OobÀ”á–eYzÃkNÕ©3ÆéÖ=§C-ݦ“O±,韯]¨ë.S”_“cs¡e²ü]9œÞ¾lŽëwÇ‘š:M­äãs ãÊ,+³ÔÖåh_‹£d·»ÙU[µjK£>{×J½ù’SõÎ+çjnmUj1Öu÷fô—ç÷é׉]zâ…ýÊd†6ƒà³¤ñQKS*,E]>ÑòÕÑä‘7ôSÓ€“ÃN(bÉúºl¬vINÒ•¦[p´=‡:tñ5ubÌtÊqe29ýì·›ÎxÜÌФêrÓ(BÕ•eºüü™:t8©úÆNÓ9€'LÖW?r‘.>g¦,/ß {[w7ë…íM¦3<ÅoYzç•óLgŒ§L­Ðÿv³2YwC­}YiJEq~^”pÐÒ¤˜¥Š2K}©'íî|_:«u/6éǿߪ§VÛòù,2­BÁ«°14]==µÆÖw\§OÞñ´~Ø¥]vûn¶ ¥éU>Í™ìÓ„¨¥P€?F$Rª§·t ù©S(ˆ[íD|…éÀÉaƒ;¿JºERµéíö×é5žÝân±y‡,G0±ò>ûÁ‹ôDÝ^}ûëÔÕ›5sñâÉúø;ÏSEyÈtÊø¼úÇ ,O;VÑH‰^ÿªZýꩮΥzuö8*gCó *J-UL³”ìv´¿ÅQk—ûáµÛkíöÃúüÝ+uÝ%§êWÌÕÂÙ\šBþö5tè‰öëñUûôì†CêKÏ׉UKS*ûŸZ#áHW€ëCÞÔ.énÓ€“Ç€;9;OÕ,]~‡¤[M·àh]Û U›öëüEÓM§ ˆùv@>r¬ÁY–¥Ë.˜¥Å§OTüg«õì–æ“€eYÒG¯_¤«/9}T ‡ûx!qŒLÎݦq îÆ×îzÀ]’“ ¸»+µ´`š¥ŽžþA÷–”û¯û:»Óúñï·êǿߪŧ×õ—œª+–ÌTͤhŠQÌ2™œžßÒ¨ÇWíÓ«ök§Ý6l?w4liBÔÒø¨¥ž[ `•—Gô̺á{}ƒaõ};ï08y ¸Àèð]IŸ’Tn:GûöÏÖë' kdyp…Á@>rlÁ0™PÑ>ò=þÜÝñ‹õêîc›;F¿)U¥úÌû—hNíxÓ)Æ×ÇrɑęásÑS5crTûܽÙÔáhÖnèv+¶4ª¥ÎÞþA÷#'÷õ߆ÍÚ°£YŸ¿û9ÍŸU¥+.¬Õ²%3µà”jÏ>Ý…ÕÜÖýÒ–öýúëZ[]éaû¹KK¤‰QŸ&D-…ƒÃöÓ€+Ûû¯ Ász%Ýa:04 ¸À(`'â­5K—ß)éfÓ-8ÚÓT·a¿.8c†é”cŒ†í‘€Âcƒ;†“ϲôº OÑâÓ'ꎟ®Vݶ&ÓI@Á\ræ}ìç* ™NV ¸ÌÉ9²øo3¬n¸ütý׫]Éä¤#Ž&Dù½8å!Kó¦XêÍôoÃolÏ©7sr?×–=-Ú²§E·ÿt¦M(ײ fêŠ fjÉ‚É |ÃÏÈæmÚÕ¬ÇWí×ã«öiÃŽæaýùKÒ„hÿ¶öòŸçÌŠFËõÌÚvÓØ}v"Þh:04 ¸Àèq»¤å’F×ôÄ(ðÍŸ®Óƒ‹¦{n„á @>ØàŽB˜T]®/}ôbýï3»ô½_nTW/ÛÜ1zTFJôñÏÔ«Ï™1*7zs£ìÀrŽ#ߨü7ç†ËO×í?]£¬Ë¯EÚpªP@šQeiz•_m)G IG-ŽNö«ÂMº÷Ñͺ÷ÑÍŠEJtùù3´ì‚™ZzvÊKY½]̺z2Z÷b“^ØÒ ç·4jõ¶ÆaÝÒ.IŸ4þ¥¡öŠR>·xÇž¦Û۽ɑôMÓ€¡cÀF ;?T³tù}’>dºG{nóa=·aŸ^uæLÓ)G±LäÁaÀâ³,]ùêSuþ¢iúñï6é·ÏÖ›N†ìL×û¯=CѰ锂ñÚ»^‘Ë9’ßtÅè2e|D¯>sšklWçÚ»õ¤¥0sÓCfI±4.b©ïo[Ý“9õ a~9™êÓ/ŸÜ©_>¹S%A¿^}ÆT]rît;o’æÖŽSÀÏvw/kjíÖª- zak£žßܨͻ(“Í û¯ã³¤ªrK£–Æ•Y⯉ŢZ±£Ítöˆˆï0:Ü`tùº¤HâÝ@ùÆkõð¢éò{èZKýÃ)læœM Ðª*Jõ±wž§+^5Kßh6×ó¦ŠÏ”ªRÝôö³uöü)¦S Ž÷åX×U7¾ît×î’Ô˜Ìifµw^%iúß¶ºw9jhwt$å iS]_:«'^د'^Ø/IŠ„ƒ:kÎ;’Λ?YgÏ™¨ò2îT0Åq¤v›^ØÒ¨U/mh¯?”,دô÷ßPQéj÷Ð%48ƶƒ}¦p|_7 ¸À(b'â»k–.ÿ¹¤w˜nÁÑ^ØÖ¬§^أ˖Ì6r” ßR/“‹€àF(Œ”¹³ÆëÛŸ¼LO<¿Gwþr“ÚR¼A€âð¶ËfëoX¨²1².ÚÏ€û€xâIa\ya­ÆECjíèuuîpÒÑŒêþ»1ü*Ë,U–YJgû·º7´m«ûߤzÒZ±þ V¬?(©ÿi/skÇéÜù“u:oÞ$M›e›wd29í>Ø®íõ­ÚVߪ-»hõÖFן{n•‡-U•õ¶GÃüÆ(±XL+v´šÎÀÀž´ñU¦#Ãw}¾*Ü=é‹÷¬ÖEgÎT8ä¿~N †´I>Ÿ¥Ë/8EKÕèçÚ¬ŸØ5¤Í°@!ÍžÕMï]wÉ©ºç·›]ëÍHm]ŽÆ•ññZHA¿T3ÎRÍ8¿:{étÔ’’R½ÃóùsmÙÓ¢-{Ztÿc[$I“ªÊtÞüI:gÞ$Í«­Òìš MªŠ0ôž§œãÈnìÔöúm«oíhßÛ¢]Ú•Éä þëû}Ò¸2Kã"ýßJüÿ%`XY–¥ ûzLgàøØÞ£ˆw&ìÃÂNÄ7Ö,]þ¨¤7™nÁÑvHê+vèºËæ™Nù;¿Ï')k:àaÙlá]€WŠFJôëÏÒ² fé¾G7é¯L' úôÞ×ÏÕµ—ÎQIpìMæù¸Iv@wãÌÛ–Íѽnv}ÃSc;î#©÷¡WkÛžfÝ÷è&­ÚÞl: cÜõÏÒÛ®˜¯êÊRÓ)Æ0à>°Ü f^m•ί;Ýýp$å(íß2Ž‘JS+-M­´”ÎJ­)GGRŽZSŽ ñ©’êIkãÎæc>F,Kš61ªÙÓŽ~Ÿ:!¢êŠREËJŠrØ:›sÔÜÖ­CÍ)lêÔ¡#)lJéPsêïÿ¬±¥ËØ“%~)¶TYÖ?ÔÉ€açóù´fw—é ß×íDœ‹t0Š0ࣈ¯¬Yºü)I¯5œ‚WhnïÑ/ŸØ¦÷^}¦éI’ß_„ïäF{ð‚¹³Æë¶å¯ÕÆuߣ›´~w«é$Œ1KOÖ{¯^¤S*L§ç+ÆiÐÀ a…õöes\¸;ŽÔÔáhj%³&ýÒĘ¥‰1K9GjëêßìÞòÒ …ä8’ÝØ!»±C‰5ö1ÿ>ð©:VuEXÕ¥ª® «:Vªêаª*Â_Yªª¿ÿû°b‘аÄg²9uõdÔÙVª;­®ž´:»ú¿Ouÿß?ojëÒÁ¦”^doléRÆCOY ¥XiÿvöX©¥²ÓEP¥‘¨[ÙÞîQõ’4^ ¸Àèu›p÷¤Ûþg­ÞpÑ©šX]n:… î€A1௰$->}’¾yÓD­ÞrH÷>ºYÛö·›ÎÂ(·°¶R¸n±œ:Q|åÜ îËygÖtTºvélÝú£:õôe\kL2àî%>KªŠôoõv$uö8JvKÉGÉR&“ScK—[òÛ¾ç³,ƒ>|>ùý–þ—ïSÀ÷ÊöÒ÷>Ÿr¹œR/ ³wu§•êI«·o„ÿË’ÊC–báþ¡öh©¥ž’` ðûýz~G§é ß7íDÜÝ…#€ç1à£×Ÿ%­–tŽé­«7«~¿Y7ýÃÓ) ¸ÅFZxeY:wÁT=oŠê6غçÑÍÚÝÀ ^ÓªËôÁkêUgMgcù+0à>0þ¾,¬h¤D¯U­~õÔNWçR½Ž:{•‡ù¸õKR4l)–¦½t QwZJv;êxiཫÏlã+åG½}YõªøÓO–ß§¿of•ö·û}¦«`ä•”FÕÚqÄtÖ,éÓ€áÇ€;ŒRv"îÔ,]~›¤‡M·àXßyh³Þ|Ùéš9uœÑ܃a#-¼Êç³tá™ÓµdqÖl=¤‡þ²]/¼È šñ±Þuå]ñªÙ* ²’v üÌá‰'wãëNw=à.õoqgÀ½8”¥Ò ¥I±þ߯Lö¥íî=Ž:º¥ŽG|ªN8(EJ,•…¤²K‘TZbñc^0ÐÊm©»ÏQߨY¨>,J¯d/édg3; Ì FÔÙÝb:k‘ô}Ó€Â`ÀF1;ÏÕ,]þUI÷šnÁ±îÿã½ëõs5oö$c ¸ÃÀŠ…%éÔUºù=èÝWuê±§wé—‰Ýêfê 'pæì*ݸlŽÎ?•Áí<±Á}`Ü62n¼üt}ãÕ®ÎdrRs§£‰Q>v‹eIѰ¥hXÒËöŠgrýƒîÝ}Rwºÿû®—~Ît0d~¿OgÏŸ¢³çOч“=Z±v¿]±[;òäÒ±`îô ½ñ¢Yºè¬éª(™Î)zã+ËôÎ×f:Ãs"¥%¦ÆŒw¿q¾ëwI:ÔæhöDÜq´¿ “‡ƒ¯üØÈïcååïÿ~€¿ü×ò[ý[ØÞÖ• )é2%Å’Gõ¸Œ cDÍÒåÿ!é6ÓØÿ|æ]ºd¶é €1Ñ´£þˆžx¾^­¬WWoÖt†Qe¤DW½j¦^{ÞLÕN«ä0Ê\òᇵÓv·AÍï“Οå—äï-E¦¬´TOlN)“å©}õ%;ÿŒé@añ0K#bµKÖIú ¤2Ó-8Ö¦Ý-zû²9 ðN;Àˆ°$UW–éÜStÝkOÓéÓb XŽì¦”²9Þ´(F–%]zÖ}ðÚEú×·­sæOѸX˜áv`Êå=µÚvuÆq¤PÐR4ÌŸ àÄRN©ö7ñ$tê”ô¶d}]·é@aq5Æš¥Ë?%ék¦;0°ïÞt‘®¹tžé €1­»'­õ/6êÙõõäÚlv/‹gÓ¥çM׫Ϛ®q±RÓ9F@GªOç¾ç§êêɸ: Y:k7–€ã‹DÊôçõÊ9,Bñ¨ÛìDüÿ™Žî0†Ô,]‘´GÒÓ-8ÖÄʰžºë-ŠF¦S ©/ÕæMZ¹á€_}@m©>ÓI úôšE“uÁ¢©:cÎ$UU0ÔŒEŸúÎÓúÙŸ¶»>·¸Æ§X)—ÅÀÀ’Ùˆ6ìNšÎÀÀR’jíD¼Ùt ðü¦#'Y_—ŽÕ.ÉIZfºÇJõd4µ:¤3æL6I~¿OS&”ë¼…Sõ–KOÓùó&ª¦ºLN.§ÆVž~:’&+ÕUÍÔû®Z Þp–^{ÞLÍšV©ÒpÐtC¦N(×Oþ¸Íõ¹œ#/gÀ+ê™-í¦3p|w؉øoLGFWò`Œ©Yº¼LÒnI“L·àXe!¿žùÑ[5~\¹éœ@WwZÛ÷ѦMZµµQ›ëÛL'*%ŸÎ˜]¥óLÖÙs'kæÔ Y—±íšOþVk¶vuƲ¤ógùdõ 8Š%»#¤½ )Ó!X·¤Yv"Þh:02xgÆ š¥Ë?.évÓØ'ß±X{Çù¦3àB²³WÛö6kÓŽ&­y±IÛí¤r9ÇtVј<®Tç̯ù³ªuÚÌ*͘R©`Àg: €Ç=òÄN}ü[O¹>7³Ú§éU\ÿ'«ÐV·˜ÎÀñÝn'â7™ŽŒ®âÀT³ty©¤]’¦˜nÁ±>Ÿþz×õš>¥Òt NR_:«ý Ií=HìTü IDATئ]ûÛ´uo‹6×·)Ëл|>K‹fÓâÙÕš;«Z§N¯Rõ¸2.Rp-ÉéÜwÿT-ÉWçBéÜY~þÜ’$¿ß¯Í¥ædŸé ¬WýÛÛ™Œ®áÀU³tù¿JŠ›îÀÀÞû†ÓõÅ\l:Ã(Ééàá¤öl×®ý­ªoèP}c‡ö7u™N+ˆpЯӦÅ4kjL3&G5mbTS&”kRu¹J‚~ÓyF‰¯Üû¼î|dƒësó§úTáò8‘ ýeÛÛ=ì;v"¾Üt`dqƨš¥ËÃ’vJšfºÇòù¤?}ûjÍ=e¢éX:“Usk·šZRj8Ò©CÍ)lêT}C‡ö6¦”ÎæL'Wu,¤‰•aM¨,UÍÄrÕLŠjꄨ¦Œ/WUe©|—žÖþƽæ¿pý„Œqe–Ló¨ ‹PI‰VîìSWoÖt Ö'i¶ˆÛ¦C#‹w` «Yºü#’¾gº»ê¢ºó?—™Î€AŽã¨»'£Ž®^u¤úÔ‘êS2Õ«dªWí½jïìS[GÚ;ûԛΪ/ëÿ>Óÿ}o:§ž¾ì€ƒŸá _¡ŸÂ%þþ¿ô­$èëÿ¾Ä¯ŠH‰ÆÅ «²<¤ŠhXå!Å"!E#%òû`Þ{>ÿ'=ñÂ~×çέõ+,@(%Z±™íív§ˆÄt`äLŒúoIÿ!iºéëwÏìÓû7Ù:waébY–ÊJƒ*+ jRõÉÿ<9ÇQ&“S.ç(ðÉï÷±õÀ¨ñî7Î?©÷Cí9ÍÏ:ŒU‘H©ߨj:Ç—–ôUÓ3¸zc˜ˆ÷Jú²éßWï_­l6g:EÎgY* ú`¸À(sé¹ÓU3)êú\c»£pƈÆ¿2Y.xؽv"¾ÏtÀ Ü÷Jª7ÕmiÒãu»LgàY–%½ëʹ®ÏerRSob0E£åZ¿»ÝtŽ/#é6Ósp€1ÎNÄû$}ÉtŽï–»W©³«×tžõö+æ¨$èw}îP;îŒ=–^<”‘Ãe/»ßNÄ÷šŽ˜Ã€;@’þGÒÓØ¡æ.=ôç­¦3ð¬ªXXo¼h–ës=Ž:{x7€±¤<Ó®C)Ó8¾¬¤¯˜Ž˜Å€;@v"ž–ôEÓ8¾/ÿÏZ<œ4€g½ûóNê[Ü;|>ŸVïb¸Ýã~b'â»LGÌbÀð7?–Ä êíËê·יÎÀ³Î7I N©v}®©ÃQ&[€ à9¡²˜šÚzMgàørb{;@’ßtÀ’õu¹Xí’6I×™nÁÀÖí8¢×;E“ª£¦Sð$˲ô—ç÷¹:ãH ú-ÅJ­ÂDO•µr{—ÒYžææa?³ñ»MGÌcƒ;àå~*i‡éß—ï{AÙ\Îtžtý%§*)q}îP;¯µíú¬R¥zyŒ›‡9’¾l:à lpüÝK[Ü[$]oºÛߘҙ³+uJM•é<'𩱥Kë^lru.““b¥–ÂA¶¸0•••êé­bŸœ§=h'â?0ð6¸^éç’¶™ŽÀñ}ú®ç•êî3€'ýÃæÉ:‰9õCí<ž€Ñª9åW&ÃkËJú¬é€w0à8Šˆg%}ÁtŽï@SJÿy‹é <é´é•º`á×çŽt:êÍ –kí®vÓ8±{íD|‡é€w0àÈC’˜ ö°/Ý·V MIÓxÒ{®šRçÚyN9£ÍŽÆŒ–·{YŸ¤[MG¼…wÀ1Øâî}=}YÝùÈzÓxÒ•Öjêøˆës íŽr¼á À¨Å´ó@ÊtNìûv"¾ßtÀ[pÏÃ’6™ŽÀñÝó»íÚ¼³Ñtžã÷Yzß›¸>—ÎJML¸0ø|>­ÝÝe:'–’t›é€÷0àˆç$}ÞtNì+÷­RŽÕrãWÎU$t}î@+¯³ BeQ5´öšÎÀ‰Ýn'â‡MG¼‡wÀ‰üJÒzÓ8¾¿®kÐS«ö˜ÎÀs¢‘ÝðºÓ]ŸëêsÔÖÅ;Å,TÔÊmIÓ8±6Iß4ð&ÜÇõÒ÷Ï™îÀ‰}æîçÕÕÝg:Ïù§kÊï³\Ÿc‹;Å­Ç)UgwÆtNìkv"Þf:àM ¸ó[Iu¦#p|û;õÈãÛLgà93&Guùù3\ŸkírÔÕÇ;Ũ¼<¢•[™›ö¸FIß1ð.Ü'd'⎤7Ýû⽫Õx¤ÃtžóÁëÔ¹ƒm ¸PŒö4ç”sx]ïq_²ñ”é€w1à”ˆ'$ýÞtޝ»7«»Yo:Ï9Ád->m¼ës‡“ŽÒÙ€‚)UhûþNÓ8±zI?4ð6ÜùúOIÜâìa?zt›¶î>l:ÏùÀ5î·¸çéP;—B(@@«v0Ü^>o'⽦#ÞÆ€; /v"¾AÒ¦;p|Ž#}å¾UrxÔG¹ê5³4e|Äõ¹Cm9åx™ @Q°J":’ì3Û.fOy`ÀàÆg%ñjÐÞZsH‰öšÎÀS~ŸÞ{Õ|×çÒY©©ƒ w¼®¬4¬›ZMg`pŸ±ñŒé€÷1àÈ›ˆï•ô=Ó8±[îz^Ý=iÓxÊ»^?O‘pÐõ¹­ ¸àu)¿ÒY^Ã{ÜZI˜ŽÜn}ERÒtޝ¾¡Cýy«é <%)Ñ[/?Íõ¹®>Gm]¼A€WEcQ­ßÅCø´ˆçLGŠîWìD¼YÒ×MwàÄn½wµìÆ6ÓxÊû¯Y(¿Ïr}î@îx‘ÏçÓ†½=¦30¸’þh:P<pœŒoKj0ãëíË*þ³µ¦3ð”Ú)1]vþ ×çZSŽºú †$‰éÀÜ‹À§íDœ €¼ùMŠO²¾.«]’’t•éߦݭzÕ‚ñª™\a:ϘTU¦‡þ²Ãõ9GRUÄýöwP¡P‰žÝ–R:ËÜ´ÇýÉNÄ¿l:P\Øà8Yÿ-Éý»ÁQŸ¹ûyu÷¤Mgà,œ¢E³Ç»>w8é(-@8)©lH]½¼X/Ÿ6(>lpœ”d}].V»ä¤L·àøšÛ{4­:¤Å§O2€g”†úãʽ®Î8’>K¥lqÀ´òòˆ›ÚMg`p؉ø¦#Ň xDÒ*Ó8±ÏݳZvc›é <ãê‹OÑäêˆësÛrÊñÔs ³´£1+‡×è^—“ôYÓ€âÄwÀIKÖ×)V»d§¤÷˜nÁñe³Ž:S=Zvá,Ó)x‚Ïg)ÉiÅúƒ®Îå)´Tb‹;¦”Ç*´êŤé î~;ÿ¡é@qbƒ;`HìDüII4Ý{ðñÝzný>ÓxÆ»^?Weá€ësÛX€)Á`@Ïmï0Á¥%}Át x1àÿi:ƒûô]uêîI›ÎÀ*ÊCzËe§»>—êuÔÖÅ;&dýejëä}ï"ðC;ßc:P¼p ™ˆ¯“ôÓ8±÷µëá¿l5€güÓ5 ä³,×çØâÀÈ‹”•êÙ-m¦30¸nI_6(n ¸†ËgÔÿˆ)xØîY-»±Ýtž0kj….;oºës-)GÝ}Çu ÝR&ËMçEà[v"~Ðt ¸ùMF‡d}][¬vÉxIKL·àø²YGÉŽn]ñªSL§à «ÊôÐã;\Ÿs$UEÜoîEc1=»•enEà°¤“õu¬ ÜÃéK’:LGàÄzrV®ßg:O¸pÑ-œ]íúÜᤣt¶Aà(~¿Okww™Î@~>g'â̆ŒwÀ°±ñ&Iß0ÝÁ}úÎçÔÝ“6€'|àÚE®Ïä©¡Ç¢PhpT ­½¦30¸m’~d:0:0àn·Kj4Ûa'õП·˜ÎÀ®¾øÕL,w}î`[N9fÜ(˜ÒÒVln7üÜl'âÓ€ÑwÀ°²ñNI·šîÀàn½g4r!€€ß§]¿Øõ¹tVjd‹;s8Po:k:ƒ{JÒc¦#£î€Bø¡¤¦#pb½é¬¾þãU¦3ð„·/›£ñ•¥®ÏÙ­99̸0좱˜ÖïJšÎ@~>i'â\! ¿éÀ蓬¯ËÅj—4Jz«éœØÖ½mºpÁxMŸ\a:£~ŸÒ™œžYÐÕ¹lN* ZŠ„¬•0ö­ÛÛ§®^¶·ìDü{¦#£ Ü…ò°¤Õ¦#0¸ÿÞsêîI›ÎÀ¸÷]µ@ÑH‰ësvk®5Œ]¹@DÍÉ>Ó\¯¤O›ŽŒ>lpD²¾Î‰Õ.Ù%éݦ[pbm½šTY¢3çL6€Q%A¿:ºú´jK£«sé¬ Y*+a‹;CU^^¦§6&å8¦K‡ÿ²ñ_šŽŒ>lpŒˆ?.é¦;0¸[ïY£í¦30Y¨pIÀõ¹ý­¼ëÀÐYÚy8§lŽ×ÙE YÒWMGF'Ü…ö IYÓ8±¾LV·Ý÷¼é Œ_Yª—îú\g£¶.Þ|`("±˜vH™Î@~¾`'âlÒ²ñ­’¾oºƒûÍÓõZ±f¯é Œûç7/V àþò¹ÍwNZ8T¢›™—.;$Ýe:0z1à _Ôj:ƒûDüYu¤zMg`Ô´ åºöâٮϵu9êèaÈ€“‘L‡”êáñEâSv"ž6½pœˆ‘ôyÓÜÁæ.Ýóëõ¦30î#o=C>Ër}ÎnaÀ·b±¨V½Øf:ùyZÒoLGF7Ü#åNIÛLG`pßzpƒ6ïl0€Q§M¯Ô² fº>w$娫!wòåóù´vo^N‹OÚ‰8¿[€‚bÀ0"^z4ÕM¦;0¸\NúÜÝÏ«/Í£ßcÛGo8C'±Ä-î¸,êБÓÈÏÏíDüyÓ€ÑÏo:0v$ëëvÆj—\ éTÓ-8±M)͘ÖÂS'šNÀ˜ÉÕ­ÚÒ¨} ®ÎuõIc>¸À •••*±)©÷Šƒ>I×%ëëÚL‡F?6¸FÚ'$±¼Ür÷ Úw¨ÕtFýË[Ïp}Æ‘t 57ü1Œ2v›¥t–éö"·ñ=¦#cî€e'â[$ÝiºƒëéÍè÷¿ Çáb`ìºèŒ©:kŽû'œ5&õq‹?ÇUhK½»§¦Á˜I_1;p˜ðyI<²ªüúéz=þÜ.ÓõÑ“Øâžs¤ƒlq`@Á`@+·3Ü^D¾h'â<0bpŒ8;?¢þ!wO}ï9iK™ÎÀ˜eÌÔœ™ã\Ÿ;Ôî(ÃŒ;ÇèS™Ú:Ó¦3Ÿ]’¾o:0¶øMƦXí’5’n4Þt N¬«'#'—ÕÅgÏ0€1åe%úãʽ®Î8Žä÷Yª(µ Ò@1ŠFËõÔÆv9¦C¯Ù‰øFÓ€±… î#ìD<-é&ÓÈÏ]¿ÞªÕ›mÓsÍÒÙš>)êúÜÁ¶œr¼c€$ɲ,m9VÎáÅr‘X)éÓ€±‡w€Iô'ÓÈϧ¾·R]=<"06ù}–þùÍ‹]ŸKg¥†vÞ´@’‘˜ê»Lg Ÿ°q.lFîc^zô IYÓ-Ü‹ûÚõ“Çxê`ìºñu§k¸R×ç´æÄb:ÀXWééÍí¦3¿‡íD|¥éÀØä7Û’õuM±Ú%%oºƒ[±¡AW]4CUe¦Sq~¿O9GzzÝWç²9)´T² T€÷µ÷•Ênî6üôJº.Y_×j:06±ÁàŸ—Ôf:ƒËæ}æ+•ÍæL§`Ä?¼až*ÊC®ÏÙ­9±Ä0VEcQ­ÝÅöö"ò_v"¾Ût`ìbƒ;À¸d}]W¬vI¤+M·`pûSš=µLsgM0Àˆ+ ú•êɨnSƒ«s™¬ Y*+a‹;`l Z»7­®Þ¬éä瀤“õuiÓ!€±‹ î¯ø¾¤í¦#Ÿÿ¸³N ͦ30âýW/PY8àúœÝÂwÀØÓk•©9Ùg:ùû¤ˆ§LGÆ66¸™¬¯3ÝãØàð’ßKú_ÓÈÏ#OíÖÓ«ëMg`ÄGÞr†JCî·¸ïc‹;`ŒðûýZ³§G/…‹ENÒr;çw `îÏxéEÒM’²¦[Ÿ»ã%;{Lg0âÆW–ê]¯Ÿçú\G£ÖïF?'QC ï'‘»ìD|é$Éo:€—KÖ×5Åj—L”t¾é .Õ–O9½úÌÓ)Œ¸…³ÇëþßoQ:“su®;-M®° T€yÑhDOnHŠ[¼‹F«¤ë’õuݦCØàð¦ÏKj3ü|ï‘MÚ´£Ñt#®º"¬w¿q¾ës=ŽZØâ¥|>Ÿ6Ùiå^û‘[ìDüˆéþ†w€ç؉x³¤/˜î@~GúøíUwOÚt #îŸß¼X‘pÐõ¹}Gx“0:ÂQí?Ì"ð"²AÒݦ#x9¿é«]²FÒ’ªM·`pGÚ{Uöé¼SM§0¢JCuv§µj‹»§›õe¥HÈRY‰U 2F^yy™žÜ˜TŽûº‹Év"¾Çt/Çw€'Ù‰xŸ¤O˜î@þ¾öÀZmÙåîÍ|Fƒ_¿Xåe'±Å½…wû£‡eYÚ~(«L–×»EäA;O˜Žà•pxÙc’þ`:ùÉ夛ãϨ§7m:€U é}oZàú\ª×Qs'oúF‡P¤B{ºLg Ý’n6À@px–ˆ;’–Kê5Ý‚ülØÕ¢Ûh:€÷¡ë))q}nßÜÅ/)UbC‹é ¸ó;ßo:€øMp"Éúº–Xí’ ¤¥¦[Ÿg64hÙùÓ4¡ªÜt #&\PO_FÏmjpu.•ÊB–ÊJ¬•Ph–$jjï3‚üí‘ôÎd}]Ætaƒ; |Uý/®P2YG·ü`¥zzÓ¦SQ¼v‘b'µÅ='ö¸ŠU$Z¡íNÓpç&;ï1Àñ°ÁàyÉúºL¬vÉNIï0Ý‚ülîÒ„X@gÍb:€*ñ+ÉiåÆC®Î¥³RY‰¥Hˆ-î€âRVÖ_·t*“åÖí"ògI·$ëëLwp\lp;LÒoLw ·Þ»F[w5šÎ`DýÓ5 U ¹>·¯…-î€âs Ý§ž¾¬é ä/#écv"Îe€§1à(&“Ôm:ùÉdÝr×JõôfL§0bÊË‚úോ\Ÿë:xoP<ÊcÚ\ßa:î|ÇNÄ·šŽ`0~Óä+Y_׫]âHºÌt òs ©Kb~5wŠéFÌÂS«õ“?ls½Á®«×Ñ” Ÿ,«@a “p8¤g¶¥”Îp³v9,é-Éúº^Ó! † î€bóMI/šŽ@þn½g­¶í>l:€ õ¡ë»>×f‹; 84u”êqwc7Œûv"Þn:€|0à(*v"Þ+飦;¿L.§ÿøþ³êí˘N`ļïM T]v}n_KN3î‹Æ*´~WÒtÜyAÒ½¦#È—ßtn%ëëvÇj—,´Àt òs¨¹KÕрΚ;Ùt #"èß/óôº®ÎerR8h©;›Žàd±ÁPôìD¼AÒ-¦;àέ÷¬ÖŽúfÓŒˆw½~ž¦Œ¸>Çw€I‡;êìæéÜE¦EÒͦ# ܣŒ֙Ž@þ²9GÿÖ_Õ—æb`ô |ú×Ît}®/#5´3áy‘X…6ìIšÎ€{7Û‰8ÛæEwÀ¨`'âI1Ýw6ìjÑ=¿Ù`:€ñöes4crÔõ¹ý-9ey<`••†•ØØn:î­tŸé†Êo:€á’¬¯³cµKfH:Ët ò·bý!]~ÞTMª.7@Aù|–ªc¥úó{]Ë9’ßg©¢Ô*L/cY–$ƒjlí5w2’®²ñæC*6¸F›ÿÔj:ùsé_¾ñWu¦¸8ý®}íl-œ]íúœÝšS:[€ ^!ôÿÙ»Ó(É﻾÷Ÿª^§—­3ÚÕò&Ûò&o-yccƒŒ ‚!؆ؗãë˜[BIH.ÉMnB. 7aq ÆÖê²$Ë-Yû>’f¦45£Ù—š¥÷®û@\ˆcl¦zºæ×ËëuŽŽ}ÏyŸ£êÕ·¾ÿÑZ¶µN”Π{¿ÚjÔ)+ÁwÖ•vsêTmbòh’÷”náô=>›¥……¼ùÕ——N€ž»â¢ZþÛ­Ou5Óé<÷Ϲ£®¸Ð;££#¹õáv––J—Ð¥I¾«Ýœš/+ÁwÖ£ßLrwéºóoþèÑÜ~ïÎÒÐs_wí¥yÓ+/ézîÙcÌøš€©V«yìÙ…,,tJ§Ð½i5ê§JGÀJ±àÀºÓjÔ“üpOÝkÌÇ~íŽ8âUw¬?ívžç IDATýá×§Zéî{§“49¡@oT‡Æó̾éÒtï[ú§KGÀJê+½ÐnNí©MLnMòºÒ-œ¾“Ó 9Ö>•·_7‘J—_òÀZ²õ¼‘<¹ëh¶=s¤«¹SsÉyc• ö{n`åŒå–޹"·öœHòžvsêxéXI.¸°žýL’¥#èÎïݼ=~Û¶ÒÐsŸü¾×¦¿¿ûé›­°rúûûsßÎÙ,u¶u’ü`«Q_(½ÐW:z©ÝœJmbòŽ$IÒý·Å³}Ïñ\tÎ@^ñ¢‹J§@ÏŒ dfn1Sïíjnn!ªdd°Ò£2Ö»ÁÁܽ}.Ó³­AÿW«QÿÍÒÐ+.¸°îµõ§“ü\éº÷ó¿yO}z_é è©üöWäüÍÃ]Ïí<¸”ŽCî,S{~8GŽÏ•Π{{“üLéè% îl¿–äÞÒtgna)Ÿ¨ß‘“Ó>T`ýÛ4û®Wu=73ŸìkÛp {cµÍùÒ¶£¥3Xžµõc¥# —,¸°!´õ…$7‰w«­1=}8ÿöü6€õíƒïzi.ß:Þõ\óÐR—zÀº5<<”Ûm—Î`y>›äS¥# ×úJÀÙÒnNí­MLŽ$ySéºóÅGöç ×\Ë.Ú\:z¢Z­äÜÚp>sçήæ–:I_µ’Í›*=é`ý943œÖéÒto6É»[úáÒ!Ðk.¸°Ñüb’§KGнû·åÐÑ“¥3 gÞÿ–äšçßõ\ëÈRæ½³€Ó0:¾9íp½}ú¥V£n߀ Áw6”vsj¡61ùp’–n¡;'¦røè©¼ãº«Rq”€u¨RI.Û2žÿþ¹§ºšëtžûçÜQÌ|u##›ÒxäD—:¥SèÞãI¾¯Ýœòw6 îl8íæÔŽÚÄäI®-ÝBwÙq$/¹b,/¼²ûkv°L\RËÔÃÏf×¾]͘M¶ŒWÓïSþ•J%»ŽõåÀÑÙÒ),Ïw¸ÞÀFR-…ü½$ûJGнýúÒÚ{´tôÌOøõ]¿½¬ÓIž9´Ô› Ö¼þMµ<µûdé –ç?µõÏ•Ž€³É-6¤vsjº61ÙLò¥[èÎüÂRžhÎûÞò‚T«^½ÀúsÑù£y¢y$OîêîÞ'ç’óÇ*ì÷¼ À_©çæަS:„å8’ä½íæÔ©Ò!p6¹àÀFöIþ¤tÝ»ý½ù/Ÿ~¸tôÌ'¿ïµéïïþ#ü‡¬+ðW2õÔ©,usÇ“¥3 '~øo½2çÕ†»žkZJÇÀ†Ô××—Çv/f~a©t Ësg’ß(%¹àIÚÍ©ƒµ‰Éj’o(ÝB÷nº»•÷¾y"çŒo*+jp /ý}Õ4îmu5·°˜ õW26ìŠ;ÀF³40ž‡w/ÁòÌ%yW«Qß_:JrÁþʯ$y¤tÝ›ž]ÌOþŸŸÏÌìBéXqzÏKsåŵ®çš‡–²èXÀ†2^«å )ÁòýÃV£þXé(Íwø íæÔbmbò¾$ߟÄy³5fÏÁSê_Êu/¿´t ¬¨¾j%—\8šÿqÛö®æ–:Ïýûœsl›†‡rÇÓ™›÷kç5êþ$j7§ü`óàÿ“vsªU›˜§t ¬¨\~NîzdovíëîóÇg“-ãÕôû6`]«T*yöÄ`öš)Âò,&yO«Qß]:VƒjéX…~&É®Ò,ÏýËÛ³÷@»t¬¸_øÈuéïëîcýN'ÙqÐá7€õnp¤–Çwu÷£hV•ÖjÔï+«…›-ð¿h7§æj“Û’| t Ý;9³=ûÛùæ7>/ÕªW°°~\pΦì?|*>u°«¹é¹dóH%Þ“Ö£ñ±±Üüà±t:¥KX¦Ç“| ÝœZ(«…wøk´›SOÖ&&¯NòòÒ-tïÉV;ÓŸW¼è¢Ò)°¢®}ñ–üÎgÏìübWs'g“‹6WbÅ`}èïÏ»rbÚnôÕIò­­F}géXMº{—)l,Kr¸tËós¿ù¥ÜÿØîÒ°¢Î« çcßýê®çNÎv²ï˜S~ëÍñÅMÙt¶tËWo5êw–Ž€ÕÆ‚;|­F}’—î`yæ:ùø¯ß‘ÃÇN•N€õáoyižÙæ®çš‡–²°Ôƒ Š­mΗ¶-ÁòíHò3¥#`5ê+«YmbòÁ$oLò¼Ò-tïp{6ÇOœÊÛ^?‘JÅKØXªÕJ.ßZË5žîjn©óÜ{ÏÏñŒ °ÖŽnÊç>‘Å%oëZþ£Õ¨?Q:V# îð5´›S©MLÞžäï&,ÝC÷zúHžwñH^|Õ…¥S`Å<ïÒ͹ï‰ýÙùl»«¹³É…cÕ øv`ͪV«Ù~¨/‡Ú³¥SX¾ßl5ê¿^:V«jéXíZúŽ$Ÿ(ÝÁò}â7î̶JgÀŠúù\—þþî>æït’—zTÀÙÐÏν'Kg°|{b¾&7Zà4Ô&&ïIò†$Ï/ÝB÷—:¹÷±ýyß[žŸÁþÒ9°"Ϋ çH{&÷=Ñݺ§ç“ñM•l¨ô¨ €^©Õj¹åÁ#¥383ßÓjÔ,«™w8 íæTj“ŸKòI† ç° ûÎdnv>_ÿš+J§ÀŠyõÕ[ò»Ÿ}"3s‹]Íœíä¢ÍÕT츬ÃCƒùâSÓ™™óf®5ìw[ú/—Ž€Õ΂;œ¦vsª]›˜Ü—ä[K·°<÷>q0/¿jsžùy¥S`E ögdx ·|iWWsó‹É@_%ãÃ6ÜÖ†JÎ e×™Ò!,ßÁ$ßÒnN*«]µt¬1ÿ1ÉŸ–Ž`ù~ô_Ü–gž=Z:VÌ÷¾ë%yÑçv=÷Ì¡¥,twø€B†Ç6çáÇKgpf~´Õ¨(kwèB«Qï$ùh’#¥[XžS3 ùñ_ý\fçJ§ÀŠè«Vò ¹.•.±/,%ÍÃ^k°ÚåÖ—ÎàÌüq’O•Ž€µ¢¯t¬5íæÔ‰ÚÄä3I¾½t Ëóì¡S©f1oxåe¥S`E\yq-=u0ÛwëjîäLrÁx%}]nÇpV æîís95ë\kر$ïj5êNðÀirÁ–ç÷’üaé–ï×~ÿ¡|þž¥3`ÅüÜG®Ë@wûw’l?ÐéMg¤R©dO»?GŽÏ•NáÌ|¼Õ¨ï)k‰wX†V£ÞIòCI”naù>úËŸË®½GKgÀŠ˜¸¸–ïï5]Ï=ÕÉá“–ÜV›þMµ<öŒ£ßkÜI~«t¬5Ü`™Zú$?Xºƒå;9³þ§·fzf¾t ¬ˆýíWç‚s6u=·ãÀR:vÜVZ­–Ï=x¸tgæd’þÅ=  }¥`-k7§«ML¾(ÉËK·°<{Ogfv6_ÿš+J§ÀèKmt07ÝõLWs KIµ’Ú¦JÊ8]›6 åŽ'¦37¿T:…3ó­Fý¦Ò°¹àgîÇ’<[:‚åû÷üx>}Û¶Ò°"¾û/Î5Ï;¿ë¹g/e~±Aœ¶jµš«91½P:…3ó™$ÿwéX«\p€3ÔnNM×&&OòÒ-,ßwµòÎë/Ïù猔N€3R©$/¸üœüÁÍOv5×é$‹KÉy£®¸38žûŸn—®àÌIòÍ­FýxéX«,¸À h7§ž¬ML^‘äÚÒ-,ÏâR'w>ôlÞÿ–çgh°¿tœ‘˶Œçñæ‘<¹ëhWs'f“óÇ*ì·äp¶×j¹åÁ#¥38sn5ê_,kYµt¬#O²«tË·m×±üãÿpg:Né8c?ûý¯ÏÐ`÷wn¶ð\ p¶ŒlJãáv|U¹æý^«QÿýÒ°Ö¹à+¤Ýœš­ML>”äûJ·°|m?’Ë/Ê5ÏßR:ÎHml(3³‹¹ë‘½]ÍÍ.$#C•Œ ºâp6ôõõ婃ÉÁcs¥S83Ï&yO»95]:Ö: î°‚ÚÍ©íµ‰É­I^Wº…å»åK{ò–k·æ¢ ÆK§À¹öê-ù¯7mËÉéù®æNÌvrÑæj*vÜzn¾o,ìÙs¤Óƒ"þg£µÍùâcGKgpæþm«QÿLéX/,¸À k5ê'’|8‰o×°æÞùÅ÷…Ì/,–N€3òo{a^ù »žÛud)s = I2::’[´Ü¾<ä¥#`=é+ëQ»9Õ¬MLnNr}é–ï‰gŽåü±j®}ñÅ¥SàŒ¼èÊsó©›¶u5Óé$ KÉùc•Ul\ýýyäÙ¥;1_:…3³”ä½­FÝ[Þ`¹à½ó3Iž(Á™ùÅÿç¾Üy³tœ‘×¾dkÞûuÏïzn_»“3^R°ÒŽ- çÙC3¥38sÿ´Õ¨¡t¬7Ü GZút’æ¹_l³F-.uòÿz[Z{½€µíg>üúŒ ÷w=·ý€w€•42¶9÷>y¬tgî$¿P:Ö£¾Ò°žµ›S»k“›’¼©t Ëwjf!ï<”÷¼éyéï÷çkÓøÈ`úª•Ü~ÿž®æf’¡JƆ*=*Ø8ÆÇGsóCDzäLÚZ7—ä]­F½»‡là´ØÐ€«MLÞžä}I¶”naùví;™,-䯺¼t ,ÛµWoÉgîÜ™CÇfºškÏt²µVMŸ÷Â,Ûàà@îo.äÄôBéÎÜO·õÿV:Ö+E@µõÙ$LâSŠ5î7þà‘|öŽ'KgÀ²õ÷UóË?òÆT+Ý]c_XLvt^`ù*9xj0ŽÍ–áÌÝžä_”Ž€õÌw8 ÚÍ©gk“•$ßPº…3óÙ©VÞý†+rÞæ‘Ò)°,—^8–ÝNä‘퇺š;9›œ3RÉÐ@wËñ$C£›óÅÇ–ÎàÌLòM­FýpéXÏ\p€³çŸ$¹³tgfv~1ùå›sü¤Ë ¬]ÿàû's^m¸ë¹§öwÒéô `«ÕÆsëGJg°2~²Õ¨o/ë îp–´›SKµ‰É[’|’¡Ò=,ßáölö>‘w\7‘J—¯t€Õ`x¨?çoÎ _lv57¿˜ôU+©mò< p:6 å Ûf2;¿X:…3÷é$Ÿh7§JwÀºgÁ΢vsêhmbrW’o+Ý™ytÇ‘\PÈ+¯ÞZ:–åšçŸ;Ø“ÝNt5מîäÂñjú}Ãð5õõõeû¡jöõvèuàp’on5êÇK‡ÀFàãg8ËÚÍ©k“/JòòÒ-œ™[ïÝ7¼ìÂ\¶uséX–k¯¾0¿ûÙ'²´Ô9í™N’™ùäÂqWܾ–éŒæÑgºûQ1«Ö[ºÓíp–TKÀõÃIº{8«N§“|øß’gž=Z:–åEWœ›¼¯ûßà>ÙÉ¡§¿°Ñl;'_Úv¬t+ãwZú-‰w( Õ¨Kò=I–J·pfŽŸœÏGþÉÍ9~ÒkX›~ò׿²­ã]Ïm?°”EŸl|…ñÚxnyàpé VÆî$?Z:6š¾Ò°Qµ›S»j“}I¾¾t gæÀÑ™ì?|"oŸœH¥âõì¬-ý}Õ\uÉæüñçŸîjnq)é$9wij0Àÿodd8w<>Ùy¿^'þV«Q¤tl4Ü  ÚÄäíIÞžäòÒ-œ™GwÉyc}¹öÅ•N€®=ïÒÍytÇá<Õ:ÚÕ܉™äü±Jû-¹ô÷õåɃ•8:W:…•ñ¯[ú¿*Qµtld­F}!É÷&9^º…3÷ó¿ù¥Üq_³t,Ë?üß®Ïèð@W3$Oíïô&`9¾¸)Ïì›.ÁÊx2ÉO•Ž€Êw(¬Ýœ:R›˜l%yéÎÜg¦våÝ×_‘sk›J§@WÆG38ЗÏß·»«¹¹…d°¿’±aWÜ€kxìœÜñȑҬŒ…$ïj5ê®›@!.¸ÀêðŸ“ünéÎ܉Sóù¡_¹5í3¥S k?ð­/ËK¯:¯ë¹—2¿Øƒ €5`¼6ž[î?\:ƒ•óÓ­FýK¥#`#sÁVvs*µ‰É›’|w’sJ÷pfÉþCÇóöɉT«®×°vT+•\ó¼óó©·¥ÓÅÜR'™_LÎó l,#›6åŽ'Nev~©t +ãÆ$?ÒnNuóX ¬0 î°J´›S³µ‰É/%ùP߯qî<šsF«yõK..]¹ø‚Ñì;|*=u°«¹“³Éæ‘J†|¬l ýýýyr%ŽÍ–NaeHòŽV£~¼tltÜ`i7§ž©MLö'ùúÒ-œ¹ÆýÏæÕ/<7—ž[:ºòúk.ʧnÚ–S3 ]ÍŸéä¢ÍÕTì¸À‰¥Ñ<¾Ë.ô:ò­Fý¾Ò€wXuj“·%yG’ËJ·pæn¸«•ož¼,ç3R:NÛÐ`_.ûD—:§=ÓI2=—l©¹â¬?##›rûc'3·°T:…•q*ÉÛ[ú¾Ò!À_±à«Tmbò¡$W'yYéÎÜ£;f|¸’×¾ô’Ò)pÚΫ gv~1w=²·«¹™ùdd¨’‘AKîÀúÑßߟ'ö%‡Ús¥SX9?ØjÔo*|9'D`•j5ê$?”¤Yº…•ñKÿñ¾ÜüŧKg@W~⻮͕׺žÛ~`)‹ëF%Çæ‡Ò:0]:„•ó©$¿U:øJ.¸À*ÖnNÍÔ&&¿”äCIœ<[>3µ+ßôúËrÁ¹£¥Sà´ô÷Uó¼K7çOu5·¸”,u’sG}¤¬}ƒ£›sç£GKg°ršIÞÓjÔgJ‡_É‚;¬ríæÔ3µ‰Éþ$__º…3·°ØIã¾=ùÖ¯»*#Ã¥sà´L\R˶gŽdÛ3Ý-sŸIΫd°ß’;°vÕjµÜxÿ‘Ò¬œÅ<·Üþdéà¯W-œ–”dªt+£¹÷x>þkÌÍ/–N€Óö ½>c#]Ï=µ¿“NzΆёMi<ÜNǃÍzò‹­Fý ¥#€¯ÎwXÚÍ©¥ÚÄä­I¾?‰³ßëÀŽ=dz0?Ÿ7_{yé8-c›²i¨?Ÿ»§ÕÕÜÜB2Ø_Éø°+îÀÚ2ÐߟÇö&‡ŽÏ•Naå|>Éßm7§üdV1 î°F´›SGj“»“¼¿t +ãîÇäò †rÍó·”N€Óòª]˜›ïÚ•ýGNu5w|º“-›«éó^Y`¨T*98;œ§÷œ,ÂÊ9’ä­Fýhéàk³àkHmbòÁ$W'yYéVÆ wµrýË.Ìe[7—N€¿Q¥RÉË^p~~ÿÆmétqën©óÜ%÷ Æ\qÖ†Î`-÷ý…fÞyÝå9oóHéø]tþhÉOèjîÔ\RÛTÉð€%w`uÛœÏ=x¤t+ëß¶õ_-œ/€5æ/^—öIæK·°2NN/äƒÿè¦<âõ†¬ ÿƒ¯ËÖóºÿ¡öSû—²ÔÅåw€³­V«åæ,·¯3$ùxéàô¹àkP»9µ§61y4É;K·°2Ž˜Ëc;åÝo¼*ýýþD`uèËU—nΟ|þ鮿–’¥Nrîˆ+îÀê3::’Ï?z"s K¥SX9³I¾©Õ¨ï.œ>ÛS°FÕ&&ïNrM’—–nae4÷žÈ‰“3yËk¯H¥â‹~V·ç_º9;ö´óøÎÃ]ÍŸIέd¨ß³/°z  æþgrì¤i¯3?ÑjÔÿ¬tÐ î°Fµ›S©MLÞä;“œ[º‡•qÿ“‡rþx_^uõE¥SàotýË/ÎÜòdNÍ,t5w|¦“­›«ñûn`5¨V«iµ²ëÀtéVÖ'ùD»9Uºè’wXÃÚÍ©ÙÚÄäíI>ÿ__7n½wO^õ‚srÕ¥~·Àê6<ÔŸ+.ªåOoßÞÕÜübÒIrΈ w ¼ÙÊXÚÑ.ÁÊÚä­FýTé {á`k7§ž­MLNòîÒ-¬œOßùL¾ñµ—äÂóÆJ§À×ôÂËÏÉ“»ŽfÛ3Gºš;>œ7VÉ`¿%w œÁÑ͹ý‘îžgXõ:IÞ×jÔ-,Oµt°"þM’ß/ÁÊ™[̇þÑÍyö€K¬~¿ôCoÈù›‡»šé$yr_'Nošþ&ãµZn}àpé VÞ?i5ê·–Ž–ÏwXÚÍ©Ô&&oHòIÎ+ÝÃÊ8qj><±/ï~ÓUè/_Õ¦¡þ\ºe,vÇŽ®ææ“J’Í#®¸gרØhn~ðx—üêvùB’·›SK¥C€å³àëD»95[›˜¼-ɇ“؆^'v<•C‡Oäm¯¿2Õª/ûX½®¾òÜ<¶ãpžjíj®=“œ?ZÉ`¿ç^àìØ´i(w?=›“3‹¥SXY“|c«QïîÁXu,¸À:ÒnNí­MLHòžÒ-¬œ‡wÉÈ`'¯»æ’Ò)ð5½áçS7nËÌ\wK"Çg’‹j•Tì¸=Ößߟ§V³÷ÈléVV'É·µõûJ‡g΂;¬3µ‰É{“¼(ÉËK·°rn{`o^|Ùh^xå¥Sà«ÈÖóGó™;wv57¿˜T+•lÞdÃè¥JŽÍä‰Ö‰Ò!¬¼ØjÔÿCé`eXp€u¦ÝœJmbò†$ßžäüÒ=¬œ¦ZùºWnÉÅÖJ§ÀWõ’«ÎËCOÌöÝǺškÏtrÁX%}–Ü€Þ¨×r×GKg°ònJòÑvsªS:XÕÒÀÊk5êÇ“|G’™Ò-¬œ¹…¥üÀ?¾5Í݇K§À×ô+?ú¦ÔF»šét’mû:éXGz`t|s>ÿБÒ¬¼=I¾§Õ¨/–VŽ î°Nµ›Sûj“û’¼·t +çÔÌBî~ôÙ¼ë Ù4ÙjÔ¿t°ò|< ëX»9•ÚÄä I¾-É¥{X9OµÚ™Í›¯½"GíX¥®ùÅùÝžÈÜüé/’t’œ˜M¶n®Ä#/p&òȳK9Üž+ÂÊû£$k7§Jw=`ÁÖ¹vsj®61ÙHòá$¥{X9÷<~0nîÏ+_´µt üµÆGsîøpnºë™®ææ’þj%µMVÜ€å©V«Ùwj(;öž*ÂÊÛžä]­F}¦tÐÜ`h7§ö×&&ŸMò­¥[XY·Ü³;/»ª–ç_~^éøk½âäîGöæ™}Ç»škOwrÁx5¾É–a¡o,÷=Ý.ÁÊ›MòÍ­F}Gé wª¥€³æ·’üvéVV§“|ôW¹÷ÑÝ¥Sà«úç?þæŒw÷b¹¥Nòä¾¥ëÙÐèæÜùØÑÒôÆ·õ{KG½åî líæTj“7&y’ K÷°r–:ɟݾ3ßtÝe9oóHéø µ±¡Œ æ–/íêjnv!éï«d|¸Ò£2`½¯mÎ÷.Aoüç$?ÛnN•îzÌ‚;l íæÔ|mbòsI>”¤»³i¬js K¹ùî]yÏ'262T:¾Â«^ta¾ðàžìÞ¢«¹cÓ\8^M¿o4€¿Áxm<7Þ4K^µ=šä[[ú\é ÷| L»9u 61¹;ÉûJ·°²Ú'çs÷#{óž7]•¡ÁþÒ9ð&¯¹(¿{ÃYX<ým“N’SsÉ–š+îÀW766šÏ?r"³ó¶Ûס“IÞÞjÔ÷”Î î°µ›SÔ&&¯LrméVÖÞÃÓÙ¾ëp¾éú‰ô÷UKçÀ—9g|(ÃCýiÜÛêjnf>ì¯dlØ’;ð•F6 ç®ís9~j¡t ½ñáV£~kéàì±àTmbòÆ?W\|Néø2¯yÉ–|îžVöêîÒb{º“-µjúª= Ö„ÊP-S-Aï|W«QŸ*”áã_ I~.ÉgKG°ò––’ýÒ-yä©}¥SàËT+•üË}}º»Å³°”<µ©GUÀZ°iìœÜöð‘ÒôÎ?k5êR:(Çw íæT§61ùé$ß‘äÜÒ=¬¬…ÅNnøâ3yçõ—góø¦Ò9ð—Îß<œj¥’;ÜÓÕÜô|2 ôçÉýÕì=2S:…ÞùïI~¼Ýœ:ý×zëš{€¯ÐnN-Õ&&ÿ<Éw'©•îaå}ñ‘ý¹èœþ¼üE[K§À_zÓ«.ɽùÉÌÌ-žöL'ÉñÙdk­â‡Ü°ÎT«Õì?5”§Ÿ=Y:…Þy4É{Zúlé`õ°àüµÚÍ©“µ‰É;’|0þfX—n¾gw^vU-Ï¿ü¼Ò)$ÌÕòé;vt57·ðܿϱáëG%Ó˃ÛÛ¥CècIÞÖjÔŸ-¬.–Õ€¯ªÝœÚ]›˜|6É{K·ÐvÇ3yó+.Ì%[ê`uxÑçf×¾ãytÇá®æÚÓÏ-¸ Xr€õ :\Ë-Aït’|[«QŸ*¬>Ü€¯©Ýœº¯61yq’×–naå-u:ù“;væm¯¹8ž7V:’$oºöÒüÉç·ç؉¹®æŽMw²µVMÕŽ;¬i#ãçä–ºûÑ+kÎ?h5ê¿U:Xª¥€5á'’|±t½qjz!ßý³7fGˇ„¬£Ãùõÿý-éïëîkŒ™ùäéK=ªΆñZ-7Ýç{«uî’üré`õrÁøµ›S‹µ‰É?Oò½Iœù^‡¦grã]Ïä]×_™ñÑ¡Ò9K.ËüâR¦ÞÛÕÜÉÙdd¨’‘AgÜ`­ËMËâR§t ½óp’oi5êݽ² ØP,¸§¥Ýœ:^›˜üb’ï‹·À¬Kí“ó¹ýÝy÷®ÌÈð`éÈu/»8Ÿ»§•½‡Nu5wôT'Öªé÷ ¬££#¹ýñS™™óV¦uìh’·¶õ}¥C€ÕÍ‚;pÚÚÍ©gj“G’¼«t ½qðèLî{bÞù†‰ ö—Î`ƒ«V*yÃ+.ɧnÜ–ù…Ó_rYê$§æ’-5WÜ`-Ù´)w?=›ö©…Ò)ôÎR’÷·õ»K‡«Ÿw +µ‰É»“\•ä•¥[èÝNfÛ3‡óŽÉ+3ÐïÏEÊ:g|(çmÎMw=ÓÕÜÌ|ÒW­¤¶É’;¬fÃÃCy`×BµçJ§Ð[¿Õ¨ÿ§ÒÀÚ`c èJ»9•ÚÄäg“¼3ÉÅ¥{èí»ÛÙwðxÞúº+ÒWõ>wÊzù .È#ÛåéÖ±®æŽMwrþh%ƒý–Ü`5Èû’gÏ”N¡·>•ä'ÛÍ©ÒÀaÁèZ»9µðKî'ÉHézã‘G23=›7]{y*‹”õæW]š?¼åÉœšYèj®=lÝ\‰G[X]úûûóÌÑþ4÷*Bo=”ä½­F݉~à´Yp–¥Ýœ:V›˜¼7É÷&ññ:uÏ3Ø·”É—]Z:€ nÓP®¾ò¼üQã©®ææ“Å¥äÜQ_ÀjQ­V³ÿÔP¶µN”N¡·Ž$yk«Qß_:X[,¸ËÖnNm¯MLN'y{ézçŽ÷åÂZ^ù¢­¥SØà&.©åp{&÷o;ÐÕÜñ™¤¶©’áKîPZ¥RɉÅÑ<´³]:…ÞZJò¾V£~Oé`í±àœ‘ÚÄäI^’äšÒ-ôÎÍ_Ú^2’«'.(À÷ÆW\’?¿sg›éjîè©N¶Ôªé«ö¦ 8•Ìõåž'•¡÷~ªÕ¨ÿ¿¥#€µÉǸÀi5ê$?äáÒ-ôÖþËÛó¹»w”Î`ƒìËo|â28ÐÝ Ÿ¹Åä©ýK=ªNGe¨–»?Z:ƒÞû½$¿Z:X»\pÎX»95W›˜¼1É“ —î¡7:äOooæ /¿0—n©•Î`ÛrîHúrÛý»»š›žK†*ªô¨ øjG6§ñÐáÒôÞI¾µÕ¨Ï—Ö. îÀŠh7§×&&ïMòxK̺µÔéäOnß‘·¾ú’l9o¬tØk_²5_|øÙ´öŸèjîØt'ŽWÓï8kFÆ6çæ,·o‡“¼­Õ¨(¬m>¾VL»9õtmbòp’w•n¡w:ù³/4óM¯¿,çn)ÀU©$ozÕ¥ùÔMOfvnñ´ç:äøL²µVIÅ!wè¹ñÚæÜpßát:¥Kè±¥$ïm5ê÷–Ö> îÀŠªMLÞdk’×–n¡wffsã]»òÎë¯Hml¸tÔøÈ`.Û2–?ÿÂήææ’J’Í#6Ü —ÆkµÜpßÑ,Ynß>ÑjÔ§t°>XpVT»9•ÚÄä IÞ˜äªÒ=ôÎñSó¹í=y×®ÌȦÁÒ9lPW_y^vìiçñ‡»škO'çŽV2ÔoÉz¡VÏM´³°h»}ø/I>ÙnN•îÖ îÀŠk7§–j“šäÛ’œ_º‡Þ9tl&÷=±/ï¼~"Cƒý¥sØ ÞüªKóÇŸßžöɹ®æŽMw²µVMÕŽ;¬¨±±Ñ|î‘™_*BïÝ—äý­F}¾t°~Xpz¢Ýœšþ‹Kîß›d¸t½³ûÀ©lkÊ;®›È@¿?/8ûúòŠ\?¼åÉtº8¹°”Ì/&çÙp€•26:’;¶ÍääÌBézï`’·µõƒ¥C€õÅÐ3íæÔ¡ÚÄä½I>¤Zº‡ÞÙ¾çxZ{æ­¯½2ýýþSpö]ºe,³s‹¹ëÑ}]ÍœMF‡*´ägjÓðP¾´s>ÇN8æ½Ì'yo«Q t°þXpzªÝœÚ^›˜<˜äÝ¥[è­Ç›Ç²ïP;ßðÚËÓ×gÉ€³ïº—_œ[ïÙ•}‡Ou5wtº“-ãÕxœ€åÌÃ{:9pt¶t gÇGZú•ŽÖ' î@ϵ›Sw×&&·$y]ézë‘GrôØÉ|Ý«/O_ÕVgWµZÉõ/¿8Ÿºi[æ–N{n©“œœK¶Ô\q€åèÏS+Ù}p¦t gÇ?k5êÿ¼t°~YpΊÚÄäI®Oò¼Ò-ôÖOÎÉ“Óyóµ—§ZµÀÙunm8çŒåæ»wu573Ÿô÷U2>ìYºÑß×—ÝíÁìx¶»7)±fýQ’¶›SÒ!ÀúeÁ8+ÚÍ©¥ÚÄäŸ&y’óK÷Ð[÷n;”¹¹Ù¼ñ•—¥R±ÀÙõÊ^˜‡Ÿ>”í»u5wlº“óF+ì÷, §£Z­æÐìpßu¢t gÇ}I¾¥Õ¨Ï•Ö7 îÀYÓnNÍÔ&&oHòw’ —î¡·î~ì@*K ¹î—Zrà¬{Ëk.ËŸ|~{Ú'Oç–Ü·ÖªñR2øÚªÕjŽ/ŒäÁíÒ)œÏ&yk«Q?T:Xÿ,¸gU»9u¨61ù¥$ß“¤Zº‡Þúâ#û3Ô×É뮹$vÜ8›†ûóšoÉÜòd––:§=·°˜Ì.$Œy€¯¦R©ääÒhî{º»·&±fM'yG«Q¼t°1XpκvsjGmbò@’w—n¡÷npoƇ“×¼ôâÒ)l0_0š‘áþ4îÝÝÕÜ©¹d°¿’±aKîð¿ªT*™ÎhîyÒrûòÝ­FýæÒÀÆaÁ(¢ÝœúRmbò‚$¯/ÝBï5î6Œ÷å•W_T:€ æ5/ÞšG¶ÊÓ­î–oŽžêä¼ÑJû-¹À_©d®:–»·Ynß@~ºÕ¨ÿ»ÒÀÆbÁ(¦61yc’ë’<¿t ½wË={rɹƒyÙ ·”N`ƒù†×\žÿqÛö´OÎöL'Ï-¹o­USµãI*YèÏÔGK‡pöüv’O´›S¥;þ?öî<ÆÍ;Ïïüç!Y,²H>u¨Ý¢/Ù²lÙ²dÓw[¶Ûîvwoß×ô ›,&È"È&X$&AYll°0f‘6Á&;íé¶åÛnÉ:–h–¬ÛRôè–êxê`‹ä³”'Óíén“¶ª~<Þ/@~÷¨Èúð!€&ÃÀ㻹²Î¼%é»’ºM÷`þm=àé¶¾¸ÖÜÞc:ÐDZ£am¼·O¿ØvVårPñ]±,M¥î$ w4;Kå–”ö1‚…³WÒ='[4šw`”ïæ¦ítæW’þPRÜtæß{¹ Z½<¡Õ«øL`á,^”P²­E;yUÝM¤–ˆ¥TŒ‘;šWµõÁIÆíMdPÒóž“õM‡€æÄÀ绹a;9 ég’B¦{0ÿÞÙw^÷­²uÇŠ.Ó)€&òÐݽ:58¬sÞhUw£Sº–¢Fîh>V«­='·7_Òsž“uM‡€æÅÀÔßÍ ÚéÌ5Iß4Ý‚ùÒ›{‡´þÎN¥—ušÎ4‘M–ëÍ=›(Tu7:¨×)ÄÆM$o×®cŒÛ›HIÒw='»ßthn Ü@ÍðÝÜ!;é’”1Ý‚ùÒ»‡ôÈ=‹´bI‡é@“h†õðšÅúåö³*•ƒŠïŠeizVêN±p@sˆÄÛå|qGtöÂhUw£ù@] KÑ#w4¦ÖD»¶eÜÞdÞ“ô7}7W6 I!ÓŸå9ÙQIß’Ä;gMbf¶¤ÿ³_éØÙ+¦SMäÿüOkÕ’ê¾Q,¤Ó—Ë*2û@Š'Ûµí¢k2'$ýÄs²EÓ!‰'¸€šä»¹a;Ù+ég’"¦{0ÿŠ¥@¯íЦõKÔÛ•4hÑ–°^Û§_n?«R)¨ø®X–ò³ROЧ¸ qÄ“ízŸq{³¹!éYÏÉò*PS¸€šå»¹ v:sZÒ%ñã&0;[Ök»õ̃‹Õ»ˆ‘;`þõuµ©=Ѫí/Tu—/H‘°¥TŒ·,PÿÚRsãö òÏ}¢þ$}Ýs²›ø,î ¦ùnî¤Îø’^4Ý‚…Q˜-ëÝCzj]¯úºS¦sMàÁÕ=:waTŸœ©ên4¨«ÍR4ÂÈõ+a·këGŒÛ›ÐßôœìÛ¦#~î æùnn¿ÎtJzÔt Fa¶¤7÷¸zr]3r,€¯lX®·÷ jtb¦ª»Ñ| ^;¤wÔ¡„Ý®-‡·7¡é9Ùc:àw ™¨Ð?”ôªé,œñ©‚~ü϶èÈéK¦SM oÑŸþ“çÔ­îÙ@Ó³ÒÙ«åyªæOÊn×ÖÃ#ŒÛ›Ï/$ý‰é€ß‡'¸€ºà»¹ÀNgÞ”ô¬¤¦{°0f‹e½æ êÉu=ZÒc›Î4¸ÞÎ6uÚ1m;p¡ª»|AŠ„-¥b<Æõ!e·ëW‡GTfÝÞl>”ô]ÏÉL‡ü> Ü@ÝðÝ\ÑNg^—ô]I‹L÷`aKs#÷ÇïëÑÒ^Fî€ùõÀ]=ê÷ÆtÆ©ên4¨³ÍRk„‘;j[ʶµå£QÆíÍ眤ç<';f:àó0puÅwsSv:󎤟JJ˜îÁÂ(–mÞ=¨ÇÖöh#wÀ<{fÃr½³wH#ã3UÝNê³C …æ) ø’Rv»¶U©Ì¸½É\—´És²žé€J0puÇws#v:³KÒÏ$µ˜îÁÂ(•½¶kP®éÖ²¾vÓ9€„•¹o‰~¹í¬Š¥rÅw¥²4UzR<ŵ'e·kËG#ŒÛ›Ï”¤='{Üt@¥¸€ºä»¹‹v:s\Ò$ñWã&Q*zÍTfÍ"-_ÌÈ0z:ãZÔÓûž¯ê.?+…C–ì8oW v$ívm9<¢rÀ¸½É”%}ßs²;L‡Tƒ;¨[¾›;c§37%½dº §Tž¹?²¦K+w˜Î4°uwvkðÒ˜NTu7–ÔÙf©5ÂÈæ%RíÚòѰض7¥¿ã9ÙŸ›Ž¨wP×|7wÀNg’ž0Ý‚…S½æ iã=]Z¹„‘;`þ<óÐ ½ûÁ Fü™ªîF§õÙ!…BóT -Ù®­G·7©á9ÙÿËtÀÁÛª ü±¤—MG`aÍ–ÊúÙŸ¼¯Ý‡†L§X[,¢?ýãçoTu7S”>¹Zž§*àóÅ·7³ÿGÒŸ˜Žø¢x‚;¨{¾› ìtæ-IOKZeº '¤×v jýJ/ë4hPÝquwĵõÃóUÝåg¥pÈ’·æ© øí¢‰vm;2l:f¼'égž“-™ø¢¸€†à»¹¢Î¼!éÛ’ºM÷`áôúî!=pG§ncä˜'÷ßÙ­óW|¬n$46¨#a©5ÂÈ £¥­];Ž2noR‡%½ä9ÙiÓ!_wÐ0|7—·Ó™·%ýTRÒtÎÜÈ}PënïÐí˹æÇ3–kû º>’¯ênd*PO*¤phžÂ€O…bír>fÜÞ¤†$=ë9Y~@ÝcàŠïæFítf‡¤ŸIŠšîÁ é=ƒZ›¶uÇŠ.Ó9€ ‡ôÌC˵yg¿ò3ÅŠïJei|Zêµ-Y<Èó%jk÷ñÓ0ã¦æÆí®é€[;h8¾›»l§3G$ýDÏFk"A ½¹gH÷¦mÝÉÈ0ìd«ÖÝ٭ל~•ƒ â»™¢4[’º,Üp«Y*·ØÚ{’q{“š–ô5ÏÉ1p«0p Éwsgít沤o™nÁÂ{sÏV/OjõªE¦S håâ”ñˆœÃ«º›˜‘¢KÉ#wÜ–e©Ijß©QÓ)0£,éGž“}ßtÀ­ÄÀ4,ßͶәIO›nÁÂ{ûWË»[µöŽ^Ó)€´áž> ^Óé¡êž’92¨£ÍRk„‘;¾˲4­¤><ø½‰ý=ÏÉþ¿¦#n5î ¡ÙéÌIwHZgº ïW9OÝ©°¸{±é@znãJm?xA×FòUÝLêI…ÍS^(ÒdÔ¡³ŒÛ›Ø¿òœì¿20¸€†æ»9ÙéÌÛ’žt›é,¼í‡.) ´aÍYOÇÜ:‘pH›6®Ðæç”Ÿ)V|W $Zêµ-ñRÕ …B+Æuäܘé˜ó_$ý=ßÍ™î˜ Ü@ÃóÝ\ÉNg^—ôMI½¦{°ðv¹¢ŠzxíR…B,·ŽˆjÝ]=zmg¿ÊAPñ]¡(Í–¤®¯SP¹p8¤‘BLŒ›N9ïKú±çdK¦Cæ wÐ|77c§3oJú¤vÓ=XxûŽ_Óôt^­[¦pˆï€Ü:+úRJ¶µÈ9ìUu71#E#–’1Fîø|‘pX×ó1bÜÞÄŽJúºçd§L‡Ì'î iønηәw$ýDRÂtÞÁÓ7tcd\O>¸B‘#wÀ­óÐ=½:ÅשÁáªîF¦uÄ-µ¶0rÀï‰Dte2ªSç'L§Àœó’žõœì Ó!ó;h*¾›»i§3Û$ý¤VÓ=XxÇúGtáʈ¾òÐ E[øupëlÚ°B;zº6RÝÇ'õ¦B óYlü-‘ˆZ¸4®N_ѳ—«-5h©¶¨\ݣͨåAã IDAT;ûU.ߊsÿ%Y¸`N,Öª³×- ]­î‚ÐPI?õœì{¦Cwд|7wÆNg\Iß1Ý3¼k“Ú{ô’žx¹’m­¦s byoJv[T;yUÝMÎH-K©#w€f×éc¯¬K7ó¦S`Ö?ðœì2°Ð¸€¦æ»¹£v:3.éEÓ-0ãÚH^Û\Ðó/“Œ™Î4ˆõw÷ê•q®ênt*PGÜRk #w€f•H´é@ÿŒnøÓ)0ëO<'û˜Ž0;hz¾›Ûg§3­’ž2Ý3†ÇgôîCz~ã2uÚqÓ9€ñìÆÚyØÓÕᩪî†'õ¤BŠ„æ) 5+•Jj÷©IùSEÓ)0ëßHú§¾›3Ý`wIv:³]ÒIL·ÀŒñ©Y½±{P›Z¢î΄é@‡Czvã mÞÙ¯©éÊJå@ò§¥^ےŃÜš†mÛÚvÌ×t¡l:fýgI×s²éS¸HòÝœìtæ]I÷~úM(?SÔ+N¿ž~ O}‹R¦s ÕÕúÕ½zuç9•Ë•ïS Ź‹’,ÜšAÊn×Ö#£š-²inr¯KúCÏÉ–L‡˜ÄÀàS¾› ìtæ IJºÝt̘-ë•ízì¾-ëµMçÀòÞ¤:’­ÚqðBUw“3RKØR*ÆÈ ‘%RíÚòшJU|  i»¤ïyN¶`:À4î¿Æws%;Ù,éyIËL÷ÀŒR9Ð+;úõÐê.­ZÚa:Ð\Ý#ïÚ„Nܬên4¨=n)ÖÂÈ EÛÚµíè°¶íÍ—<';e: 0pø ßÍ>¹KRé˜Q¤Í΀֬²uçÊ.Ó9€°iÃr9‡/êêpu›•‘É@=©"¡y €–µå1óNJzÞs²£¦Cjw€ßÂwsy;y]Ò$µ›î9oíÒ²E1­½“Ï:¾œp8¤g^¡Í;û55]¬ø®Hþ´Ôk[²x;@ݳ,K…PRûN±g††$mòœìUÓ!µ„;Àïà»9ßNgÞ‘ôI Ó=0gˇ‹ÚxïY, _B²-ª ÷ôêÕçT.ߊÒLQZ”äu)@= ‡Ãëð¹1Ó)0ïªæÆí®é€ZÃÀà÷ðÝÜM;Ù&é$µšî9{Ž^ÑäT^?°Láß øâ–õ$Õ™jÕöƒªº›œ‘"aK©#w€zÔ‰èòdT'ÝqÓ)0oTÒsž“=e: 1pø¾›»l§3û$ýTRÄtÌ9tæ†.^ÓSë—+Ú¯Ҁ/îÕ=ºt}B'nVu7:¨½ÍR¬…‘;@=imªÿfHý—&M§À¼)I/zNöé€ZÅ* ¾›²Ó™c’~$‰¿ 7±“C£:5p]O?´LñX‹é@Û´q…v}tQWnV7r™ Ô“ )Œԅ¶xLÇ/–uñFÞt Ì›•ômÏÉ:¦Cjw€ ùnîŒÎœ—ôÓ-0kðò¸œ¸¤§×/S*Ñj:P§Â!KÏ>¼B›wžÓÔt±â»r ùy©×¶dñ1|€š–H´éÀ@A7ÆfL§À¼²¤ŸzNöMÓ!µŽ;@|7wÄNgÆ%½hºf]¾™×΃ôÔ}êjo3¨SÉx‹6¬éÓkN¿J¥ â»BIšž•º“,ÜjU*•ÔžÓSò'gM§ 6ümÏÉþWÓõ€;@•|7·ÏNgZ%=eºf Ïè­½Cz|múºS¦sujiOR+ûl½·o¨ª»©‚$ËR{œ‘;@­±í”¶›P~¦d:µá{Nöߛލ ܾ;Ù.i©¤ ¦[`ÖÔtQ¯:ƒÚpW‡V.é0¨S÷¤»$IûŽ]®ên,(µ”heäP+R¶­­GÇ4[,›NAmøß<'û/LGÔî_€ïæd§3ïHº÷ÓhbÅRY›Aݹ´M«Óݦsuê±û—hè’¯ÓCÃUÝ Oêˆ[jmaä`Z"Õ®-ªTL§ 6ü©¤è»9Óu…;À仹ÀNg^—´^ÒjÓ=0+¤·?8¯E©°X½X›Àðü#+µïØe]¼>QÕÝðd îdHþò`L4Ñ®mG†°mÇœŸKú#ÏÉò(€*ñ6'À—໹’Îl–ôˆ¤;L÷À¼í‡.)(ôÈ}K ±rT'²ô£«ôîC˜©ø®H#Szíx9 °°,ËR)bk÷ñÓ)¨ïHú±çd‹¦Cêw€/ÉwsE;yUÒã’n3ÝóöŸ¸¦k7ÇõÔúeŠðè<@•â­=³a¹6ïì×L¡Tñ]±$MÌH=)‹oX ‘HD£…¸3‚Ú±[Ò·='[ù'VðXÛܾ››µÓ™W$}EÒJÓ=0ïøÀ°N ^׳W¨51¨3vLëïîÕkN¿Êå â»éY©P”%Y¸Ì·XkTƒÃ!ñ&L§ v‘ô¢çdù¡ø¸Ü"¾›+ØéÌ/%='i™é˜7pi\¹¨ç^¡D[Ôt Î¬èKiIwB[snUw“3R(dÉŽ3r˜/‰¶¸Ž\(éâiÓ)¨ŸHzÖs²Ã¦Cêw€[Èws3Ÿ>ÉýIKL÷À¼+ÃyýjÿžÛ¸L©¸é@Y{û"ÍÌ–tàäÕªîF§µµZj‹2r¸ÕRvJ{NOitbÖt jG¿¤Mž“½b: 0p¸Å|77ýéÈý%I½¦{`ÞØDA¯îè×3ë—¨§+a:Pgž|p™ÎžÑ'çG«ºž ÔÑf©5ÂÈàVIÙízÿȨ¦ eÓ)¨Cš·{¦Cw€y໹);yUÒ7%u›îyÓ…’~±íœ6Þ³H+·›ÎÔ™¯>²J»\Ò•›“ßš¹÷¤BŠ„æ¯  YÄ“ÚòѰJlÛñW.HzÆs²®é€FÂÀ`žønnÒNg6Kúޤ.Ó=0¯TôÊŽ~­ìéÞÛ{LçêH$ÒW3+õöÞ!ù“…ŠïÊ4:%õÚ–B<Èà ±,KŠÚÚùñ°éÔ–‹š·šh4 Üæ‘ïæÆítæ5Iß•Ôaºµá½ýQQï]¢ë@…Úb-zzý2mÞÙ¯Âl©â»Ù’49#õ¤,Y¼ ¨J8Öx±Mž5‚ÚrYÒ&ÏÉž3Ј¸Ì3ßÍÙéÌ’¾/É6݃ÚðÁ±«ºrÃד,SK ¿–*³¨=®ûïìÖ»T‚Šï¦g¥bIêJ°p¨Tk´EüˆNºã¦SP[®IzÖs²gL‡4*–4 Àws£v:ó¶¤JJšîAm8>0¢?¹ª¯<´Lmñ¨é@XµÄÖ¢Ž˜¶¼PÕÝÄŒ [JŹ|ž¶x\Ç/•uþZÞt jË ÍÛOšhd ܈ïænÚéÌ»’~$)aºµÁ½:¡Ïëé—¨ÓŽ›ÎÔ‰îêÑøTA‡O_«ênd*P2f)eäð»¤R í;;­›~Át j˰¤ç<'{Ìt@£cà°€|7wÝNg~%éÇ’X3C’tÓŸÑ»ôÈšn-é±MçêÄÓë—ëøÀM \«ênx2PgÂR4ÂÈà³R¶­mÇÆ55]2‚Ú2*éyÏÉ1Ð ¸,0ßÍ]µÓ™mš¹ÇL÷ 6ägJÚ¼c@kV&uÇŠE¦suÀ²¤]¥‡<]™ªø.æFî=©Â¡y ¨3‰T‡¶|4¢b)0‚ÚâKzÁs²M‡4 îønî²Îì”ôIQÃ9¨¥r 7ö¸Z” iÝê>YOÒü~-‘žÏ¬Ô›»415[ñ]©,奞”¥/?@Ó³еkûÑa1mÇgLHzÑs²9Ó!Í„;€!¾›óìtfæžäÞbºµcû¡KÊçóÊÜ·T¥øÉx‹_·T›wôk¶X®ø®P’¦ RwÊwЬB¡òJjß©Ó)¨=S’¾î9Ù½¦Cš wƒ|7wÞNgöknä1݃Úqðô ;SO=¸L±V>ÿøýz;ÛtwºKoíPPÅcGó³R¹,u&˜¸€æ¶èÊDTú¦SP{ò’¾á9Ù]¦CšwÃ|77h§3‡$ýHü~†_sÖóµ÷ˆ§¯¬_*;3¨qw,kW²-*ç°WÕÝø´Ô±”Š1rÍ#kÕé+Òà•)Ó)¨=3’¾å9Ùí¦Cš*€໹sv:ó±¤J ™îAí¸:2­·v è‰u½êíJšÎÔ¸‡îéÕͱi={½ª»ÑÉ@©¸¥x #wÐøR©„>(èÚèŒéÔž‚¤ïxNv‹é€fÆÀ FønîŒÎœ’ôIü5ÿÍätQ¿ØÖ¯îèPzY§é@Û´q¹Ž|r]C—ýªî†'-JZj ó¶h\)»]ïìkrºh:µgVÒ÷='ûŽé€fÇÀ †ønî¤Îœ“ô=1rǯ)•mÞ5¨¾Ž¨î¿«×t †Y–¥]¥m.èÆh¾â» ˜¹÷Ø!…ù~9Ðp,EÛÚõþ‘a•ÊéÔž’¤yNö Ó!`àPs|7wìÓ‘ûwÄÈŸñþO3ùi=ºn©Â!Ö€ß.ÚÖs¯Ðë»ú5UÅÓIKeÉÏK½¶%‹w%@ƒ‡Ãš ÚôÁÉQÓ)¨M%I?õœì+¦C0‡;@ útä~FÒw%±bÆo8púºÎºÃÚ´a¹¢Ñˆé@²Q=þÀR½îô«P,W|W(JS©;ÉÈÔ¿X¬UîHH'Ý Ó)¨MeIÃs²/›À_aàP£|7wÂNgNHúž¹ã3ÎzcÚyø‚6mX&;3¨Q}]mzðî^½¹{@¥rPñ]¾ Í–¤® wP¿’É„téæ´éÔ¦@Òßòœì1€ßÄÀ †ùnî”Î|,éûâw7|Æõ‘iýr{¿ž¸¿W‹»S¦s5jåâ”n_Ö®w?RåwibfnñÓÑÆÈÔŸ”mkû±qM䋦SP»þÈs²ÿÉtþ:FR5Îwsgìtæ#I?¿¿á3¦ %½üþ9ݹ4¡ÕénÓ9€u÷ªNu¤Zµó°WÕŸ—Z–R1Fî ~´&ÚµõȈJ¥j>Þ‡&ó?zNöÏLGà·c P|7÷‰ÎÐÜÈ=bºµ%¤·?8¯PPÔ†{+ ™NÔ õw÷j¶XÖ‡'®Tu72¨­ÕR[”‘;¨mápXy%´÷ĨéÔ®@Òßöœì4€ß;@ðÝ\¿Îì—ôCI-¦{P{ö¿ªþ ÃzòÁ¥Šµò#øëžx`©®ÜœÔñþ›UÝÝœ dÇ,ÅZ¹€ÚkêÂh‹Ž›NAí*Kúï='ûŸM‡à÷càPG|77h§3{57ršîAíùä˜vöôä‹ÕaÇMçjÐs¬Ô‰a \«êîæd Î„¥h„‘;¨-ÉdB‡†fuñFÞt jWIÒxNöÏM‡àó1p¨3¾›²Ó™]’~$Fîø-®Nëu§_ïîÒ²¾vÓ9€cY–¾öXZûŽ]Ñ¥ëßts"Pw2¤a5¶mm?6¡ñ|Ñt j׬¤zNöÓ!¨ o?Ô!ßÍ·Ó™š{’{«áÔ |¡¤_îЪޘÖÜÞc:Pc"á¾þxZÛœ×ͱéŠïÊ4<¨'R84hM´kë‘KéÔ®Ißóœì›¦CP9îuÊwsžÎl×ÜÈ=fºµ'¤w÷_PPœÑ†5Kayø5­Ñ°^|,­wöÊŸ,T|W,KcSROÊRÈšÇ@€ß!iÆJjωÓ)¨myIßöœì{¦CPîuÌwsítf«¤IŠ›îAmÚâºú/ÜÔc÷/Q[,j:PC’ñmÚ°BoìP~¦Xñ]¡$OÏÜ-Fî`µ¶Fua,¢cƒã¦SPÛ&%}Ãs²ÛL‡ z Üêœïæ.ÛéÌ{š{’{›éÔ¦³|í#–h×Ö#£š™-›NA}8"é9ÏÉ^7€ùÅÀ ‰øn.o§3?—”‘t»éÔ¶ ÞÝASzxíµDxùÍlQ{L¬]¬7v ¨Xª|„6=;÷¯;ÉẨD"š(µiïÉQ¦cP/Húªçd‡M‡`þ±Ph2¾›+|ú$÷µ’Ö˜îAí;|憜¸¬'Ö-–Œ™Î´´'©5·uéí=ƒ*•ÏѦ R±,u&¹ÐìÚÚâ:sU:ãM˜NAýø@Ò‹ž“3€…ÁÀ  ùn®d§3¯HZ)éAÓ=¨}¯OêµýÚ°ºKËúÚMç º}Y»–ö$´5çVu7>-…B–ì8#wšUÊNiÏÉIÝô ¦SP?vJzÉs²ã¦C°p¸4)ßÍ•ítæMIí’5݃Ú75SÒ/w ¨·=¢µwôʲ$@³Z{û"E[ÂÚsôRUw£SZ[,%[yM @s±mk×ûGFT(Vþ-0hzïHúŽçd'M‡`a1phb¾› ìtf‹¤’¤M¦{Pû‚@zÿÀEŒNèᵋÕ˜NòÈÚÅšž)êà©«UÝLjkµÔeä@3h‰D4:×þÓ£¦SP_þ«¤ŸzNvÆtw€&ç»9ùnn—Î KúºéÔ‡£ç†•;~Q™{{Õi·™ÎòÔúe›˜ÑGg®Wuws2P²ÕRœ‘; -‘hÓñKeõ_âܨʿ•ôw<'[23¸@’仹ítfPÒ')dºµïÒ¼6ïÐý·ÙZµ´ÓtÀMVèÚ𔎻QÕ݉@vÌR¬…‘;(eÛÚybB£³¦SP_þIÿÄs²é˜ÃÀÿïæŽÚéÌQIß•1݃Ú7](éUgP©˜´nuŸB!F ÐŒž{x¥Î_õujp¸ª»ì8#w‰eYŠÄÚµí舊%6ʨÊß÷œìÿî»9Ó0Œ;~ƒïæÎØéÌ^Iß—5݃úà|tYýnê‰uKµ˜Î,0Ë’^xt•ú½1}r~¤â»@Ò͉@m–Z#ŒÜ¨wÑh‹nL·êÀ'c¦SP_Š’þ†çdÿÌtjwü5¾›²Ó™mš¹ÇM÷ >|raLïîÒ“÷÷iQGÂt`Y–¥[¥“ƒÃ¸Xù¨->¹',E¹P·’É6=_ÒЕ)Ó)¨/Ó’¾ç9ÙWL‡ v0pÀo廹‹v:ó¶¤ïHJ™îA}/èç[Îiõò¤îZ¹Èt`…B–^zâ6ùäºÜË~Åwå@º1¨+a©%ÌÈ€z“²Ûµýظü©¢éÔ—1I_÷œì6Ó!¨- Üð;ùnîºÎl–ô-I¦{PJå@oîq•ÏOëá{«%ÂËh&á¥o/ @mkk‹«ÿFHLJÆM§ þ IÚä9ÙS¦CP›xkŸËwsv:󲤯HZnºõãÊp^?ßú‰Ö¦ÛuÛ2¾šIK$¤o>y»v¹¨«ÃSß•ÊÒ͉@Ý©"¡y _XÊn×®“º1V0‚ús\sãv×tjwTÄwsùOGîHºÝtêÇl±¬ÍΠÊÅ‚ºg±"¬ iD[Âúæ“·iÇAO7Fóß•ÊÒðd îdHa^FP3B¡Ê‘”vÑl10ƒú³OÒ ž“½f:µ;*滹‚Îü…¤{%­1݃ú’;qM¹ã—ôÄý}²“1Ó9€‹FôÒ·éýÏkØŸ®ø®X–F¦æžäÎÈóÚâq ‡ulÐ7‚úô+Ißôœ,?@ø\ ÜPßÍ•ìtæUI+%=hºõåâõIýÅûgµîö­ZÚa:°@Úb}ýñ´~µßÕØÄLÅw³%itJêIZ 1rÀ˜”ݮݧ&t}¬òÿÇ_ó²¤yN¶òO; ©1p@Õ|7W¶Ó™7%Ù’3݃úR˜-땊XE­¿§OaÃM!oÑ‹­Ò{û†äO*¾›-I£y©;e)dÍ_øëB¡‚–”v|<¢Ùb`:õéO%ý‘çd‹¦CP?¸à ñÝ\`§3[$•$m2݃úóÁ±«:rúÞë¤: IDATŠ»¿O©DÌt`؉¨¾úÈJ½óÁ&ò³ßŠ’?-u'¹°PÚÚbéèÀ¸éÔ¯)éyN¶l:õ…·ð¥-ÿÊßÿ»’þøý_@—ݪÿðŸÒëÓ¦S äœ7ªþñÛº1š¯ê®=nií²#wæ™mÛrNøšœ.™NAýúŸ='û¯MG >ñw|i¾›;`§3Kú¶¤ˆéÔ—üLI¯ìP¼¥¬u«û‡L'æY—Ó3-×›»4]¨|87S”&¦¥î”%‹‘;·\(’¢)mÿxD…b`:õ©$éoyNöÿ6€úÅÀ·„ïæNÛéÌIß•7݃ú³û踦̽}J%ZMçæYwG\O=¸LoìPa¶ò‘ûô¬4Uº“ŒÜ¸•â±VèH¿o:õkFÒ<'û¦CP߸à–ñÝÜ;yCÒ·$u˜îAý¸4®7vhÝííZ¾˜!ht}]mÊÜ·XoíÔl±\ñ]¾07t_”´ÄÆ€//eÛÚ{&¯«#3¦SP¿|IßðœìÓ!¨ ÜpKùnî†Î¼,éYIKL÷ þLæ‹ze瀒Ñ@ëV÷) ™NÌ£¥=ImXÓ§·ö ªXª|ä>UfŠs#wðÅ„B!Y­)m?:¢ÂlåÿŸq]Òóž“Ýo:;n9ßÍMØéÌÿ'iƒ¤;L÷ þä¹¢ç®é±û+ÙÖj: 0Vô¥ôÀê½µgP¥rPñÝäŒT(I] FîT+oÕ…±ˆ>:ç›NA};'éYÏÉž4€ÆÁÀóÂws;ù I«$=`ºõiàÒ¸^Ùѯ‡VwjY_»éÀ1#ËR'#w*fÛ¶öžÉëÊðŒéÔ·ýš{r»g:…;æïæJv:óº¤IO™îA}ÊÏõ‹íýŠ·HëV÷*™NÌ“;–wèÎåúÕ>Wå ò‘ûø´HêhcäÀïcY–±vm;:¢ÂlÙtêÛë’¾í9Ù1Ó!h< Ü0¯|7'ßÍm·Ó™«’^’Ä_šñ…ì>zYN\Òc÷õÉNÆLçæÉê•ZÑ—Ò–ý®*Ÿ¸K~~n´×ç­~›x¬UÇ[tø{d|iÿNÒÿà9Ù‚é4&îX¾›;h§3G%}GRÄtê“wmR?ßú‰V/OêŽ]¦sóäÞÛºÔÛÕ¦mÎWu7–Y²¹ðRvJûÎNëÒÍiÓ)¨ÿHÒ?÷œ,_€yÃÀ Æwsgìtf»æFîm¦{PŸf‹e½±{H#£Ú¸¦O­Q>/hÝÝêîŒkÇA¯ª'¹N1rà/…Ãa•#)í86ª™{d|)I?óœìôÝœé48îXP¾›óìtæuIßÔiºõëÈÙ›zïƒA=²¦G½]IÓ9€yðÀ]=ZÒÐöT±r bährÉdB§¯:᎛NAý•ô’çdß1€æÀÀ Îws7ítæeIÏJZbºõkd¼ ?ßrV‹Ra­½£W¡Ãh4÷ÝÑ­}¶¶æÜªGî²,µ3r4Kñd»v|<¦ÑÉYÓ1¨®¤g='{Ètšwỹ ;ùsIIºÓtêWHÛ^ÒÉþkʬíS2Ñj: p‹Ý{[—n_Ö®-ûÏ«\ÅÊ},(ÔÑÆÈÐb­Q]ŸnÕþÓc*WñÁ0àw8¬¹qûé4î0Æws…OŸä¾RÒƒ¦{Pß.ë—;Îií*[«–všÎÜbw¯êÒê•zo¿«r‹=?/•Fî€Æ—²SÚnFÞõ¼é4†w%}Ãs²Ã¦CÐ|¸À(ßÍ•ítæuÍýnú´éÔ·é™’^Ý9¨ÙÂŒÖßݧh /y ‘ܵ²SkoëÒ»û\•ª¹OKŲԙ`äh<ápXåHJ;Žj¦P6ƒÆðg’þÐs²Ó¦CМX{À8ßÍÉws;ìt护—$ñ×f|)ž¼.çÐym¼§GÝ Ó9€[èŽåZwg·Þù`H¥Rå#÷ñii¶$u1r4dòÿgïN£ä<ëí_µWwUWk_ì–TZ,KÞchÛ1Ì 6™œÉ2„$4 Ù“7É$!ó&L&u&¼y“aß8`¼Ëe[–Ê–wÙÚ¬¥¤Ò¾uWï[ÕûÁ!/a TËê¾»«¯ß¾ð?ç:‡öÁu?ÿç~2ìÀøDã»Wý#0ê’»$©)Dhɶ³éé^zÆBǨ9Œ?[)þ¦Z.…n‘$IÒç‚»$I’f”j¹´+—ï¼—–Ü[C÷hv›¨Õ¹³T¡|ø,Wm\B¦%:I’$I’tž¬ZžãªK–rûæŒOnÉ}xd#~BN’4+¥SIN §Øº³—Zã3‘~”>à•bá[¡C$I’$pÁ]’$I3Pµ\ªäòßÞÌÝ£Ùog¹‡ÛØÇåkrt,›:G’$I’tž¬XÚFçeËùÎæýŒŽ5¾ä>0Ãc°0Á~I’f“¶\[ŸáÐÉ¡Ð)j‡ë+Å–Ð!’$IÒ÷¸à.I’¤©Z.Éå;¿ t†îÑì×?4Æ×7í#àŠ‹–ûsH’$I’šÁ…‹³¼îò ¸}ó~FÆ&ž…¡QX˜uÉ]’4óÅb1j‰66=ÝÃÈhã/uI?ÆvàºJ±°'tˆ$I’ôýÜè$IÒŒU-—rùÎ/—„îQsØüôq¶<}˜Wo\ÌüöÖÐ9’$I’¤ó`ù¢ ×¼üBnx?ã“[rqÉ]’4³e³v¯óì¾Ð)j.÷7VŠ…“¡C$I’¤ä‚»$I’f´j¹4–Ëw~ˆ׆îQs8rj/ßµ‡KÒ\¼j·$I’$iÖ[º°•®+;¸}ó†FÆžƒþXä’»$iƉВmgÓÓ½ôô…ŽQsùÀàpãKîÃcÐ7 ‹Ú\r—$Í éT’SÃ)¶îì¥V]£&ó§@w¥Xhü³7’$IÒ4óˆN’$I³JGW÷5À7…¡[Ô<ÚZüõ}=7¼v]èI’$IÒyð|¥‡[~çvNœ™Ü¥¤í-.¹ J,:Ea’$5 -ׯæT¼µ]çÕðË•báÿ "I’$ý8Þ|)I’¤Y¥Z.Ìå;¿¼XºGÍat¬Æ¿om×yW~ øJ±0:F’$I:Þp)I’¤¦ÑÑÕ}9ð¯ÀªÐ-j>—¯]ÀÿøÈÕlX³$tŠ$I’$éêâÖß½]峓škMÂeÆHƧ(L’4gd3­ì9^cïÑÐ)jNÀOUŠ…ÛB‡H’$I/…×J’$©iTË¥¹|ç—«ŽÐ=j.'Îñå;÷° á’µ‹‰E½ºO’$I’f›Öt‚·_»–ž8ÌɳC ÏMÀ™: ³Qâþ”$“él;›¶÷qª::FÍé ð¦J±ð@èI’$é¥rÁ]’$IM¥Z. äò_Ö—…îQs©ÕëÜ÷ØÛq”«6,f^®%t’$I’$i’ZRqÞ~ÍzêÇÏ 6<7^sÉ]’tnZ[[8\óèî^jµzè5§­Àõ•ba_èI’$é|pÁ]’$IM§Z.çòÿ Ô7ÎQ:x|€/ݵ›ŽE)ÖçDB'I’$I’&!ŒóÎkײ噣=5ÐðÜx N÷ÿÛ’»OÙ$I?V„LÛ<ŠÏös¢g$tŒš×€÷TŠ…ÞÐ!’$IÒùâÑ›$I’šRµ\¢Z.sùÎÝÀÍ@]Ý7_ÚC·¨ù½æ²¥üÙ‡^ËE«…N‘$I’$ý'ÏñŸ~ÿ»ì80¹]³Öd„Ë.Œ’ŒOQ˜$iʤÓ)N &xrooèÍüq¥X¨‡‘$I’BòwI’$éûTË¥çsùÎoo‡îQs«œà‹w즽%Â%ky¥Ÿ$I’$ÍT™–ïêZË#ÏçÈÉþ†çÆ&àô@ù™( ŸÌIÒ,!ÓÖÎæ:9:Fsà ðÓ•báSÕr)t‹$I’œÇh’$IÒ¨–KgrùÎÏ ¡{ÔÜjõ:›?Ââå-`ñ‚lè$I’$IÒ‘JÆxW×ZžÝwšýGª Ï×àT_y­’q?°,I3Y¦µ…ÃÕ8ìêelÂK´5-ö7TŠ…ûB‡H’$I3… î’$IÒ‹¨–K£¹|ç?Àu¡{ÔüŽâKwí&«qéÚÅ$âþ\“$I’¤™(‹òök×rèx;öŸix®V‡“}ur-Ò —Ü%i¦‰F£$Zs·W9Ù;:GsÇw+ÅB9tˆ$I’4“¸1!I’$ýÕr©^-—Èå;ŸnR¡›ÔÜêuxð©cÜóH™—­Ï²Em¡“$I’$I/"‰pãkóô Œòø® ÏÕë/ÜäÞšŒÐštÉ]’fж¶,{ŽÃ“ûªÔ¼´]ÓçOÿR)C‡H’$I3 î’$IÒQ-—våòßÞ , Ý£æwªg˜/ß½jc\¾n1ÉDcÛž*µzèÍ=_ÞY)އ‘$I’f#Ü%I’¤—¨Z.Õ«åÒ½¹|çàm@"t“æŽ3Õ¾vï^NŸíãòu‹È´$C'I’$I’€lk’w^»–­Ûqìô@Ãscpº¿Î‚L”¸Oò$iÒb±(±tŽû·W9]müKÒyR>üz¥XðP’$I:G~àP’$I::ºº¯¾¬Ý¢¹'—Ið‰uò¶kÖóª?I’$Iš†FÆùÅ?½‡âã•IÍ%ãpéQ2)çIR£rmmé“4Gd2­íK°ug/ãµÐ9šÛþ¸µR,ô„‘$I’š™Ç^’$IÒ4ª–KÏäòß®ç…Ý¥iW99ÀîØcl\½tÊ÷-$I’$)„–Tœw¿aûTÙ}ðlÃsã58ÙW'—ŽJø….IÍ+IµQÜ^åDOã_¼¦ÀðÁJ±ð'Õri"tŒ$I’Ôì\p—$I’¦Yµ\:™Ëw~X \ºGsS½[¶Ÿà÷î!¿´…Õó‰F\Š$I’¤é‹EyÛÕ«›`ÛŽã ÏÕêp¢¯NK"B&åï9Iͧ-—ãñ£ì<ØO­ºFsÜ^à-•bỡC$I’¤¹ÂwI’$)€j¹4šËwþ3p¸ÿÝ\ sÛCežÞuŒ +ÛY¼ :I’$I’椫_~!ËfØôx…Ú$69O÷׉F"äZ\r—Ô2­-œHòðŽ^†F¼([Á}¸¹R,"I’$Í%.ÑH’$ITË%ªåÒ¶\¾óà-À¼ÐMš»öíç‹wí¦66†üBZÒ‰ÐI’$I’4ç\¾nW^¼„»JeFÇj Ïõ Õ‡™~œKÒl‹Åˆ·ä¸ÿÙ*ÇÏŽ„ΑF¿Q)†CÇH’$IsG\’$IÒ ÐÑÕ½ø,psèia.Åû/¯â¦kÖECçH’$IÒœ³óÀ>ð‡wräÔÀ¤ææµFذ9À—îÜÃ@ÿ W/ Ó’ $I’$IsF¦%Á»¯[ÇÎgØw¸·á¹± 8Õ_§½5B2îûó’f¦X,J¢5GñÙ~Žž#Œ¿üZ¥XðR’$I ÌwI’$i†©–KrùÎ/WùÀ9í:Å—îÜÅòyIÖ­\@,æ5€’$I’4ñ(ï¸v gûFxj÷Ɇç&jp²¯N&¡%é’»¤™%—kcûáÏìï£V«‡Î‘ÊÀM•b៫åRèI’$I¸à.I’$ÍHÕr©?—ïü®Ý#ŽÕ¸£tˆû-³qU;,Î…N’$I’¤9!‰ðÆ«VÐÖšä¡'Sop´^aÉ=‹Ð–vÉ]Rx--)ªc-<ðl/ýCã¡s¤ïù^Xnß:D’$IÒÿÏwI’$i†ª–Kµj¹to.ßùðV ºI:qv˜¯Üý<'NU¹lͲ™Tè$I’$Iš^¹a ò ¸ç‘ƒŒOÔž;;Xg¢ó2\s—B4%•ÉñàsTN …Α¾gø8ðÑJ±à¦$I’4ÃxŽ%I’$Í]Ý«^ºEúžt2Æþü+yÏ —NÆCçH’$IÒœðäî“üç?¾‹S=“ÛÅ[˜pñ²(QŸJšFm¹OìâØ™áÐ)Ò÷;ÜR)¶„‘$I’ôâ¼Á]’$IšªåRO.ßùY`„†o IDATðªÐ=ÀøD{¶æ»›÷³aEËÚC'I’$IRÓ[¶0Ãͯ_Mñ‰Ãœ©6¾0:4 g_XtE§0P’€L¦•cý ¶ìì¥hȃOTXwA† —¶‡N’$I’¤¦õÚË—³rYŽ{=H­Öørééþ»í­.¹Kš¼l¶•£} ¶ìì¥hø‰{8Ý;<©¹Åm.Z%ê“CI H§’ ÖÒlÝÑC­îíš‘Ž·VŠ…B‡H’$I:7Þà.I’$5j¹Ô›Ëw~¨×âˬšažÝßÃîØE´>κóhM'C'I’$IRÓéX’åækÖ°õ™£œ<;ÔðÜà(œ€ù™ñèJšÕ¢Ñ(éL;ï`ß±A\m× u7ðæJ±ð\èI’$IçÎwI’$©ITË¥Zµ\º?—ïܼ hÝ$}¿Z~æ8_»{7‹Ûã¬éX@ÜÍ I’$I:¯r™$ïyãEì?ÒËîƒ= ÏNÀɾ:¹t„TÂ÷æ%ýG¹\Ží•qžÞßÇØ„«íš‘jÀ¬ ý¡c$I’$½4.¸K’$IM¦Z.Ìå;? ¬6†î‘~ÐÐèw–*ܹek–gX¹¼HÄå I’$I:_ñ(7_½†x4ÂÖgŽ5|Ër­'úê$c²i§I‚l6ÃѾ[vöÒ?<:GúaŽï¬ Ÿ«–K¾!I’$5Ü%I’¤&T-—†rùίGyá6÷xà$éÿpº:Â7îßÇÓ{NpñÊvÏÏ„N’$I’¤¦ÒyÙr.[·ˆ{=ÈèX­á¹3uÆj0¿5‚ï#KsS:•d4𡏽ÊÉÞ‘Ð9Òrpc¥Xx.tˆ$I’¤óÇ#)I’$©Éutu_ |¸,t‹ôÃD"ðs7_Ì/½çå,[Ô:G’$I’šÊžƒ=üÜ»‹G«“ško‰°ay”„WfIsF4%ÕÚÆæçzñÆvÍhCÀÇ€OWŠom—$I’šŒÇQ’$IR“«–K'sùÎÏóWΑ~¨'vŸæsßÙI[:Âú• HºA!I’$IçÅÂö4ï½þ"¶ï=EùX_Ãs#ãpº¿N{K„dÜ{³¤f—ËåØ^çéýýŒM¸/¬í)àÍ•báŽj¹ºE’$IÒp[@’$IšªåÒxµ\º=—ï| x кIz1µ:›?Â×ïÛͪ¥­¬¾`ѨK’$I’ôR¥’1Þ}Ý:†Æxb׉†çÆkp¢Z§%¡5éï3©e³­íK°eg/ýÃÞÚ®ï“Àû+űÐ!’$I’¦Ž§P’$IÒÓÑÕ½øpmèéÇyÅúEüÑ/¾šWl¼ tŠ$I’$5¯ß·‡ßú›‡Ü"ëŠV-ŒNQ•¤é–N§OQÚÙC­îíšñލ w‡‘$I’4õ¼Á]’$IšcªåR5—ïü<0t>™ÖŒuìô _¾{ûŸeãªyÌÏùñI’$Iz©.Y½®+;¸o[…þ¡±†çªC00 2üØ–4{%âqbé66ïàÀñA\m×,ppS¥XØ:D’$IÒôðèI’$IšÃ:ºº_| XºEúq"øà».áçßy9˵…Α$I’¤YïÄ™A~ñÏîáñ'&5ךŒpÉQÒ‰) “4%¢Ñ(©Ö6¶ì¬Ò?4:GjÄð1àÓ•bÁw1$I’¤9ÄÜ%I’¤9¬Z.Êå;? ¬. Ý#ý8ÛvžäsßÙI*^g]Ç<Ò)·)$I’$é\eZ¼÷qäÔÏí;ÝðÜØœ¨Öɦ#¤Þ§%Í|Úrí<}pœgô3:^ $5â)àÍ•báŽj¹ºE’$IÒ4sÁ]’$IšãªåÒp.ßùu ܸ1¬m¢Vç'òÕ»w³¨-Æê æ‘HøóV’$I’ÎE,á-¯YE{6ÉCO¡Voì‚ÜZNôÕ‰Ç"´¥]r—fª\.ÇžðØóUG&BçHú$ðþJ±p,tˆ$I’¤0|ºR,øÇ+I’$ ðwI’$I?Dµ\ÚËw~XlÝ#5jÿÑ~¾|÷óDÝõ`Í.Oo® wTË¥Ð-’$I’fÜ%I’$ýPÕri —ïü*p¸H…-’·ã@Ÿ¿c½Õ.Z1\6:I’$I’f•×]qò ¸ïÑCŒ×ž;=Pg¢óZ#DÜs—¦D,%•ÉñÈóÃì><à­íš> ¼¿R, "I’$iæñHI’$IRC:ººóÀg€®°%Òä%bQ>zËåü§·^âî’$I’4I;œáçÿänë›ÔܼÖ–E‰{å–tÞD"2m9¶íéçTu4tŽt.ލ w‡‘$I’4syœ$I’$©!Õr©'—ïüPÞÄÃI«Õë<üÌq>wûNréë:æ“Lú',I’$IX4¯…÷\wO?ŠCÇ_rƒSýuæµFHļwKz©Úrmì>Qçñçû™#‹Û€›*ÅÂöÐ!’$I’f6Ü%I’$5¬Z.Õ«åÒ–\¾ó[Àkå¡›¤É¯qßcGøÒ]»X6?Åš çECgI’$IÒŒ—NÅy÷uëèíå©='ž¯Á‰¾:­©­I—Ü¥sÑÖ–åp5ÆÖUªã¡s¤s1t¯ ƒ¡c$I’$Í|.¸K’$Iš´j¹t"—ïüß@¸ð µf•á‘ ¾»å ߺÿyV,N³jy;Ѩ‹î’$I’ô£D#®»jËe(>~˜‰Z½¡¹zNõÕ‰D"´·x„ 5*“iáìHšÍ;z9Õ;:G:WOo® wTË¥Ð-’$I’f O$I’$½$]ݯ>¬ Ý"«µ¶óû?÷Jº®Ê{£»$I’$5à©='ù¥OÜKåDÿ¤æd"¬_%îO/é‡jI§èOòȮކ_$‘f ðß?ª #¡c$I’$Í..¸K’$IzÉ:ºº3À_ Ý"½—¬žÏoÿÌ•\så*b.ºK’$IÒÔÛ?B÷_ÞÏ}ÛMj.€ Ë£dS>ª”¾_K:Å`-EiWãã.¶kVÛ| R,xe»$I’¤s  I’$iö«–KcÕré;¹|çVàz -t“t.Nö óÍâ~ŠbÅâ4KÛ‰D\¸$I’¤“NÆy÷Ö‘ˆEÙºý(õ÷qÇkp¢Z'‹Mû›KJ§SLÄ2<´£ŸLJ¨ÕBIç¬üpK¥X8¸E’$IÒ,扑$I’¤óª£«{ð)à–Ð-ÒKõÚËó_oy9¯yÙJÝ%I’$éGØüÔ~õ/6qªghRsKÚ"¬]Åhi.J§’ŒÐÂÖ=Œ»Õ®Yoð³•báÁÐ!’$I’f?ŸÎK’$Iš]Ý·ò¢ûüÐ-ÒKõ†+—ñá÷^Á«._‰{î’$I’ôâNœäCÿý>yöؤæZ“6.Ò’œ¢0i†I§’ŒF^Xls±]MáSÀoVŠ…þÐ!’$I’šC,t€$I’¤æT-—¶çò_.Ö…î‘^ŠGûùÚ½{Ùþü1.\ÔÂKr¡“$I’$iÆÉ´$xïõ1<:Ác;7<76'úê¤2)ß*VóJ%hãá]ƒì;:ÈD­:Iz©ï­ S-—FCÇH’$Ij.¸K’$Iš2Õr©/—ïü"p¸HN’^’}Gúøê=ÏóìÞã¬XÒÊòÅ.ºK’$IÒ÷‹F"\ûŠ ¹tÍBî¬ÂÈØDCsõ:œî¯3Vƒy­¿ž¥¦’L&ˆ$ÛØ²{½.¶«yüð®J±°#tˆ$I’¤æãÑ$I’¤iÑÑÕ}ðy 3t‹t¾Üøš~õ}/ãe/"I’$I3ÎÁc}üÒ'î噽§&5זްay”T|ŠÂ¤i’L$¨'ZÙº³—¡‘Æ^öf£À/VŠ…ï„‘$I’Ô¼¼Á]’$IÒ´¨–KgrùÎÏ£Àµ@4l‘ôÒ=_©ò¥»ö°kÿIV/ϲda6t’$I’$ÍíÙï{ÓEœîfû$–ÜGÇáD_L2BKÒûº4û$qâé6¶îdÏáAÆ'¼±]Mã‹ÀÛ+ÅÂÓ¡C$I’$57O„$I’$M»Ž®î+yá6÷KB·HçÓͯ[ɇoy9—¬]:E’$I’f”oÜ÷<¿ó©‡ŸÔÜŠV.ŒúPS³B"'’ÊPÚÙËÀ°7¶«©œ>X)¾:D’$IÒÜà î’$I’¦]µ\:šËwþ#Ð ¼_¾U“Ø}¨—/ܱ‹½‡N³î‹ægB'I’$IÒŒpÉê¼å5«ØüÔÎVGž«Aß0ÌÏDˆù-8ÍP‰xœDKìfWe€±qolWSùðÖJ±ðXèI’$Is‡K$’$I’‚êèê~-ðÀ†Ð-ÒùöÖ×®äWßw—¯_:E’$I’f„á1>þ×ò¯î›Ô\2–EɵøxS3G<'žÊ°uW•þ¡É}@šÎ¿|¥R,øÖ†$I’¤iå î’$I’‚ª–K•\¾ó€(ðºûO©)ì©ôòÅ;wóäÎc¬XÒÊòÅ9"îbH’$IšÃ’ño»z5óÛR<ôÔjµÆv&'jp¢Z'¸ä®àâñ8©Ö6Ý;ÂÎCŒŽ×B'IçÛ·›*Å–j¹ºE’$IÒäé$I’¤££«ûJ^¸Íýe¡[¤©ðºË—òÑ[^Fç+ˆFýI.I’$in{b× >ôç÷qødÿ¤æf#\´4JÜWä5Íb±ÉÖ6ÙÕKï€7¶«)UŸñÖvI’$I!ù4]’$IÒŒÒÑÕ~ø 8GšW^¼ˆÝú2^å*â172$I’$Í]=}#tò~6m;4©¹t6,’Mù¸SS/KextOÕÅv5³»_¨ C‡H’$I’'>’$I’f¤Ž®îKyá6÷W‡n‘¦ÊåkæñÑ[_F×U«I%ã¡s$I’$)˜ÂWžà|éq&j_ÀšÅQ–µûÈSS#J2máÑ]½ ŒL„Α¦ÊðëÀ§½µ]’$IÒLái$I’¤«£«;|øS 8Gš2ëWäøØ­WðÆÎµ´¤ýp$I’¤¹é¡§Žðá¿ØÄ©ž¡IÍ-ÉEX·$JÔ'Ÿ:OZÒ)†j)J»z¯…Α¦ÒÀ® ûB‡H’$IÒ÷ó˜G’$IÒŒ×ÑÕ½ø®Ð-ÒTZµ,ËÇn½‚^»–¶L*tŽ$I’$M»ãgùПßǣϛÔ\k2ÂÆåQZ’S¦9!›iåÌpŒÇ÷ô2>áEÖjjCÀï])|‹C’$IÒŒ  I’$I?Nµ\:“Ëw~8Î Kî>®VSêí厭‡øÚ=»iKÁŠe9Ò)ot—$I’4wd[¼÷ú‹çñ'ž›€}uZ’Z“Þñ¥ÉikËpv$Éæ}>5LÍÝv5·{·VŠ…Û«å’í’$I’f$Ow$I’$Í*]Ý«€Oo Ý"MµLK‚_ÿ¼ëºõ,šŸ #I’$IÓêέe>öWEª£“š»`^„Õ‹¢D|ª#—kãÀ© vì£îš¯šßYàcÀg+Å‚ñ’$I’f4u$I’$Í:]Ýàg€ÿ Ì œ#M¹T"F÷û.å'oØÈ²Åm¡s$I’$iÚ<ÖÇ?qÛ÷žžÔ\[:†åQRñ) Ó,¡-ׯž£c<¤?tŒ4]¾ |¤R,"I’$IpÁ]’$IÒ¬ÕÑÕ½øð®Ð-ÒtˆÇ"üÂ;6òÓ7mdÕóCçH’$IÒ´¯ñ‰Ï<Â?ü˳Ô&qÍv< ë–FY”õ‘¨ ‰iËñì¡! #M— ðË•bá_C‡H’$IÒdÄBH’$IÒ¹ª–Ký¹|ç×€ç€7™°EÒÔªÕaÛΓüïoïàÀ‘³t,jeéÂlè,I’$IšR±h„®+;¸rÃ|ò0ƒÃã ÍÕêpª¿ÎÈ8ÌkuÏ}NŠÅb´fsl¯ŒóÔþ~ªýýH³\.yO¥Xx&tŒ$I’$M–Ç8’$I’šBGW÷"௟ Ý"M§×]¾Œ¿ï2^ó²•ÄcÑÐ9’$I’4¥Nõ ñkÿóîÛvhRs-I¸xY”lÊÇ£sE"'–ʰmO=ýc¡s¤é´øÅJ±°9tˆ$I’$+Op$I’$5•Ž®î·\ºEšNë;r|ì§^Îu¯ÊÓÚ’ #I’$ISênÛÎ'>ó(#£ ÏD"_åÂù>"mf©d’Z¼…Gvõ20ܸ߇ÔÆ€?>Q)FBÇH’$IÒKáé$I’¤¦ÓÑÕ=øKàçC·HÓmQ{š½ÿ ÞzõZÎ˄Α$I’¤)³ãÀ~åÿ¾={&57¯5Âú¥Q’ñ) S--)†kiJ»z«…Α¦ÛVà*ų¡C$I’$é|pÁ]’$IRÓêèê¾ø{`Uèiº¥R1>ü—ð®ëÖ³ê‚ù¡s$I’$iJŒŒNðG¿•/ܱƒz½ñ¹D .ZeAÆÇ¥³]6ÓJÏHŒm»{Ÿ˜ÄÔúßþW¥Xð“’$I’š†'6’$I’šZGWwøcà#@4pŽ4í¢Qøé·¬ãÖ.æòõËCçH’$IÒ”¸kk™äLuxRsËçEX½(JÔ§¦³N.ׯ¡35¶¨Nê婉Ü|¨R, "I’$Iç›G5’$I’愎®îWŸ^ºE å-¯¾Ÿ{ûF:¯XI,æû’$I’šËñ3ƒ|ä“÷³ù©#“škMFذî{ô ²q.\š#÷h@’$IRsȶ$xÏ/"ŠQÚ~ŒZ­±½Ï± 8^­FhK»ä>¥SI¢©,OáÙòÕñÐIR(ŸÞQ)­–K¡[$I’$iÊxB#I’$iÎéèê^üpKè)¤%óÒ|ôÖ+xÛÕëX0¯5tŽ$I’$7Oï9ůþÅ&öéÔÜ‚L„‹–FIø.ðŒÍ´Ò;gÛîÆ&¼¨ZsÚ~àƒ•báîÐ!’$I’4\p—$I’4gutußü-°&t‹R2ã—ß} ï»ábV.Ÿ:G’$I’΋Ááq~ïmæë÷í¡>‰Ýèd Ö/‹2¯ÕG©aDÈå²”OOð\¹oRÿÛIM¨Æ uü_•ba tŒ$I’$MOe$I’$Íi]Ý-Àï¿$çHAE"ðŽkVós7oà/ ñØ@’$IÒìwÛ{ùí¿ÝLu`tRsÎ_ÅŸFÓ#‹‘nͲýà‡O …Αf‚§€_¨ ÛB‡H’$IÒtó8F’$I’€Ž®îK€¿® Ý"ÍóóøÈO^ήZM¦5:G’$I’^’ʉ~ºÿr>w|RsÙT„‹—EiñgÑ”I§’Ôb-l{¾êÀXèi&þød¥Xð I’$IsR,t€$I’$ÍÕréd.ßù  \ ´†-’Â:Õ3Ì·7ä³ß~–hd‚å [ÉeÓ¡³$I’$éœä2IÞ÷¦õD"¶=wœZ½ÞÐÜè¯ÖIÆ#dSÞv>e³­ ÖÒ<¼{€½G‡«…N’f‚"pS¥X¸­Z.ù…$I’¤9ËSI’$Iú]Ý‹€¿~6pŠ4cD£ðž7¬æ§oÜÀ+6^@$â‘‚$I’¤ÙéÑçŽÓýÉû©ï›ÔÜ¢l„uK£Ä£S6'Dh˵qàä8;õÑà{Ò\pøuà •bÁ2$I’$Íy>–$I’¤¢£«» ø;`Cèi&¹bí~å½—ÑõÊUdZS¡s$I’$iÒúÇøÍ¿yˆÛØ;©¹TÖ/‹ÒÞâcÖɈÅb¤3Y¶äðéáÐ9ÒLRþøƒJ±Ð:F’$I’f O^$I’$éGèèêN~p“Wú>óÛR|ø½—rÓë×бl^èI’$Iš´ºg7ðé-ôMjnÅ‚+DñãV?Z:b"šæÑÝUú‡ÆCçH3ÍVà—+Å¡C$IúÿØ»ó(9ìúÌ×oïÝên©µo¥Å²eYÆà ³xIAÀ,Á„˜“&Ã@–JÈÍ„IHÈN’É$Ê “›äÎdc’™Áž f± ll¼`dclY²­’dmÖ¾µZÝóG LÉ–ôëåyÎéSî–ëðç ŽªÞþ6Œ7^r8 •jí¼´®)½¬t Œ7ííÉ[_znÞríù¹ä‚Ei³ð&G¶ìÍOý盲æ¡í§ô¼ÁÞ¶¬ZОޮ36 ôç‰Cíùʺ=+ãÍÎ$ïKòWÍF}´t Àxäg€“T©ÖÚ’¼%ɇ“Ì/œãÒ«çä]¯¹0×\¾<ý}Ý¥sNÊȱÑüþ_ß?ûø½;ùAvG{rÞ¼öÌô¶kGGGzûòà¦ÃÙðøÁÒ90%ùó$¿ÔlÔw–ŽϼÒpŠ*ÕÚP’&ywü½ þU³gôä'_ÿ¬¼òê©Ì*pRn]³9ïýP#[v8¥çÍl˹óÚÓÑ~†ÂƱþi}94Ú»Ú“‡•Îñê+IÞÓlÔï(0bšäâÒ-0^µ·'ozñ¹yû+Vå’ ¦­ÍKÀø¶÷Àp>ðÑ/å7­Ë)sOOg²r~{†¦Mþ¿÷´µµe`p0íÉÚÇöÒO0ÅìNòþ$m6ê¾à$MþWWΠJµÖ™äg’üz’þÂ90®¿tF~ò åÅW,ÏÌé}¥s¾§o4ÿéOnÉö]‡Néy g´eùœÉyͽ··'£½Y³~vî.ãÝKò ÍF}[选ÆÀà4¨TkK’ü—$o.Ýã]wgG~ô‡Væõ/>/Ï:oAuÆ«ÝûŽä—>rk>õÅõ§ô¼Þ®Ö5÷}“ã/<Ó³ußX֬ߛ‘cεÃ÷q_’Ÿh6ê·”˜¨&Ç+*ãD¥Z{Q’z’gN á9çÎÊ»_wa~àòå™1Ø[:à_uý-òËzkvî9|JÏ[4ÔºæÞ>ß•íêêLwo¾öØ¡lÚqjWìaŠÚ—äW“üq³Q)0‘MÀ—RÆ·JµÖ™äÝI~3ÉPá˜z»;òã?|A~øšY}îüÒ9ßaÇîCùÅ?¹5ÿç¶GNéy}ÝÉùóÛ3Ø;1Þš˜–½G:ó•u{sxøXé˜(þ>ÉÏ7õÍ¥C&ƒ‰ñ* ÀT©Öæ$ù­$ÁI{Þ…sóã¯^«/[šÁ~WÝ€ñå“7¯Ë>z[vï;rJÏ«ÌlËÒÙãóš{{{{ú³îñá<´ié˜H¾žä'›úçK‡L&ãðå€É¥R­]–ä“\Yº&’þ¾®¼ë5äUW­Èªsæ–ÎxÒ¶'æþø‹ùÜOéyÓŽ_s'×ܱ5F1 IDAT§õõf8=ùÊÃû²÷ÀÑÒ90‘LòI>ÔlÔ‡KÇL6ãã•€I®R­µ%y[’ßO²°pL8×\2??öC«så%KÒ?­§t@’ä>û`~íÏoϾ'¿omKR™Õ–¥³ÚÓVäÝÚ¶LŸ>˜æ®cùÚ†}+Ù'“ül³Q¬tÀdeàpUªµÁ$ïOòsIº çÀ„34Ðw¿vu^~å99oéœÒ9Ù¼ã@~þ¾/޳锞×ßÓ–óç·¥¿çì¼eÛÛÓ¶®i¹÷‘ÙºëðYùÏ„Iæá$?ÝlÔÿ¥tÀdgàP@¥Z[™äÃI~¨t LT×^±(ÿö«ò‚‹—fZ¯ïÊú›ùz~û/¿œý‡ŽžôsÚÚ’¥³ÚS™ÙvF®¹·µµepp0[væ¾Göfä˜kíð4IòÁ$ÿ¹Ù¨ûÀÀ  Jµöª´†îç•n‰jÆ@wÞýº óò,ÏÊe®ºå4·îËÏ}ø ¹í¾-§ô¼ž¶œ¿ -ÓºOÏÛ·ýý}92Ú5ë÷e×þ“Üßá%ù¹f£þp逩ÄÀ °JµÖ“äg“üJ’þÂ90¡]¾jnÞùêU¹úÒ¥™5cZé`ŠúËÿu~÷¿Ý™CGFNú9mmɲÙíY<³íi½‰ÛÙÙ™ÞiýY¿u8mÚŸ1ÇÚá™øZ’Ÿm6êŸ+0¸Œ•jmq’ßKòöÒ-0Ñuv´åß¼ô¼¼¶º"—]¸(]¥“€)fÃæ=ù¹}!w=°õ”ž7ØÛ–óç·§¯û$ÿýÁì>Ô–{Þ—ÃÃÇžF)ð-v$ùå$ÑlÔOþ;T8­ ÜÆ™Jµvu’?NrIé˜ ÎêË»^{a^ò¼¥9§2»t0…Œ%ÿõ“÷å÷ÿæ®9…ñy{[²|N{ ýëoçööt§­kZÖ>v ›v>]¹0•MòGI~«Ù¨ï)0Õ¸ŒC•j­#É'ùí$¹pš\sñ‚üÈ+Wå…W2c°¯t0E<´qwÞû‡¬yhû)=oz_ëš{oWÒÖÖ–ÁlÙ=–û6ìͱѱ3T SÎÿLòóÍF}]éZ ÜƱJµ6+Éo$yO’öÂ90iôtuäG^¹2×]sN.>a::üÏ 8³ŽŽå#ÿ¸&þØ=>zò×Ü;ÚÛ²bÁ´ìØ;œ]ûžÁB˜rîKòÞf£þ¹Ò!|;w€  R­='I=Iµt L6Ë ä]¯½0/zîÒ,Y0T:˜ä¾þÈùÙ?läþõ;K§ÀTµ=É/'ù‹f£~òßmÀYcà0ATªµ¶$oJò{I–—­Ééϯäß\»2/xÎ’ôOë.LR#ÇFóG»'ÿï?®ÉÈÈhé˜*Ž&ùp’ßn6ê{JÇðݸL0•j­7ÉO¥uijFᘔúûºòï®[•W\¹<7?mm^BN¿ûÖíÈOþ盲a³­-œaÿœä?6õu¥Cøþ¼; 0AUªµÙI>ä'’tÎIë‚¥3òŽW­ÊÕ—.ɲE3Kç“ÀþƒGó¿¿´!Ÿ¸i]n¿oKŽŽ•N‚ÉêÞ$ïm6êŸ/ÀÉ3p˜à*ÕÚÊ$¿›äõ¥[`²»úâùyëKWæW2oÖ@é`ÍçïÚ˜OÜ´.Ÿ»sc”N‚Él{’÷'ùËf£~¬t §ÆÀ`’¨TkW'ùƒ$Ï+Ý“]{{rÝ•Ëòú­È-ÎôÞÒIÀ8uÇýç“7¯Ëõ·lÈî}GJçÀd7œäÃI>ØlÔ÷”Žàé1p˜D*ÕZ[’7§uÑ}yÙ˜zº:òÖkÏÍ«®ZžK.X”ÞžÎÒI@a=¶;Ÿ¸é¡üóÖ§¹u_é˜*>™ä?6õ‡K‡ð̸LB•j­'ÉO'ùå$3 çÀ”14Гw¼êü\û¼¥yÖÊéh÷Ò L[Ÿ8˜ÿÙx8Ÿ¸i]ÖnØ™±±ÒE0e¬IòÞf£~SéNï²Lb•jmv’_Iò“Iœ•†³¨2¯?ÿîº R½|IV.›S:8ö:šÿ}ë†|ò¦u¹í¾-96jÕgѶ$ïOòWÍFýXéNw€) R­­Lò;IÞPº¦¢g¯˜™}Õª\}É’,žï‡*ÀD622š›îÞ˜OÜ´.Ÿ½cc”N‚©f8ɇ’|°Ù¨ï-Àégà0…Tªµ«’üA’ç—n©êÅ—.Ê[®=//xÎâÌê/œ¤;×>žOÜ´.7ܲ!»ö)SÕ?$ù¥f£þpéÎw€)¦R­µ%ys’ßM²¼l L]ímyÍ,Ïëª+rÙê…™>Ð[: xŠÛ•¾ùá|²ñpš[÷•ΩìóIÞ×lÔï*À™gà0EUªµž$?•ä—“ Î)­§«=oüÁyùó—æ²Õ 3c°¯tLY_ä‰\ˆÜpˆ¬kî.SÝW“¼/ÉgšúXéÎw€)®R­ÍNkäþ“Iº çÀ”×ÓÕž×ýÀò¼òÊe¹lõ¢ M7v€3í'GíëópsOé ÙäýIþG³Q-ÀÙeà@’¤R­—äw“¼¡t ÐÒÕÑž×üÀ²üЕËòÜ eæŒi¥“`ÒX»á‰\ËúÜpˆ¬ßdÔãÄö$¿™ä£ÍF}¸t e¸ðm*ÕÚUIþ ÉóK·'t¶·çº«–äÕW/ÏåÏZ”ÙCý¥“`ÂùÚÃ;sÃ-ësídÃf£vG$ù/Iþ Ù¨ï+@Yî|‡JµÖ–äµI~+É……s€§hoO~è…KóškÎÉsŸµ(sf»ÀwsßÃ;rÃ-rÃ-òÈ–½¥s€o7’ä£I~³Ù¨o-Àø`àÀwU©Ö:’¼=ɯ'Y^¶ø×´·'/»¢’×UW䊋eî¬ÒIPÜ}ëväú[6ä†[7äQ£v¯>–äWšúºÒ!Œ/î|_•j­;É¿Oò+IæÎ¾‹¶¶ä/_”7¾øÜ<ï¢Å™7ÛØ€©ãÞ‡väú[Öç†[7ä±Ç÷•ξ»Ï$ùÅf£~wéÆ'wNZ¥ZëOòSIÞ—dfáà{hkK®¾xaÞò’ssÙêY²`¨tœv_}p{®¿e}þ÷­dãV£vç¾’ä?5õÏ”`|3pà”Uªµ¡$?Ÿäg“ôÎNÂ¥+çäM?xNž{ႜÎÜt´·—N€Svtd4·®Ùœ¿üh>{ÇcÙ²ã@é$àû{8Éû“üc³Q-ÀøgàÀÓV©Öæ'ùÅ$ïIÒ]88IKçäÍ/Y‘+Ÿ½0­\¾Þ®ÒIð]íÙ$Ÿ»scn¼ýÑ4îifÿÁ£¥“€“³-Éo$ùóf£>\:€‰ÃÀ€g¬R­-Kò$ïHâ,4L ý}yËÎÉKž[ÉÅ«döÊ@y·î˧o47Þþhî\»5#Ç}† d’ÿ’ä›ú¾Ò1L<îœ6•jí‚$¿žäÍ¥[€S×Þž¼ô¹‹óª«–åò dÙâY¥“˜B¾úàöÜxû£¹ñËæÁÇvel¬tpŠŽ&ù³$¿ÕlÔ·•Ž`â2pà´«Tk—&ùí$¯,Ý<},Ê¿yɹyÁseÕ9sÓÙá4pú =–/~us>óåGó™;˶'–Nž¾¿Kò+ÍF}}é&>wΘJµvM’&¹ºt ðÌ̜ޓ·¾ô¼¼èòÅyÎÊéŸÖ]: € h×¾#ùìåÆÛÍïÙ”‡–Nž™O'ùÅf£~Oé&wΨJµÖ–äi]t¿´pptu¶çÕW-Ë+¯\šË.Xy³K'0Žmؼ'7ÞþXnüò£¹û­96:V: xæ>“äW›úm¥C˜| Ü8+*ÕZ{’7$ùÍ$« ç§ÑÅ+gçõÕsòÜ çç‚s榻«³tÍÝlËçïÚ˜o4oÚ1›v˜,>ŸÖ°ý–Ò!L^îœU•j­3É$ùµ$KÊÖ§ÛôiÝyý‹–çšKæ¢óæeѼ¥“8 6ï8›îÚ˜›ïnæÖ{7gßáÒIÀéÕHkØÞ(Àägà@•j­'ÉHòþ$ó çg@[[òÜ æäº«–åÒUó²zżôöt•Îà48:2šÛïÛ’›înææ¯l̺®´Ã$uK’4õ›J‡0u¸PT¥ZëOòî$¿Cw˜Ôúû:óÚ«—å.]”gŸ??K •Nà<²eon¾»™›ïÞ˜ÛîÛ’ƒ‡GJ'gÎmI>äsÍFÝ·¯pV¸0.TªµiIÞ•ä}IÎ΂ – åõÕå¹â¹ðÜy™Ö×]: €oqèÈHn]³97¥™ÆÝÍ<²eoé$àÌûr’_Mr£a;¥¸0®Tªµ¾$?žä?%YT88Kº;;òÊTríó–ä’Uó³lñÌÒISÒƒí:~¥½™;Ö>ž#ÃÇJ'gÇ]i ÛÿŰ€Ò Ü—*ÕZo’w&ùÅ$•Â9ÀYV™×Ÿ7¾xE®zά^173ûJ'LJûÍ¿ºéø¨}c6ï8P: 8»îIkØ~½a;ã…;ãZ¥ZëIòŽ$¿”diÙ „¶¶äy«ç凮\šKWÍ˪ås2­¯»tÀ„4:6–{Ú‘[ÖlÎMwmÌW¾±-##£¥³€³oM’_Kò? Ûo ܘ*ÕZw’Iòþ$ËËÖ%uw¶çÚçUòâËå¢sçä¼¥sÒÓÝY: `Üzà‘'rëšÍùҚ͹ýþdzïÀpé$ œ¯¥u±ýŸ›ºïn`\2p`B©Tk]IþmZC÷s çãÀÐ@W®»jY^xÑü\pΜœ»dv::ÚKg³~ÓžÜzokÐ~Û}[²sÏáÒI@ykÓºØþqÃvÆ;w&¤JµÖ™ämI~9ÉÊÂ9À82w¨7?|õҼࢅ¹àœÙY¶hVÚ¼ Lb›¶ïÏ­k6·®´ß»%ïx_¾hf::ÚKg“؎݇r×[sÇý[sçÚÇóµõ;322Z: ˜¾œäƒI®o6êþà`R0p`R;>tu’_Mriá`š=½'¯xa%Ï¿p~V-›•Kf§·§«t0­ß´'w®Ýš;î¶ëÉëì_}p{xô‰ŒŒŒ–N¦®;’|0ɧšº?Œà) ÜàTªµË“üB’7&i/œ¶¶dÕÒ¡T/]˜gŸ;;+eÉ‚šÞW: ŠhnÛü*û¶¬ypG¾öðŽì?ä020.|.­aûMÍFÝÏŒ€ïÂÀž†Jµv^’ÿ'É%é)œð–-HõÒ…¹ø¼9Y±xF–,œ‘ù³KgÀi36–lؼ'÷¯ß™µëwfí†'rïºÙ±ûPé4€§úd’ßi6êw–€‰ÀÀžJµ6?I-ÉO$*œð=͛ٛ]º0—¬œ“•Y²`FÏ›‘Ž?€ñíððHØðDî_ÿD֮ߙû7ìÌ×y"”NønŽ&ùû$¿×lÔ×–Ž€‰ÄÀNƒJµ6˜ä]IÞ›dqဓ6Ôß•k.Y˜KÏŸ“ó*­Kï•ùCéíé,Àµ}סܿ~ç“k7ìÌ#›÷æØèXé4€“ñD’?Kò'ÍF}s阈 Üà4ªTkÝIÞ–ä’¬.œð´t¶·çòÕsòügÍÏ…ËgæœÅ3²hÞô ö•N`ËÃÍ=­‹ìOŽÙŸÈŽÝ‡J§<ßHòá$ÿ½Ù¨,™;œ•j­=ÉË’üL’WÎ8-æ õåÊ‹æå9+gçÜÅ3R™?˜Es§gú@oé4ƹ‡æ O³?‘û×ï̃íÊ¡##¥Óž©Ï%ùP’i6꣥c`20p€3¬R­­NòÓI~4É´Â9§]en®|öü¶;=¶+[vÈØXé:€Óf8Éß%ùp³Q_S:&w8K*ÕÚÌ$?žÖØ}Iá€3ª½=9oñô<ÿYó²zùÌ,[0=‹æ fѼé™ÖÛ]:€ghçžÃyhckÈþàc»òÐÆÝyhãîlßuИÌv&ùH’4õÇKÇÀdeàgY¥ZëLòº$?“äªÂ9gUgG[.Z1+—¯š•K†²láô,ž7= 禷§«tO±õ‰ƒO^d_·qwܸ+ë6îÎÎ=‡K§œM$ùP’¿i6ê‡JÇÀdgàUªµ+Òº¿%Igá€bÚÚ’¥órùê9¹`éÌ,[8˜…s2væÍHggGéD€I­¹mú–Kìßü罆K§”ô™$˜äÆf£>Z:¦ w*ÕÚ¢$ïIòî$s çŒ+ímY½|(—®œ“ó–ÌÈÒùƒ™?§?óg dÎÌþ´·{™àdlÙq lÙ›G6ïm=nÙ›G6ïÉ£[öåÀᣥóÆ‹á$“äÃÍFý¾Ò10yçÆ‘JµÖ—ä­I~6ɳ çŒ{½=¹tåœ<ûÜ™Y±hz*ó[WßgdÖŒi¥óΪ±±dÓ¶}ÙðäxýÄãcïËáá‘Ò‰ãÙö$Iò§ÍF}ké˜Ê Ü`ªTkmI^”ÖÐýÕñwx€S6{zO.[5'«ÏÊòÓ³pNæ Mˬ¡i™=cZ::ÚK'œ²c£cinÝ÷—Ø7lÞ“[÷gøè±Ò‰ÍýI>”äo›úáÒ1€7Ç`Ü«Tkç&ùé$ïL2X8`RèìhËy•¹ðœ™Y±h0•y™7kZæÀãÀî}G²iûþlÞ¾?·îφÍ{ž´7·ïÏÈÈhéD€Éàÿ¤5lÿL³Q+œ`àD¥Z›žäÇ’Ô’¬(œ0©}Û~ñ`*s2Vkø>{¨õa<#ÇFóøŽÙ´ý@šÛZ#öMßò±yÛ8|´t&Àdu$É_'ùp³Q¿¿t ð¯3p€ ¦R­u$¹.ÉÏ$yqá€)©«£=ç.™ž —eÅ¢é©Ìm]€Ÿ3Ô—ƒ½™1Ø—þ¾îÒ™@{ gÓöý­ñú¶o×dÓ¶}Ù´ý@¶ï:˜c£œe›’|4ÉG›ú¶Ò1À÷fàX¥Z»8­‹îoOÒS8€o1£¿;ç/‘å S™×Ÿù3û2g¨/3§÷fh°7Cƒ}šÞ—ҩÀIÚµïH¶ï:˜­OÌö]‡²yÇlÞ¶?Ííû³iÛþlÞ±?ûº¾0Ž|6ÉG’|ªÙ¨”ŽNŽ;L•jmv’Mòî$+ çp’ÚÚ’yC}Y¹dF–/È¢¹ý™?kZæÌèÍÌé½™1Л¡é}™1Ø—Žv/ç™ptd4Ûv̶ã£õ­»Z­!{ëqÛ³}÷¡- À÷·'É_%ù³f£þÒ1À©óŽL"•j­=É‹“¼'Ék“8 0 t´·eñÜi9ÉP–.ȼ¡¾ÌšÞ“¡Áž öwg°¿;Óz20­;ƒÓz2­¯»t2·gÿ‘l{âP¶¬oÛuðøýøxýø×÷ì?’±±Òµœ_Iò'I>ÖlÔ–Žž>w˜¤*ÕÚ¢$ïLò®$K çpõuwdé‚,ž7…³ú2w¨/³g´ñ3z28­;ƒýÇñý=˜Ö“vâ§FŽf÷¾#Ùµ÷Hvï?œ]{d×¾#­¯íûæç‡~$»öή}G2|ôXétμ#I>–ä#Iîl6ê¾e &ïXÀ$W©Ö:“¼2É»?z=€oÓÖ–ÌžÞ›¥ ²hNæÏêËÌÁžÌèÎà´®ô÷v¦¿¯+}=]éëíl=öt¥··+Óz»ÒÓÝYú·Àptd4ûÍÞý'†è»÷yr þähýø@½õùá8tÔ…užêá$šäÿo6ê;Kǧ—7´` ©Tkç$ù÷Iþ]’y…s˜$zz:2o¨/s‡z3{zofMïÎŒîã×â»28­ûøH¾;}½™ÖÛ•¾žÎtuu¤«³#ÝÇ{º;ÓÝÕQú·ÃqccÉCG³ÿÐpö:ÚúçƒÇÍþƒ­¯?õ×:šƒ‡Gràðð“_ß{p8ÃGGKÿ–˜ØF“\ŸÖµöÏ4uÿÇ“”;LA•j­;Éë’¼'Iµp<©»³-CƒÝèÉôþ®ô÷v¥¿¯3}½éïéJoOG¦õv¦·«#½=ééîHOWGzº[CùîÎÎtu¶·Fó]éhoK{{[ÚÛŽ?¶·¥½½=íím­_;þõŽŽöt´·¥£½=ßùØÙÑ~Ú¯ccÉèØXÆFÇ2–dtt,£ccÇ¿–Œ}óóÖ¯9z,ÃGåÈðñÇãŸm}m䨓ßüõ£GG3|ôXŽŽŒæèHëß=:ò­Ïoýú¡áÖs÷ÎîÃÙw`8‡ŽŒ¸œÀx°-Éÿ—ä¿6õGKÇgž;Lq•jmu’ÿäIf”­€ñ«½­íɱû7;àGÇÆ’¦·þ)c£myò³±´†ìm­±zÒ–Ñc£˱cc96jIOñÅ´®µ¢Ù¨—ŽÎw IR©Ö¦%yK’w'y^ᦞýIþ:ÉŸ6õûJÇe¸ß¡R­]žÖU÷·'™V8€Éíþ$’äošú¾Ò1@YîÀwU©Öf$ù·IÞ“äY…s˜<Ž&ùx’$¹¥ËöûIDATÙ¨îÆ wàûªTkmI®Jòî$oJÒ]¶€ j}’¿LòÍFýñÒ1Àøcàœ’Jµ67ÉÛ“¼3ɳ ç0þNòOIþ"Éšúhá`3pž–ãWÝ/Kkèþ¶$Ce‹gîLkÔþ±f£¾§t 01¸ÏX¥ZëMòš$?–äeñšÀTµ#É_'ù«f£~_é`âñf3pZUªµ%I~$­±û¹…s8óF“|:­kíŸj6êÃ…{€ ÌÀ8#*ÕZ[’kÒº¿9É´²Eœf'ùË$ÿ½Ù¨7KÇ“ƒ;pÆUªµÁ$oJkì~uáž¾CIþ1­aû›úhá`’1pΪJµv~’w$ùÑ$‹ÊÖp’¾œÖ¨ý4õ=¥c€ÉËÀ(¢R­u$¹6É;“¼&IwÙ"žbG’ÿžä¯šú×JÇSƒ;P\¥Z›ämI~,É¥…s¦²Ñ$ÿ’Öµöë›úpá`Š1pÆ•JµvIZC÷·'™]8`ªX—Ö¨ý¿5õÍ¥c€©ËÀ—*ÕZO’ë’¼3ÉË“t”-˜t$ùx’¿HòÅf£>V¸ÀÀÿ*ÕÚ¼$oNò¶$/,œ0‘$ùt’¿Mò¿šúÂ=߯À˜P*ÕÚŠ$oMòö$« çL_JkÔþÍF}Gé€ïÆÀ˜*ÕZ[’‹ÓºêþÖ$•²EãÎiÚÿ®Ù¨o(p2 Ü€ ¯R­µ'¹&­±û›’Ì,[PÌæ$ŸÖ°ý«ÍF}¬pÀ)1p&•JµÖ“äåiÝ_“¤·lÀ·7É?¥5jo4õc…{ž6w`ÒªTkƒI^›äíI^š¤£lÀi3œä†´Fí74õÃ…{N w`J¨Tkó“¼)­±û ç<cIiÚ?ÞlÔwî8í Ü€)§R­­Hò¶´ÆîÎø~Ö¤5jÿûf£Þ,p&¸SV¥ZkKrqZC÷·&Y\¶àI&ù»$ÛlÔï/p¶¸$©TkíI®IkìþÆ$3ËSÐIþ!­kí_j6ꣅ{Î:w€§¨Tk]I^”ÖÐýuIæ &³ÝIþ9ÉÇ“ÜØlÔ‡ ÷eàð=TªµŽ´.»¿1Éë“,,[L;’|2­QûMFí'¸œ¤JµÖžä…IÞÖà}IÙ"`ÙšäIþ)ÉšúHá€qÉÀài¨TkmI®È‰±ûвEÀ8´)­+íÿ”äKÍFýXá€qÏÀà:>v¿$'Æî«Ê=š£ö/7õÑÂ=Š;Àit|ì~aZC÷7&¹¨lp<œÖ ýŸ’ÜÝlÔÇ ÷LXîgP¥Z[•Öe÷7$¹¬ppú|#'FíkŒÚNw€³¤R­­È‰±ûó ç§îk91j_kÔpú¸P©Ö–&y}Zc÷«âu¯îIkÐþñf£þÒ1“7N «Tk “¼*É«“\›¤¯lLywæÄ¨ýáÒ1S‰;À8R©Öú’ü`Zc÷ë’,.[SÂá$ŸMò©$74õM…{¦,w€qªR­µ%¹4­¡û«“<·lL*›“\ŸÖ¨ýóÍFý`ábà0aTªµEI^•ÖØý¥IúÊÀ„swZƒöO%¹§Ù¨îà) Ü& JµÖ—ä%iݯK²¨lŒK‡’|6­Aû ÍF}sá¾w€ ®R­µ%¹4­±û«“\^¶ŠÚœÖ ýú$Ÿo6ê ÷p Ü&™Jµ¶8ɫһ¿4IoÙ"8ãîJkÐþ©$÷4õ±Â=ßr¡½Ù¨?R6Nw¦”Jµ6/É Ò»¿0Éó’ôøÞŽ&¹'ÉíÇ?¾ØlÔ›e“àÌ0p`J«Tk]Iž“o¿ò¾¼d0åm̉1ûmIîi6ê‡Ë&ÀÙaàOQ©ÖæÄ…÷+“\ž¤§h0YNrWN Úoo6ê›Ê&@9îð}Tªµž$—äÄ…÷+“,.LTësâ2ûíIîm6êÃe“`ü0p€§¡R­-É·_y¿4IWÑ(`¼9䎜´¹Ù¨o+›ã›;œ•j­/Éei Þ/?þ±²hp¶}=­1û7í÷7õce“`b1p€3¤R­ÍHë²ûåßòq~Ñ(àtÙÖuöÛÒ´ßÑlÔŸ(›Ÿ;œE•jmz’Kþo;÷ºE€qü)Å3A€“X5ˆ'â%ÌÍÅÌ͈š€‰âʼnXËAPÖ†úa·Ùív[Zmû¶»¿_òf¦;ýð¤»ÿL¶FïWãupœ­$ù*É×I®ÏÏ}×n]3È—fPXU7KÙ½ÿ¿€~ÊÖýë¾kï]sÄdp Uus&Ó£÷S%wÀ ÙHòCÆBö böûEWÀœ¸À QÕÍÙ½Ñ;¼Èz’›Ù³Ûwí_EWÛÜàFï_&¹6qΗÜ=KòmF!ûõ$7ú®ý»è*`Oî0cªºYHr)ƒÐý‹Œ¢÷Ï’¼Zp´Õ ÞÌþMFogÿ¾ïÚõ¢«€ÿLàs¢ª›Å$ekôþE’+INœ/r?ƒýÆðz3É;kW‹®œÀæ\U7¯%ù4£ð}óú^É]Ì¥?2°•¾k7JކÀ˜ªª› I>ÏÖ·½_Kr®ä.fŸ™²ÿ*d€ù&pö¬ª›… Þì~-ƒøýãṚäbÁiO“|—A¼~#£½²ÓÜ€QÕÍÙ$W2 ÞÇã÷3§pø&¹•Q̾yn÷]û¼ä0àd¸‡jøÖ÷‹™¾˜ät¹uìÃfÄþãÄõV’{ÞÈ;PLU7/%YÎöðýã$—Ë-˜[2ŠÖœ¸¿+b›À8–ªºYJr%[Ã÷«I>Hr¡à4€“n3bŸ ØoEÄ&pNœªnÎ&y?ƒ·¿/g½/óE†“ûxÌ.bŽ-;0sªº9—Ýø7‹ 88¿'¹=½ïÚÿû÷8 ÿ—€jÉãG-bIEND®B`‚luerl-1.2.3/examples/0000775000175000017500000000000014677012037015045 5ustar debalancedebalanceluerl-1.2.3/examples/hello/0000775000175000017500000000000014677012037016150 5ustar debalancedebalanceluerl-1.2.3/examples/hello/hello2-5.lua0000664000175000017500000000024014677012037020176 0ustar debalancedebalance-- File : hello2-5.lua -- Purpose : Demonstration of Luerl interface. -- See : ./examples/hello/hello2.erl print ("(26) hello2-5.lua talking. a: " .. a)luerl-1.2.3/examples/hello/hello.lua0000664000175000017500000000021614677012037017755 0ustar debalancedebalance-- File : hello.lua -- Purpose : Brief demonstration of Luerl basics - execution of a file. -- See : ./hello.erl print("Hello, File!")luerl-1.2.3/examples/hello/hello.erl0000664000175000017500000000107714677012037017764 0ustar debalancedebalance%% File : hello.erl %% Purpose : Brief demonstration of Luerl basics. %% Use $ erlc hello.erl && erl -pa ./ebin -s hello run -s init stop -noshell %% Or $ make hello -module(hello). -export([run/0]). run() -> % execute a string luerl:do("print(\"Hello, Robert(o)!\")", luerl:init()), % execute a file luerl:dofile("./hello.lua", luerl:init()), % separately parse, then execute State0 = luerl:init(), {ok, Chunk, State1} = luerl:load("print(\"Hello, Chunk!\")", State0), {_Ret, _NewState} = luerl:do(Chunk, State1), done. luerl-1.2.3/examples/hello/Makefile0000664000175000017500000000065414677012037017615 0ustar debalancedebalanceEXAMPLES = hello \ hello2 \ hello_table \ hello_table_new \ hello_userdata \ hello_userdata_new \ hello_sandbox \ hello_funcalls ROOTDIR = ../.. SRCDIR = $(ROOTDIR)/src BEAMDIR = $(ROOTDIR)/ebin all: $(EXAMPLES) clean: rm -f *.beam erl_crash.dump .SECONDARY: %.beam: %.erl $(SRCDIR)/*.hrl erlc -I $(SRCDIR) $< %: %.beam erl -pa $(BEAMDIR) -s $@ run -s init stop -noshell .PHONY: all clean luerl-1.2.3/examples/hello/hello2-6.lua0000664000175000017500000000025314677012037020203 0ustar debalancedebalance-- File : hello2-6.lua -- Purpose : Demonstration of Luerl interface. -- See : ./examples/hello/hello2.erl a = 'new contents of a' print('(27) (a) ' .. a) return aluerl-1.2.3/examples/hello/hello_funcalls.erl0000664000175000017500000000206714677012037021653 0ustar debalancedebalance%% File : hello_funcalls.erl %% Purpose : Demonstration of various ways to expose Erlang functions to Luerl. %% Use $ erlc hello_funcalls.erl && erl -pa ../../ebin -s hello_funcalls run -s init stop -noshell -module(hello_funcalls). -include("luerl.hrl"). -export([run/0,mfa_function/3]). regular_function(Args,St) -> io:format("regular_function(~p)\n", [Args]), {[42], St}. mfa_function(StaticArgs,DynamicArgs,St) -> io:format("mfa_function(~p, ~p)\n", [StaticArgs, DynamicArgs]), {[42], St}. run() -> LuaScript = <<"return hello_funcall(4, 5, 6)">>, Lua = luerl:init(), Lua1 = luerl:set_table([<<"hello_funcall">>], fun regular_function/2, Lua), % The argument part of {M,F,A} won't get encoded, so that is why we can get away with passing a tuple here. Lua2 = luerl:set_table([<<"hello_funcall">>], {hello_funcalls,mfa_function,{1,2}}, Lua), {Res1, _} = luerl:do(LuaScript, Lua1), io:format("regular_function got ~p~n", Res1), {Res2, _} = luerl:do(LuaScript, Lua2), io:format("mfa_function got ~p~n", Res2). luerl-1.2.3/examples/hello/hello_table.erl0000664000175000017500000000173214677012037021131 0ustar debalancedebalance%% File : hello_table.erl %% Purpose : Brief demonstration of Luerl table access. %% Use $ erlc hello_table.erl && erl -pa ../../ebin -s hello_table run -s init stop -noshell -module(hello_table). -export([run/0]). run() -> LuaScript = <<"hello_table = { hello=\"world\" }; return hello_table">>, {[_Table], Lua0} = luerl:do(LuaScript, luerl:init()), {World, Lua1} = luerl:get_table([hello_table, hello], Lua0), Lua2 = luerl:set_table([hello_table, hello], there, Lua1), {HelloDict,Lua3} = luerl:get_table([hello_table], Lua2), {There, Lua4} = luerl:get_table([hello_table, hello], Lua3), io:format("(1) hello ~s ~s - ~p~n", [There, World, HelloDict]), Lua5 = luerl:set_table1([<<"hello_table">>, <<"goodbye">>], <<"bye">>, Lua4), {Bye, Lua6} = luerl:get_table1([<<"hello_table">>, <<"goodbye">>], Lua5), {HelloTab, _Lua7} = luerl:get_table1([<<"hello_table">>], Lua6), io:format("(2) ~s - ~p~n", [Bye, HelloTab]), done. luerl-1.2.3/examples/hello/hello_table_new.erl0000664000175000017500000000223214677012037021776 0ustar debalancedebalance%% File : hello_table.erl %% Purpose : Brief demonstration of Luerl table access. %% Use $ erlc hello_table_new.erl && erl -pa ../../ebin -s hello_table_new run -s init stop -noshell -module(hello_table_new). -export([run/0]). run() -> LuaScript = <<"hello_table = { hello=\"world\" }; return hello_table">>, {ok, [_Table], Lua0} = luerl_new:do(LuaScript, luerl_new:init()), {ok,World, Lua1} = luerl_new:get_table_keys_dec([hello_table, hello], Lua0), {ok,_,Lua2} = luerl_new:set_table_keys_dec([hello_table, hello], there, Lua1), {ok,HelloDict,Lua3} = luerl_new:get_table_keys_dec([hello_table], Lua2), {ok,There, Lua4} = luerl_new:get_table_keys_dec([hello_table, hello], Lua3), io:format("(1) hello ~s ~s - ~p~n", [There, World, HelloDict]), {ok,_,Lua5} = luerl_new:set_table_keys([<<"hello_table">>, <<"goodbye">>], <<"bye">>, Lua4), {ok, Bye, Lua6} = luerl_new:get_table_keys([<<"hello_table">>, <<"goodbye">>], Lua5), {ok, HelloTab, _Lua7} = luerl_new:get_table_keys([<<"hello_table">>], Lua6), io:format("(2) ~s - ~p~n", [Bye, HelloTab]), done. luerl-1.2.3/examples/hello/hello2-1.lua0000664000175000017500000000022714677012037020177 0ustar debalancedebalance-- File : hello2-1.lua -- Purpose : Demonstration of Luerl interface. -- See : ./examples/hello/hello2.erl print("(6) Hello, File 'hello2-1'!")luerl-1.2.3/examples/hello/hello2-4.lua0000664000175000017500000000023214677012037020176 0ustar debalancedebalance-- File : hello2-4.lua -- Purpose : Demonstration of Luerl interface. -- See : ./examples/hello/hello2.erl return "'(18b) Evidently, Mr. Watson.'"luerl-1.2.3/examples/hello/hello2-3.lua0000664000175000017500000000031214677012037020174 0ustar debalancedebalance-- File : hello2-3.lua -- Purpose : Demonstration of Luerl interface. -- See : ./examples/hello/hello2.erl function no() print("(16) No!") end print("(15) Maybe ...") return "(X) Yes!"luerl-1.2.3/examples/hello/hello_sandbox.erl0000664000175000017500000000406414677012037021501 0ustar debalancedebalance%% File : hello_sandbox.erl %% Purpose : Brief demonstration of Luerl sandbox basics. %% Use $ erlc hello_sandbox.erl && erl -pa ./ebin -s hello_sandbox run -s init stop -noshell %% Or $ make hello_sandbox -module(hello_sandbox). -export([run/0]). run() -> %% Default sandboxed state. SbSt = luerl_sandbox:init(), %% Sandboxing globals {error, {lua_error, Reason, _}} = luerl_sandbox:run("return os.getenv(\"HOME\")", SbSt), io:format("os.getenv with sandbox: ~p~n",[Reason]), %% Customizing sandbox %% first with default Luerl state. {[<<"number">>], _} = luerl_sandbox:run("return type(1)", luerl:init()), %% then with sandboxed type function {error, {lua_error, _, _}} = luerl_sandbox:run("return type(1)", luerl_sandbox:init([['_G', type]])), %% Using sandboxed state outside of runner try luerl:do("return os.getenv(\"HOME\")", SbSt) catch _:_ -> io:format("catch error with os.getenv(\"HOME\") with sandbox~n", []) end, %% Setting values. MaxReductions = 100, SpawnOpts = [{priority, low}], Timeout = 1000, %% Script runner with reduction counting. Flags0 = #{max_reductions => MaxReductions}, {error, {reductions, R0}} = luerl_sandbox:run("a={}; for i=1,1000000 do a[i] = 5 end", Flags0, SbSt), io:format("killed process with reductions ~p > 100~n",[R0]), %% Sandboxed run with default Luerl state. Flags1 = #{max_reductions => MaxReductions, spawn_opts => SpawnOpts, max_time => Timeout}, {error, {reductions, R1}} = luerl_sandbox:run("x = 'a'; while true do x = x .. x end", Flags1, luerl:init()), io:format("killed process with reductions ~p > 100~n",[R1]), %% Unlimited reductions Flags3 = #{max_reductions => none}, {[], _} = luerl_sandbox:run("a={}; for i=1,10 do a[i] = 5 end", Flags3, SbSt), io:format("Finished running with unlimited reductions ~n",[]), done. luerl-1.2.3/examples/hello/hello_userdata_new.erl0000664000175000017500000000156714677012037022531 0ustar debalancedebalance%% File : hello_userdata_new.erl %% Purpose : Brief demonstration of Luerl userdata access. %% Use $ erlc hello_userdata_new.erl && erl -pa ../../ebin -s hello_userdata_new run -s init stop -noshell -module(hello_userdata_new). -export([run/0]). run() -> St0 = luerl_new:init(), U42 = {userdata,42}, %The original decoded data {Uref,St1} = luerl_new:encode(U42, St0), {ok,_,St2} = luerl_new:set_table_keys([<<"u1">>], Uref, St1), {ok,_,St3} = luerl_new:set_table_keys([<<"u2">>], Uref, St2), %% This call wraps the actual data for us. St4 = luerl_heap:set_userdata_data(Uref, 84, St3), {ok,Uref,St5} = luerl_new:get_table_keys([<<"u1">>], St4), {ok,Uref,St6} = luerl_new:get_table_keys([<<"u2">>], St5), U84 = {userdata,84}, %New decoded data U84 = luerl_new:decode(Uref, St6), St6. luerl-1.2.3/examples/hello/hello2-9.lua0000664000175000017500000000027414677012037020211 0ustar debalancedebalance-- File : hello2-9.lua -- Purpose : Demonstration of Luerl interface. -- See : ./examples/hello/hello2.erl function confirm(p) return p .. ' (it really is)' end return confirm(a)luerl-1.2.3/examples/hello/hello2-7.lua0000664000175000017500000000027014677012037020203 0ustar debalancedebalance-- File : hello2-7.lua -- Purpose : Demonstration of Luerl interface. -- See : ./examples/hello/hello2.erl a = "(28a) οἶδα οá½Îº εἰδώς, oîda ouk eidÅs" return a luerl-1.2.3/examples/hello/hello_userdata.erl0000664000175000017500000000132614677012037021651 0ustar debalancedebalance%% File : hello_userdata.erl %% Purpose : Brief demonstration of Luerl userdata access. %% Use $ erlc hello_userdata.erl && erl -pa ../../ebin -s hello_userdata run -s init stop -noshell -module(hello_userdata). -export([run/0]). run() -> St0 = luerl:init(), U42 = {userdata,42}, %The original decoded data {Uref,St1} = luerl:encode(U42, St0), St2 = luerl:set_table1([<<"u1">>], Uref, St1), St3 = luerl:set_table1([<<"u2">>], Uref, St2), %% This call wraps the actual data for us. St4 = luerl_heap:set_userdata_data(Uref, 84, St3), U84 = {userdata,84}, %New decoded data {U84,St5} = luerl:get_table([<<"u1">>], St4), {U84,St6} = luerl:get_table([<<"u2">>], St5), St6. luerl-1.2.3/examples/hello/hello2-2.lua0000664000175000017500000000020314677012037020172 0ustar debalancedebalance-- File : hello2-2.lua -- Purpose : Demonstration of Luerl interface. -- See : ./examples/hello/hello2.erl return 2137 * 42luerl-1.2.3/examples/hello/hello2.erl0000664000175000017500000001554514677012037020053 0ustar debalancedebalance%% File : hello2.erl %% File : luerl/examples/hello/hello2.erl %% Purpose : Demonstration of the Luerl interface. %% Author : Henning Diedrich %% Use : $ cd examples/hello && erlc hello2.erl && erl -pa ../../ebin -s hello2 run -s init stop -noshell %% Or : $ make examples -module(hello2). -export([run/0]). run() -> io:format("-------------------------------------------~n"), io:format("This is an assortment of samples and tests.~n"), io:format("-------------------------------------------~n"), io:format("It's a comprehensive demo of the interface.~n"), io:format("Please check out the source to learn more.~n"), St0A = luerl:init(), % execute a string luerl:eval("print(\"(1) Hello, Robert!\")", St0A), luerl:eval(<<"print(\"(2) Hello, Roberto!\")">>, St0A), luerl:do("print(\"(3) Hej, Robert!\")", St0A), luerl:do(<<"print(\"(4) Olà, Roberto!\")">>, St0A), % execute a string, get a result {ok,A} = luerl:eval("return 1 + 1", St0A), {ok,A} = luerl:eval(<<"return 1 + 1">>, St0A), io:format("(5) 1 + 1 = ~p!~n", [A]), % execute a file luerl:evalfile("./hello2-1.lua", St0A), luerl:dofile("./hello2-1.lua", St0A), % execute a file, get a result {ok,B} = luerl:evalfile("./hello2-2.lua", St0A), {B,_} = luerl:dofile("./hello2-2.lua", St0A), io:format("(7) 2137 * 42 = ~p?~n", [B]), % execute a standard function luerl:call_function([print], [<<"(8) Hello, standard print function!">>], St0A), luerl:call_function([print], [<<"(9) Hello, standard print function!">>], St0A), {Result1,_} = luerl:call_function([table,pack], [<<"a">>,<<"b">>,42], St0A), {Result1,_} = luerl:call_function([table,pack], [<<"a">>,<<"b">>,42], St0A), io:format("(10) ~p?~n", [Result1]), % separately parse, then execute (doubles (11) and Chunk1 as assertion) St1A = luerl:init(), {ok,Chunk1,St1B} = luerl:load("print(\"(11) Hello, Chunk 1!\")", St1A), {ok,Chunk1,_} = luerl:load(<<"print(\"(11) Hello, Chunk 1!\")">>, St1A), luerl:eval(Chunk1, St1B), luerl:do(Chunk1, St1B), % separately parse, then execute (doubles (12) and Chunk2 as assertion) St2A = luerl:init(), {ok,Chunk2,St2B} = luerl:load("function chunk2() print(\"(12) Hello, Chunk 2!\") end", St2A), {ok,Chunk2,_} = luerl:load(<<"function chunk2() print(\"(12) Hello, Chunk 2!\") end">>, St2A), {ok,Result2} = luerl:eval(Chunk2, St2B), {Result2,St2C} = luerl:do(Chunk2, St2B), {Result2,St2D} = luerl:do(<<"function chunk2() print(\"(12) Hello, Chunk 2!\") end">>, St2A), luerl:call_function([chunk2], [], St2C), luerl:call_function([chunk2], [], St2D), % separately parse, then execute a file. The file defines a function no() St3A = luerl:init(), {ok,Chunk3,St3B} = luerl:loadfile("./hello2-3.lua", St3A), {ok,Result3} = luerl:eval(Chunk3, St3B), {Result3,St3C} = luerl:do(Chunk3, St3B), {[],_} = luerl:call_function([no], [], St3C), % separately parse, then execute, get a result St4A = luerl:init(), {ok,Chunk4,St4B} = luerl:load("return '(17b) Marvelous wheater today, isn°t it!'", St4A), {ok,Chunk4,_} = luerl:load(<<"return '(17b) Marvelous wheater today, isn°t it!'">>, St4A), {ok,Result4} = luerl:eval(Chunk4, St4B), {Result4,_} = luerl:do(Chunk4, St4B), io:format("(17) And I say: ~p~n", [Result4]), % separately parse, then execute a file, get a result St5A = luerl:init(), {ok,Chunk5,St5B} = luerl:loadfile("./hello2-4.lua", St5A), {ok,Result5} = luerl:eval(Chunk5, St5B), {Result5,_} = luerl:do(Chunk5, St5B), io:format("(18) And he says: ~p~n", [Result5]), % Same as above, passing State in all times. % create state New = luerl:init(), {_,_New2} = luerl:do("print '(19) hello generix'", New), % change state {_,State0} = luerl:do("a = 1000", New), {_,State01} = luerl:do("a = 1000", New), % execute a string, using passed in State0 luerl:eval("print('(20) ' .. a)", State0), luerl:eval(<<"print('(21) ' .. a+1)">>, State0), luerl:do("print('(22) ' .. a+2)", State0), luerl:do(<<"print('(23) ' .. a+3)">>, State0), % execute a string, get a result from passed in State0 {ok,E} = luerl:eval("return 4 * a", State0), {ok,E} = luerl:eval(<<"return 4 * a">>, State0), {E,_} = luerl:do("return 4 * a", State0), {E,_} = luerl:do(<<"return 4 * a">>, State0), io:format("(24) 4 x a = ~p!~n", [E]), % execute a string, get a result, change State0 {Z,State02} = luerl:do("a = 123; return a * 3", State01), {Z,State03} = luerl:do(<<"return (3 * a)">>, State02), io:format("(25) a = ~p~n", [Z]), % execute a file using passed in state luerl:evalfile("./hello2-5.lua", State03), luerl:dofile("./hello2-5.lua", State03), % execute a file that changes the State0 {_,State04} = luerl:dofile("./hello2-6.lua", State03), luerl:do("print('(27) (b) ' .. a)", State04), % execute a file, get a result {ok,F} = luerl:evalfile("./hello2-7.lua", State04), {F,State05} = luerl:dofile("./hello2-7.lua", State04), io:format("(28) F: ~ts~n", [F]), % execute a file that changes the State0, and get a value back {F,State06} = luerl:dofile("./hello2-7.lua", State05), io:format("(29) F: ~ts = ", [F]), luerl:do("print('(30) F: ' .. a)", State06), % separately parse, then execute {ok,Chunk11,_} = luerl:load("print(\"(31) Hello, \" .. a .. \"!\")", State06), {ok,Chunk11,State07} = luerl:load(<<"print(\"(31) Hello, \" .. a .. \"!\")">>, State06), luerl:eval(Chunk11,State07), luerl:do(Chunk11,State07), % separately parse, then execute a file. The file defines a function old() {ok,Chunk12,St7} = luerl:loadfile("./hello2-8.lua", State07), {ok,Result12} = luerl:eval(Chunk12, St7), {Result12,State07A} = luerl:do(Chunk12,St7), luerl:call_function([old],[],State07A), % separately parse, then execute, get a result {ok,Chunk13,St8} = luerl:load("a = '(30a)' .. a .. ' (this is Greek)'; return a", State07), {ok,Chunk13,_} = luerl:load(<<"a = '(30a)' .. a .. ' (this is Greek)'; return a">>, State07), {ok,Result07} = luerl:eval(Chunk13, St8), {Result07,State08} = luerl:do(Chunk13, St8), io:format("(34) And again I said: ~ts~n", [Result07]), % separately parse, then execute a file, get a result. The file defines confirm(p) {ok,Chunk14,St9} = luerl:loadfile("./hello2-9.lua", State08), {ok,Result14} = luerl:eval(Chunk14, St9), {Result14,State14} = luerl:do(Chunk14, St9), io:format("(35) And twice: ~ts~n", [Result14]), {Result14A,_} = luerl:call_function([confirm], [<<"Is it?">>], State14), io:format("(36) Well: ~ts~n", [Result14A]), % execute a file, get the decoded result of a table {ok,Result15} = luerl:evalfile("./hello2-10.lua", State14), io:format("(37) Decoded table: ~p~n", [Result15]), io:format("done~n"). luerl-1.2.3/examples/hello/hello2-10.lua0000664000175000017500000000021214677012037020251 0ustar debalancedebalance-- File : hello2-10.lua -- Purpose : Returning lua dicts -- See : ./examples/hello/hello2.erl return {1,2,{3,'Hello World!'}} luerl-1.2.3/examples/hello/hello2-8.lua0000664000175000017500000000025214677012037020204 0ustar debalancedebalance-- File : hello2-8.lua -- Purpose : Demonstration of Luerl interface. -- See : ./examples/hello/hello2.erl function old() print "(33) old" end print "(32) News!"luerl-1.2.3/examples/Makefile0000664000175000017500000000024214677012037016503 0ustar debalancedebalanceSUBDIRS ?= hello all clean: @for subdir in $(SUBDIRS); do \ echo $(MAKE) -C $$subdir $@; \ $(MAKE) -C $$subdir $@; \ done .PHONY: all clean luerl-1.2.3/examples/benchmark/0000775000175000017500000000000014677012037016777 5ustar debalancedebalanceluerl-1.2.3/examples/benchmark/util/0000775000175000017500000000000014677012037017754 5ustar debalancedebalanceluerl-1.2.3/examples/benchmark/util/extract_bench_keys.lua0000664000175000017500000000013014677012037024315 0ustar debalancedebalancelocal list = {} for key, func in pairs(bench) do list[#list+1] = key end return list luerl-1.2.3/examples/benchmark/Makefile0000664000175000017500000000044614677012037020443 0ustar debalancedebalanceEXAMPLES = benchmarks ROOTDIR = ../.. SRCDIR = $(ROOTDIR)/src BEAMDIR = $(ROOTDIR)/ebin all: $(EXAMPLES) clean: rm -f *.beam erl_crash.dump .SECONDARY: %.beam: %.erl $(SRCDIR)/*.hrl erlc -I $(SRCDIR) $< %: %.beam erl -pa $(BEAMDIR) -s $@ run -s init stop -noshell .PHONY: all clean luerl-1.2.3/examples/benchmark/benchmarks.erl0000664000175000017500000000312514677012037021621 0ustar debalancedebalance%% File : benchmarks.erl %% Purpose : Benchmarks runner for luerl %% Use: erlc -I ../src benchmark.erl && erl -pa ../ebin -s benchmark run -s init stop -noshell %% Or: make -module(benchmarks). -export([run/0, run/1]). -export([benchmarks/1, do_benchmark/2, do_iteration/3]). -define(DEFAULT_ITER, 1000). run() -> Files = filelib:wildcard("suites/*.lua"), [run(File) || File <- Files], ok. run(File) -> Lua0 = luerl:init(), {ok, Form, Lua1} = luerl:loadfile(File, Lua0), {_Resp, Lua2} = luerl:do(Form, Lua1), report_file(File), [do_benchmark(Benchmark, Lua2) || Benchmark <- benchmarks(Lua2)], {ok, Lua2}. do_benchmark(Benchmark, Lua) -> Iter = num_iterations(Lua), report_benchmark(Benchmark), {Time, _Resp} = timer:tc(?MODULE, do_iteration, [Iter, Benchmark, Lua]), report_time(Time), ok. do_iteration(0, _Benchmark, _Lua) -> ok; do_iteration(Iter, Benchmark, Lua) -> luerl:call_method1([<<"bench">>, Benchmark], [], Lua), do_iteration(Iter - 1, Benchmark, Lua). num_iterations(Lua) -> case luerl:eval("return NUM_ITERATIONS", Lua) of {ok, [Iter]} when is_number(Iter) -> round(Iter); _any -> ?DEFAULT_ITER end. benchmarks(Lua0) -> {ok, Chunk, Lua1} = luerl:loadfile("util/extract_bench_keys.lua", Lua0), {ok, [Benchmarks]} = luerl:eval(Chunk, Lua1), [Key || {_Index, Key} <- Benchmarks]. report_file(File) -> io:format("~n~s ms~n", [string:left(File, 26)]). report_benchmark(Benchmark) -> io:format(" ~s", [string:left(binary_to_list(Benchmark), 24, $.)]). report_time(Time) -> io:format(" ~p~n", [Time / 1000]). luerl-1.2.3/examples/benchmark/suites/0000775000175000017500000000000014677012037020313 5ustar debalancedebalanceluerl-1.2.3/examples/benchmark/suites/accum.lua0000664000175000017500000000516714677012037022117 0ustar debalancedebalancelocal assert, loadstring = assert, loadstring local pairs, ipairs, next = pairs, ipairs, next local table_concat = table.concat -------------------------------------------------------------------------------- local DATA = { 006.635; 009.210; 011.345; 013.277; 015.086; 016.812; 018.475; 020.090; 021.666; 023.209; 024.725; 026.217; 027.688; 029.141; 030.578; 032.000; 033.409; 034.805; 036.191; 037.566; 038.932; 040.289; 041.638; 042.980; 044.314; 045.642; 046.963; 048.278; 049.588; 050.892; 052.191; 053.486; 054.776; 056.061; 057.342; 058.619; 059.893; 061.162; 062.428; 063.691; 064.950; 066.206; 067.459; 068.710; 069.957; 071.201; 072.443; 073.683; 074.919; 076.154; 077.386; 078.616; 079.843; 081.069; 082.292; 083.513; 084.733; 085.950; 087.166; 088.379; 089.591; 090.802; 092.010; 093.217; 094.422; 095.626; 096.828; 098.028; 099.228; 100.425; 101.621; 102.816; 104.010; 105.202; 106.393; 107.583; 108.771; 109.958; 111.144; 112.329; 113.512; 114.695; 115.876; 117.057; 118.236; 119.414; 120.591; 121.767; 122.942; 124.116; 125.289; 126.462; 127.633; 128.803; 129.973; 131.141; 132.309; 133.476; 134.642; } local DATA_SIZE = #DATA -------------------------------------------------------------------------------- local accum_unrolled do local buf = { "return function(t, c) c = c or 0; " } for i = 1, DATA_SIZE do buf[#buf + 1] = "c = c + t["..i.."]; " end buf[#buf + 1] = "return c; end" local fn = assert(loadstring(table_concat(buf))) accum_unrolled = assert(fn()) end local accum_numeric_for = function(t, c) c = c or 0 for i = 1, #t do c = c + t[i] end return c end local accum_numeric_while = function(t, c) c = c or 0 local i = 1 local v = t[i] while v ~= nil do c = c + v i = i + 1 v = t[i] end return c end local accum_ipairs = function(t, c) c = c or 0 for _, v in ipairs(t) do c = c + v end return c end local accum_pairs = function(t, c) c = c or 0 for _, v in pairs(t) do c = c + v end return c end local accum_next = function(t, c) c = c or 0 local k, v = next(t) while k ~= nil do c = c + v k, v = next(t, k) end return c end -------------------------------------------------------------------------------- bench = { } bench.unrolled = function() return accum_unrolled(DATA) end bench.numeric_while = function() return accum_numeric_while(DATA) end bench.numeric_for = function() return accum_numeric_for(DATA) end bench.ipairs = function() return accum_ipairs(DATA) end bench.pairs = function() return accum_pairs(DATA) end bench.next = function() return accum_next(DATA) end return table.pack(bench) luerl-1.2.3/examples/benchmark/suites/vararg.lua0000664000175000017500000000223414677012037022301 0ustar debalancedebalancelocal noop = function() end local vararg_callback = function(...) end local call_noargs = function(fn) fn() end local call_vararg = function(fn, ...) fn(...) end local call_3 = function(fn, a, b, c) fn(a, b, c) end NUM_ITER = 1000 bench = { } bench.noop = noop bench.vararg_callback = vararg_callback bench.call_noargs_noop_nil = function() call_noargs(noop) end bench.call_noargs_vararg_nil = function() call_noargs(vararg_callback) end bench.call_vararg_noop_nil = function() call_noargs(noop) end bench.call_vararg_vararg_nil = function() call_noargs(vararg_callback) end bench.call_3_noop_nil = function() call_3(noop) end bench.call_3_vararg_nil = function() call_3(vararg_callback) end bench.call_noargs_noop_3 = function() call_noargs(noop, 1, 2, 3) end bench.call_noargs_vararg_3 = function() call_noargs(vararg_callback, 1, 2, 3) end bench.call_vararg_noop_3 = function() call_noargs(noop, 1, 2, 3) end bench.call_vararg_vararg_3 = function() call_noargs(vararg_callback, 1, 2, 3) end bench.call_3_noop_3 = function() call_3(noop, 1, 2, 3) end bench.call_3_vararg_3 = function() call_3(vararg_callback, 1, 2, 3) end return bench luerl-1.2.3/examples/benchmark/suites/elseif_large.lua0000664000175000017500000000265614677012037023450 0ustar debalancedebalance-- TODO: ?! Is this benchmark still relevant? local tostring, assert, loadstring, ipairs = tostring, assert, loadstring, ipairs local table_concat = table.concat local math_floor = math.floor local noop = function() end local plain_call = function(a) noop() end local make_plain_call = function() return plain_call end local make_elseifs = function(n) local buf = { } local _ = function(v) buf[#buf + 1] = tostring(v) end _ "local noop = function() end " _ "return function(a)" _ " if a == 'a" _(1) _"' then noop()" for i = 2, n do _ " elseif a == 'a" _(i) _"' then noop()" end _ " else error('unknown param') end" _ " end" return assert(loadstring(table_concat(buf)))() end local make_callmaps = function(n) local buf = { } local _ = function(v) buf[#buf + 1] = tostring(v) end _ "local noop = function() end " _ "local map = {" for i = 1, n do _ "a" _(i) _ " = noop;" end _ "} " _ "return function(a) assert(map[a])() end" return assert(loadstring(table_concat(buf)))() end local bench_fn = function(fn, n) return function() fn("a" .. math_floor(n / 2 + 0.5)) end end local mark_fn = function(make, n) return bench_fn(make(n), n) end bench = { } for _, i in ipairs { 1, 5, 10, 15, 20, 100, 250, 500, 1000 } do bench["plain_"..i] = mark_fn(make_plain_call, i) bench["callmap_"..i] = mark_fn(make_callmaps, i) bench["elseif_"..i] = mark_fn(make_elseifs, i) end return bench luerl-1.2.3/examples/benchmark/suites/get.lua0000664000175000017500000000164414677012037021602 0ustar debalancedebalancelocal rawget = rawget local t = { true, a = true } local get = function(t, k) return t[k] end bench = { } bench.nonnil_num_plain = function() return t[1] end bench.nonnil_num_get = function() return get(t, 1) end bench.nonnil_num_rawget = function() return rawget(t, 1) end bench.nonnil_str_plain = function() return t["a"] end bench.nonnil_str_sugar = function() return t.a end bench.nonnil_str_get = function() return get(t, "a") end bench.nonnil_str_rawget = function() return rawget(t, "a") end bench.nil_num_plain = function() return t[2] end bench.nil_num_get = function() return get(t, 2) end bench.nil_num_rawget = function() return rawget(t, 2) end bench.nil_str_plain = function() return t["b"] end bench.nil_str_sugar = function() return t.b end bench.nil_str_get = function() return get(t, "b") end bench.nil_str_rawget = function() return rawget(t, "b") end return bench luerl-1.2.3/examples/benchmark/suites/sort-simple.lua0000664000175000017500000000326614677012037023303 0ustar debalancedebalancelocal table_sort = table.sort local math_random, math_randomseed = math.random, math.randomseed -------------------------------------------------------------------------------- math_randomseed(12345) -------------------------------------------------------------------------------- -- TODO: Benchmark some pure-lua qsort local DATA_SIZE = 1e1 local generate_data = function() local t = { } for i = 1, DATA_SIZE do t[i] = math_random() end return t end local less = function(lhs, rhs) return lhs < rhs end local bubble_sort = function(t) for i = 2, #t do local switched = false for j = #t, i, -1 do if t[j] < t[j - 1] then t[j], t[j - 1] = t[j - 1], t[j] switched = true end end if switched == false then return t end end return t end local bubble_sort_cb = function(t, less) for i = 2, #t do local switched = false for j = #t, i, -1 do if less(t[j], t[j - 1]) then t[j], t[j - 1] = t[j - 1], t[j] switched = true end end if switched == false then return t end end return t end -------------------------------------------------------------------------------- bench = { } bench.generate_only = function() local data = generate_data() return true end bench.tsort_nocallback = function() local data = generate_data() return table_sort(data) end bench.tsort_callback = function() local data = generate_data() return table_sort(data, less) end bench.bubble_nocallback = function() local data = generate_data() return bubble_sort(data) end bench.bubble_callback = function() local data = generate_data() return bubble_sort_cb(data, less) end return bench luerl-1.2.3/examples/benchmark/suites/nloop_simple.lua0000664000175000017500000000521614677012037023522 0ustar debalancedebalancelocal ipairs = ipairs local t5, t25, t50 = {}, {}, {} do for i = 1, 10 do t5[i] = i end t5[6] = nil for i = 1, 30 do t25[i] = i end t25[26] = nil for i = 1, 55 do t50[i] = i end t50[51] = nil end local do_nothing = function() end bench = {} local do_loop_ipairs = function(t) for i, v in ipairs(t) do end end local do_loop_numfor = function(t) for i = 1, #t do if t[i] == nil then break end end end local do_loop_while = function(t) local i = 1 while t[i] ~= nil do i = i + 1 end end bench.loop_ipairs_50 = function() do_loop_ipairs(t50) do_nothing(t50) -- Padding to get equivalent number of function calls. do_nothing(t50) do_nothing(t50) do_nothing(t50) do_nothing(t50) do_nothing(t50) do_nothing(t50) do_nothing(t50) do_nothing(t50) end bench.loop_numfor_50 = function() do_loop_numfor(t50) do_nothing(t50) do_nothing(t50) do_nothing(t50) do_nothing(t50) do_nothing(t50) do_nothing(t50) do_nothing(t50) do_nothing(t50) do_nothing(t50) end bench.loop_while_50 = function() do_loop_while(t50) do_nothing(t50) do_nothing(t50) do_nothing(t50) do_nothing(t50) do_nothing(t50) do_nothing(t50) do_nothing(t50) do_nothing(t50) do_nothing(t50) end bench.loop_ipairs_25 = function() do_loop_ipairs(t25) do_loop_ipairs(t25) do_nothing(t25) do_nothing(t25) do_nothing(t25) do_nothing(t25) do_nothing(t25) do_nothing(t25) do_nothing(t25) do_nothing(t25) end bench.loop_numfor_25 = function() do_loop_numfor(t25) do_loop_numfor(t25) do_nothing(t25) do_nothing(t25) do_nothing(t25) do_nothing(t25) do_nothing(t25) do_nothing(t25) do_nothing(t25) do_nothing(t25) end bench.loop_while_25 = function() do_loop_while(t25) do_loop_while(t25) do_nothing(t25) do_nothing(t25) do_nothing(t25) do_nothing(t25) do_nothing(t25) do_nothing(t25) do_nothing(t25) do_nothing(t25) end bench.loop_ipairs_5 = function() do_loop_ipairs(t5) do_loop_ipairs(t5) do_loop_ipairs(t5) do_loop_ipairs(t5) do_loop_ipairs(t5) do_loop_ipairs(t5) do_loop_ipairs(t5) do_loop_ipairs(t5) do_loop_ipairs(t5) do_loop_ipairs(t5) end bench.loop_numfor_5 = function() do_loop_numfor(t5) do_loop_numfor(t5) do_loop_numfor(t5) do_loop_numfor(t5) do_loop_numfor(t5) do_loop_numfor(t5) do_loop_numfor(t5) do_loop_numfor(t5) do_loop_numfor(t5) do_loop_numfor(t5) end bench.loop_while_5 = function() do_loop_while(t5) do_loop_while(t5) do_loop_while(t5) do_loop_while(t5) do_loop_while(t5) do_loop_while(t5) do_loop_while(t5) do_loop_while(t5) do_loop_while(t5) do_loop_while(t5) end return bench luerl-1.2.3/examples/benchmark/suites/tailcall.lua0000664000175000017500000000064714677012037022612 0ustar debalancedebalancelocal ret = function(t) t[1] = true return t end local noret = function(t) t[1] = true end bench = { } bench.tailcall_local = function() local t = {} return ret(t) end bench.tailcall_nolocal = function() return ret({}) end bench.notailcall_return = function() local t = {} ret(t) return t end bench.notailcall_noreturn = function() local t = {} noret(t) return t end return table.pack(bench) luerl-1.2.3/examples/benchmark/suites/tclone.lua0000664000175000017500000001455414677012037022313 0ustar debalancedebalance-------------------------------------------------------------------------------- -- tclone.lua: tclone benchmark -------------------------------------------------------------------------------- local type, pairs, assert, error, unpack, next, newproxy = type, pairs, assert, error, unpack, next, newproxy local math_randomseed, math_random = math.randomseed, math.random local string_char = string.char local table_concat = table.concat -- local coroutine_create = coroutine.create -------------------------------------------------------------------------------- math_randomseed(123456) -------------------------------------------------------------------------------- -- -- Current lua-nucleo version (a166af) -- local tclone_nucleo do local function impl(t, visited) local t_type = type(t) if t_type ~= "table" then return t end assert(not visited[t], "recursion detected") visited[t] = true local r = { } for k, v in pairs(t) do r[impl(k, visited)] = impl(v, visited) end visited[t] = nil return r end tclone_nucleo = function(t) return impl(t, { }) end end -- -- tclone2 by Dimiter "malkia" Stanev -- http://article.gmane.org/gmane.comp.lang.lua.general/82378 -- local tclone2 do local function impl(t, visited, rtimes) local t_type = type(t) if t_type ~= "table" then return t end -- Don't remember all visited[t] levels -- Just remember every once in a 128 times -- If there is a recursion it'll still be detected -- But 128 stack levels deeper assert(not visited[t], "recursion detected (with some latency)") if rtimes == 128 then rtimes = 1 visited[t] = t end local r = { } for k, v in pairs(t) do r[impl(k, visited, rtimes + 1)] = impl(v, visited, rtimes + 1) end if rtimes == 1 then visited[t] = nil end return r end tclone2 = function(t) return impl(t, { }, 1) end end -- -- tclone5 by Dimiter "malkia" Stanev -- http://article.gmane.org/gmane.comp.lang.lua.general/82379 -- local tclone5 do local function impl(t, visited, rtimes) if visited[t] then error("recursion detected") end if rtimes == 128 then rtimes = 1 visited[t] = true end local r = { } for k, v in pairs(t) do if type(k) == "table" then if type(v) == "table" then r[impl(k, visited, rtimes + 1)] = impl(v, visited, rtimes + 1) else r[impl(k, visited, rtimes + 1)] = v end elseif type(v) == "table" then r[k] = impl(v, visited, rtimes + 1) else r[k] = v end end if rtimes == 1 then visited[t] = nil end return r end tclone5 = function(t) if type(t) == "table" then return impl(t, { }, 1) end return t end end -- -- tclone6 by Dimiter "malkia" Stanev -- http://article.gmane.org/gmane.comp.lang.lua.general/82601 -- With a fix in while condition -- local tclone6 do local function impl(t, visited, rtimes) if visited[t] then error("recursion detected") end if rtimes == 128 then rtimes = 1 visited[t] = true end local r = { } local k, v = next(t) while k ~= nil do if type(k) == "table" then if type(v) == "table" then r[impl(k, visited, rtimes + 1)] = impl(v, visited, rtimes + 1) else r[impl(k, visited, rtimes + 1)] = v end elseif type(v) == "table" then r[k] = impl(v, visited, rtimes + 1) else r[k] = v end k, v = next(t, k) end if rtimes == 1 then visited[t] = nil end return r end tclone6 = function(t) if type(t) == "table" then return impl(t, { }, 1) end return t end end -------------------------------------------------------------------------------- -- TODO: From lua-nucleo/test/table.lua. -- Make that available to other projects and reuse. local function gen_random_dataset(num, nesting, visited, random) random = random or math_random nesting = nesting or 1 visited = visited or {} num = num or random(0, 10) local gen_str = function() local len = random(1, 64) local t = {} for i = 1, len do t[i] = string_char(random(0, 255)) end return table_concat(t) end local gen_bool = function() return random() >= 0.5 end local gen_udata = function() return newproxy() end local gen_func = function() return function() end end -- local gen_thread = function() return coroutine_create(function() end) end local gen_nil = function() return nil end local gen_visited_link = function() if #visited > 1 then return visited[random(1, #visited)] else return gen_str() end end local generators = { gen_bool; gen_bool; gen_bool; function() return random(-10, 10) end; gen_str; gen_str; gen_str; --[[ gen_thread; gen_thread; gen_func; gen_func; gen_udata; gen_udata;--]] --gen_visited_link; function() if nesting >= 10 then return nil end local t = { } visited[#visited + 1] = t local n = random(0, 10 - nesting) for i = 1, n do local k = gen_random_dataset(1, nesting + 1, visited, random) if k == nil then k = "(nil)" end t[k] = gen_random_dataset(1, nesting + 1, visited, random) end return t end } local t = {} visited[#visited + 1] = t for i = 1, num do local n = random(1, #generators) t[i] = generators[n]() end return unpack(t, 1, num) end -------------------------------------------------------------------------------- local DATA = { gen_random_dataset(20) } -------------------------------------------------------------------------------- bench = { } -------------------------------------------------------------------------------- bench.lua_nucleo = function() local data = tclone_nucleo(DATA) assert(data ~= DATA) -- TODO: Check equality. end bench.tclone2 = function() local data = tclone2(DATA) assert(data ~= DATA) -- TODO: Check equality. end bench.tclone5 = function() local data = tclone5(DATA) assert(data ~= DATA) -- TODO: Check equality. end bench.tclone6 = function() local data = tclone5(DATA) assert(data ~= DATA) -- TODO: Check equality. end -------------------------------------------------------------------------------- return bench luerl-1.2.3/examples/benchmark/suites/concat.lua0000664000175000017500000000175714677012037022277 0ustar debalancedebalancelocal table_concat, table_insert = table.concat, table.insert NUM_ITERATIONS = 1 bench = {} bench.raw_concat = function() local self = "string 0\n" for i = 1, 1000 do self = self .. "string " .. i .. "\n" end return self end bench.raw_plus_1 = function() local self = { "string 0\n" } for i = 1, 1000 do self[#self + 1] = "string " self[#self + 1] = i self[#self + 1] = "\n" end return table_concat(self) end bench.raw_insert = function() local self = { "string 0\n" } for i = 1, 1000 do table_insert(self, "string ") table_insert(self, i ) table_insert(self, "\n" ) end return table_concat(self) end bench.mixed_plus_1 = function() local self = {"string 0\n"} for i = 1,1000 do self[#self + 1] = "string " .. i .. "\n" end return table_concat(self) end bench.mixed_insert = function() local self = {"string 0\n"} for i = 1, 1000 do table_insert(self, "string " .. i .. "\n") end return table_concat(self) end return bench luerl-1.2.3/examples/benchmark/suites/selectvstable.lua0000664000175000017500000000106114677012037023654 0ustar debalancedebalancelocal select = select local select_test = function(...) local nargs = select("#", ...) local r = { } for i = 1, nargs do r[#r + 1] = select(i, ...) * 2 end return r end local table_test = function(...) local nargs = select("#", ...) -- Still have to do this in case of nils local args = { ... } local r = { } for i = 1, nargs do r[#r + 1] = args[i] * 2 end return r end bench = { } bench.select = function() return select_test(3, 5, 1, 9, 7) end bench.table = function() return table_test(3, 5, 1, 9, 7) end return bench luerl-1.2.3/examples/benchmark/suites/return.lua0000664000175000017500000000063114677012037022335 0ustar debalancedebalancebench = {} local function no_ret() end local function ret_nil() return nil end local function ret_true() return true end local function ret_self() return ret_self end bench.no_ret = function() local a = no_ret() end bench.ret_nil = function() local a = ret_nil() end bench.ret_true = function() local a = ret_true() end bench.ret_self = function() local a = ret_self() end return bench luerl-1.2.3/examples/benchmark/suites/COPYRIGHT0000664000175000017500000000264614677012037021616 0ustar debalancedebalanceLuamarca is licensed under the terms of the MIT license reproduced below. This means that Luamarca is free software and can be used for both academic and commercial purposes at absolutely no cost. =============================================================================== Copyright (C) 2008-2009 Luamarca authors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =============================================================================== (end of COPYRIGHT) luerl-1.2.3/examples/benchmark/suites/callmap10.lua0000664000175000017500000000146014677012037022571 0ustar debalancedebalancelocal noop = function() end local plain_call = function(a) noop() end local if_call = function(a) if a == "a1" then noop() elseif a == "a2" then noop() elseif a == "a3" then noop() elseif a == "a4" then noop() elseif a == "a5" then noop() elseif a == "a6" then noop() elseif a == "a7" then noop() elseif a == "a8" then noop() elseif a == "a9" then noop() elseif a == "a10" then noop() end end local map = { } for i = 1, 10 do map["a"..i] = noop end local map_call = function(a) map[a]() end local do_bench = function(fn) return function() for i = 1, 10 do fn("a"..i) end end end bench = { noop = do_bench(noop); plain_call = do_bench(plain_call); if_call = do_bench(if_call); map_call = do_bench(map_call); } return bench luerl-1.2.3/examples/benchmark/suites/next_vs_pairs.lua0000664000175000017500000000057214677012037023706 0ustar debalancedebalancelocal pairs, next = pairs, next local t = {} for i = 1, 50 do t[i] = i -- Array part t[i * 256] = i -- Hash part end bench = {} bench.pairs = function() local sum = 0 for k, v in pairs(t) do sum = sum + v end end bench.next = function() local sum = 0 local k, v = next(t) while k ~= nil do sum = sum + v k, v = next(t, k) end end return bench luerl-1.2.3/examples/benchmark/suites/is_integer.lua0000664000175000017500000000300514677012037023144 0ustar debalancedebalancelocal math_floor = math.floor bench = {} local integer, noninteger = 12345, 12345.67 local noop = function(a) return a end local isint_floor = function(a) if a == math_floor(a) then return true end return false end local isint_floor_direct = function(a) return (a == math_floor(a)) end local isint_mod = function(a) if a % 1 == 0 then return true end return false end local isint_mod_direct = function(a) return (a % 1 == 0) end local isint_bits = function(a) if (a + 2^52) - 2^52 == a then return true end return false end local isint_bits_direct = function(a) return (a + 2^52) - 2^52 == a end bench.noop_int = function() noop(integer) end bench.noop_nonint = function() noop(noninteger) end bench.floor_int = function() isint_floor(integer) end bench.floor_nonint = function() isint_floor(noninteger) end bench.floor_int_direct = function() isint_floor_direct(integer) end bench.floor_nonint_direct = function() isint_floor_direct(noninteger) end bench.mod_int = function() isint_mod(integer) end bench.mod_nonint = function() isint_mod(noninteger) end bench.mod_int_direct = function() isint_mod_direct(integer) end bench.mod_nonint_direct = function() isint_mod_direct(noninteger) end bench.bits_int = function() isint_bits(integer) end bench.bits_nonint = function() isint_bits(noninteger) end bench.bits_int_direct = function() isint_bits_direct(integer) end bench.bits_nonint_direct = function() isint_bits_direct(noninteger) end return bench luerl-1.2.3/examples/benchmark/suites/mtvsclosure.lua0000664000175000017500000000106414677012037023405 0ustar debalancedebalancelocal setmetatable = setmetatable local mt = { __call = function(t, v) t[#t + 1] = v end } local call_setmetatable = function() return setmetatable({ }, mt) end local create_closure = function() local t = {} return function(v) t[#t + 1] = v end end local mt_obj = call_setmetatable() local fn_obj = create_closure() bench = { } bench.call_setmetatable = call_setmetatable bench.create_closure = create_closure -- bench.use_setmetatable = function() -- mt_obj("boo!") -- end bench.use_closure = function() fn_obj("boo!") end return bench luerl-1.2.3/examples/benchmark/suites/nloop.lua0000664000175000017500000000120014677012037022136 0ustar debalancedebalancelocal ipairs = ipairs local t = {} for i = 1, 55 do t[i] = i end t[51] = nil -- A hole bench = {} -- Bench function does: -- 1. Set all table elements to 0 until the first hole. -- 2. Return hole position. bench.loop_ipairs = function() local j for i, v in ipairs(t) do t[i] = 0 j = i end return j + 1 end bench.loop_for = function() local n = #t local j = n for i = 1, n do local v = t[i] if v == nil then j = i break end t[i] = 0 end return j end bench.loop_while = function() local i = 1 while t[i] ~= nil do t[i] = 0 i = i + 1 end return i end return bench luerl-1.2.3/examples/benchmark/suites/inf.lua0000664000175000017500000000047614677012037021601 0ustar debalancedebalancelocal tonumber = tonumber local math_huge = math.huge bench = {} -- bench.e309 = function() -- local inf = 1e309 -- end bench.huge = function() local inf = math_huge end -- bench.divide = function() -- local inf = 1/0 -- end -- bench.tonumber = function() -- local inf = tonumber("inf") -- end return bench luerl-1.2.3/examples/benchmark/suites/chaincall.lua0000664000175000017500000000173514677012037022742 0ustar debalancedebalancebench = {} local function chain() return chain end local function plain() -- No-op end bench.chain_upval = function() chain () () () () () () () () () () -- 10 calls end bench.plain_upval = function() plain () plain () plain () plain () plain () plain () plain () plain () plain () plain () -- 10 calls end bench.plain_chain_upval = function() chain () chain () chain () chain () chain () chain () chain () chain () chain () chain () -- 10 calls end bench.chain_local = function() local chain = chain chain () () () () () () () () () () -- 10 calls end bench.plain_local = function() local plain = plain plain () plain () plain () plain () plain () plain () plain () plain () plain () plain () -- 10 calls end bench.plain_chain_local = function() local chain = chain chain () chain () chain () chain () chain () chain () chain () chain () chain () chain () -- 10 calls end return bench luerl-1.2.3/examples/benchmark/suites/str_is_empty.lua0000664000175000017500000000110214677012037023531 0ustar debalancedebalancelocal empty_string = "" bench = { } bench.noop = function() local a = "" return true end bench.empty_constant = function() local a = "" return a == "" end bench.empty_upvalue = function() local a = "" return a == empty_string end bench.empty_size = function() local a = "" return #a == 0 end bench.nonempty_constant = function() local a = "nonempty" return a == "" end bench.nonempty_upvalue = function() local a = "nonempty" return a == empty_string end bench.nonempty_size = function() local a = "nonempty" return #a == 0 end return bench luerl-1.2.3/examples/benchmark/suites/arguments.lua0000664000175000017500000001635114677012037023031 0ustar debalancedebalancelocal select, tostring, assert, type, error = select, tostring, assert, type, error -------------------------------------------------------------------------------- local run_plain_assert = function(a, b, c) assert(type(a) == "number") assert(type(b) == "boolean") assert(type(c) == "string") end -------------------------------------------------------------------------------- local run_assert_is do local make_assert_is = function(typename) return function(v, msg) if type(v) == typename then return v end error( (msg or "assertion failed") .. ": expected `" .. typename .. "', got `" .. type(v) .. "'", 3 ) end end local assert_is_number = make_assert_is("number") local assert_is_boolean = make_assert_is("boolean") local assert_is_string = make_assert_is("string") run_assert_is = function(a, b, c) assert_is_number(a) assert_is_boolean(b) assert_is_string(c) end end -------------------------------------------------------------------------------- local run_arguments_select_simple do local arguments_select = function(...) local nargs = select("#", ...) for i = 1, nargs, 2 do local expected_type, value = select(i, ...) if type(value) ~= expected_type then error( "bad argument #" .. ((i + 1) / 2) .. " type: expected `" .. expected_type .. "', got `" .. type(value) .. "'", 3 ) end end end run_arguments_select_simple = function(a, b, c) arguments_select( "number", a, "boolean", b, "string", c ) end end -------------------------------------------------------------------------------- local run_arguments_recursive_simple do -- Simplified lua-nucleo version, equivalent to the others. local function impl(arg_n, expected_type, value, ...) -- Points error on function, calling function which calls *arguments() if type(value) ~= expected_type then error( "argument #"..arg_n..": expected `"..tostring(expected_type) .. "', got `"..type(value).."'", 3 + arg_n ) end -- If have at least one more type, check it return ((...) ~= nil) and impl(arg_n + 1, ...) or true end local arguments_recursive = function(...) local nargs = select('#', ...) return (nargs > 0) and impl(1, ...) or true end run_arguments_recursive_simple = function(a, b, c) arguments_recursive( "number", a, "boolean", b, "string", c ) end end -------------------------------------------------------------------------------- local run_arguments_recursive_lua_nucleo do -- Taken directly from lua-nucleo local lua51_types = { ["nil"] = true; ["boolean"] = true; ["number"] = true; ["string"] = true; ["table"] = true; ["function"] = true; ["thread"] = true; ["userdata"] = true; } local function impl(is_optional, arg_n, expected_type, value, ...) -- Points error on function, calling function which calls *arguments() if type(value) ~= expected_type then if not lua51_types[expected_type] then error( "argument #"..arg_n..": bad expected type `"..tostring(expected_type).."'", 3 + arg_n ) end if not is_optional or value ~= nil then error( (is_optional and "optional" or "") .. "argument #"..arg_n..": expected `"..tostring(expected_type) .. "', got `"..type(value).."'", 3 + arg_n ) end end -- If have at least one more type, check it return ((...) ~= nil) and impl(is_optional, arg_n + 1, ...) or true end local arguments_recursive = function(...) local nargs = select('#', ...) return (nargs > 0) and ( (nargs % 2 == 0) and impl(false, 1, ...) -- Not optional or error("arguments: bad call, dangling argument detected") ) or true end run_arguments_recursive_lua_nucleo = function(a, b, c) arguments_recursive( "number", a, "boolean", b, "string", c ) end end -------------------------------------------------------------------------------- -- TODO: Add a version with full-blown validation. local run_arguments_unroll_simple do -- TODO: Put a code-generation metatable over cache -- and pre-populate it for cases with (1-10) * 2 arguments. -- If __index sees odd number, it should crash -- with dangling argument error. local arguments_cache = { [6] = function(t1, v1, t2, v2, t3, v3) if type(v1) ~= t1 then error( "argument #1: expected `"..tostring(t1) .. "', got `"..type(v1).."'", 4 ) end if type(v2) ~= t2 then error( "argument #2: expected `"..tostring(t2) .. "', got `"..type(v2).."'", 4 ) end if type(v3) ~= t3 then error( "argument #3: expected `"..tostring(t3) .. "', got `"..type(v3).."'", 4 ) end end; } local arguments = function(...) local n = select("#", ...) -- Assuming cache is pre-populated for all possible use-cases return assert(arguments_cache[n])(...) end run_arguments_unroll_simple = function(a, b, c) arguments( "number", a, "boolean", b, "string", c ) end end -------------------------------------------------------------------------------- local run_arguments_hardcoded_simple do -- Not much real-word meaning, just for comparison with -- run_arguments_unroll_simple. local hardcoded_arguments_6 = function(t1, v1, t2, v2, t3, v3) if type(v1) ~= t1 then error( "argument #1: expected `"..tostring(t1) .. "', got `"..type(v1).."'", 2 ) end if type(v2) ~= t2 then error( "argument #2: expected `"..tostring(t2) .. "', got `"..type(v2).."'", 2 ) end if type(v3) ~= t3 then error( "argument #3: expected `"..tostring(t3) .. "', got `"..type(v3).."'", 2 ) end end run_arguments_hardcoded_simple = function(a, b, c) hardcoded_arguments_6( "number", a, "boolean", b, "string", c ) end end -------------------------------------------------------------------------------- bench = { } bench.plain_assert = function() run_plain_assert(42, true, "aaa") end bench.assert_is = function() run_assert_is(42, true, "aaa") end bench.assert_is_alloc = function() -- Imitating args table allocation. -- Needed to compensate plain Lua interpreter -- compatibility mode. local a, b, c = { }, { }, { } run_assert_is(42, true, "aaa") end bench.args_select_simple = function() run_arguments_select_simple(42, true, "aaa") end bench.args_recursive_simp = function() run_arguments_recursive_simple(42, true, "aaa") end bench.args_recursive_ln = function() run_arguments_recursive_lua_nucleo(42, true, "aaa") end bench.args_unroll_simple = function() run_arguments_unroll_simple(42, true, "aaa") end bench.args_hard_simple = function() run_arguments_hardcoded_simple(42, true, "aaa") end return bench luerl-1.2.3/examples/benchmark/suites/callmap1.lua0000664000175000017500000000142114677012037022506 0ustar debalancedebalancelocal noop = function() end local plain_call = function(a) noop() end local if_call = function(a) if a == "a1" then noop() elseif a == "a2" then noop() elseif a == "a3" then noop() elseif a == "a4" then noop() elseif a == "a5" then noop() elseif a == "a6" then noop() elseif a == "a7" then noop() elseif a == "a8" then noop() elseif a == "a9" then noop() elseif a == "a10" then noop() end end local map = { } for i = 1, 10 do map["a"..i] = noop end local map_call = function(a) map[a]() end local do_bench = function(fn) return function() fn("a"..1) end end bench = { noop = do_bench(noop); plain_call = do_bench(plain_call); if_call = do_bench(if_call); map_call = do_bench(map_call); } return bench luerl-1.2.3/examples/benchmark/suites/factory.lua0000664000175000017500000000622614677012037022473 0ustar debalancedebalancelocal pairs, setmetatable = pairs, setmetatable local clone_table = function(t) local r = {} for k, v in pairs(t) do r[k] = v end return r end local inplace = function() local factory do factory = function() return { method1 = function(self) end; method2 = function(self) end; method3 = function(self) end; method4 = function(self) end; method5 = function(self) end; method6 = function(self) end; method7 = function(self) end; method8 = function(self) end; method9 = function(self) end; method10 = function(self) end; } end end return factory end local plain = function() local factory do local method1 = function(self) end local method2 = function(self) end local method3 = function(self) end local method4 = function(self) end local method5 = function(self) end local method6 = function(self) end local method7 = function(self) end local method8 = function(self) end local method9 = function(self) end local method10 = function(self) end factory = function() return { method1 = method1; method2 = method2; method3 = method3; method4 = method4; method5 = method5; method6 = method6; method7 = method7; method8 = method8; method9 = method9; method10 = method10; } end end return factory end local mt = function() local factory do local mt = { __index = { method1 = function(self) end; method2 = function(self) end; method3 = function(self) end; method4 = function(self) end; method5 = function(self) end; method6 = function(self) end; method7 = function(self) end; method8 = function(self) end; method9 = function(self) end; method10 = function(self) end; }; } factory = function() return setmetatable({}, mt) end end return factory end local clone = function() local factory do local proto = { method1 = function(self) end; method2 = function(self) end; method3 = function(self) end; method4 = function(self) end; method5 = function(self) end; method6 = function(self) end; method7 = function(self) end; method8 = function(self) end; method9 = function(self) end; method10 = function(self) end; } factory = function() return clone_table(proto) end end return factory end local invoker = function(factory) local obj = factory() return function() obj:method1() obj:method2() obj:method3() obj:method4() obj:method5() obj:method6() obj:method7() obj:method8() obj:method9() obj:method10() end end bench = { inplace_init = inplace; plain_init = plain; metatable_init = mt; clone_init = clone; inplace_call = inplace(); plain_call = plain(); metatable_call = mt(); clone_call = clone(); inplace_method = invoker(inplace()); plain_method = invoker(plain()); metatable_method = invoker(mt()); clone_method = invoker(clone()); } return bench luerl-1.2.3/examples/euler/0000775000175000017500000000000014677012037016161 5ustar debalancedebalanceluerl-1.2.3/examples/euler/euler.erl0000664000175000017500000000204614677012037020003 0ustar debalancedebalance%% File : euler.erl %% Purpose : Running complex lua with luerl %% Use: erlc -I ../../src euler.erl && erl -pa ../../ebin -s euler run -s init stop -noshell %% Or: make -module(euler). -export([run/0, run/2]). run() -> run("./problem_001.lua", 233168), run("./problem_002.lua", 4613732), run("./problem_003.lua", 29), run("./problem_004.lua", 36863), run("./problem_005.lua", 232792560), run("./problem_006.lua", 25164150), run("./problem_007.lua", 617), run("./problem_008.lua", 32), run("./problem_009.lua", 31875000), run("./problem_010.lua", 277050.0), ok. run(File, Solution) -> Lua0 = luerl:init(), {ok, Form, Lua1} = luerl:loadfile(File, Lua0), case timer:tc(luerl, eval, [Form, Lua1]) of {T, {ok, [Return]}} when Return == Solution -> io:format("~s (returned ~p in ~pus)~n", [File, Return, T]); {T, {ok, [Return]}} -> io:format("~s (expected ~p but got ~p in ~pus)~n", [File, Solution, Return, T]); {_, {error, Error, State}} -> io:format("luerl error: ~p~n", [{Error,State}]) end. luerl-1.2.3/examples/euler/Makefile0000664000175000017500000000044014677012037017617 0ustar debalancedebalanceEXAMPLES = euler ROOTDIR = ../.. SRCDIR = $(ROOTDIR)/src BEAMDIR = $(ROOTDIR)/ebin all: $(EXAMPLES) clean: rm -f *.beam erl_crash.dump .SECONDARY: %.beam: %.erl $(SRCDIR)/*.hrl erlc -I $(SRCDIR) $< %: %.beam erl -pa $(BEAMDIR) -s $@ run -s init stop -noshell .PHONY: all clean luerl-1.2.3/examples/euler/problem_003.lua0000664000175000017500000000111114677012037020700 0ustar debalancedebalance-- The prime factors of 13195 are 5, 7, 13 and 29. -- What is the largest prime factor of the number 600851475143 ? -- NUMBER_TO_FACTOR = 600851475143 NUMBER_TO_FACTOR = 13195 limit = math.sqrt(NUMBER_TO_FACTOR) primes = { 3 } function divisible_by_any(val, array) for ii, num in ipairs(array) do if (val % num) == 0 then return true end end return false end for ii = 5, limit, 2 do if not divisible_by_any(ii, primes) then table.insert(primes, ii) if NUMBER_TO_FACTOR % ii == 0 then factor = ii end end end print(factor) return factor luerl-1.2.3/examples/euler/problem_001.lua0000664000175000017500000000051214677012037020702 0ustar debalancedebalance-- If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23. -- Find the sum of all the multiples of 3 or 5 below 1000. LIMIT = 1000 sum = 0 for ii = 1, (LIMIT-1) do if (ii%3 == 0) or (ii%5 == 0) then sum = sum + ii end end print(sum) return sum luerl-1.2.3/examples/euler/problem_002.lua0000664000175000017500000000073514677012037020712 0ustar debalancedebalance-- Each new term in the Fibonacci sequence is generated by adding the previous two terms. -- By starting with 1 and 2, the first 10 terms will be: -- 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ... -- By considering the terms in the Fibonacci sequence whose values do not exceed four million, -- find the sum of the even-valued terms. LIMIT = 4000000 a, b, sum = 1, 2, 0 while b <= LIMIT do if b % 2 == 0 then sum = sum + b end a, b = b, a + b end print(sum) return sum luerl-1.2.3/examples/euler/problem_006.lua0000664000175000017500000000116714677012037020716 0ustar debalancedebalance-- The sum of the squares of the first ten natural numbers is, -- 12 + 22 + ... + 102 = 385 -- The square of the sum of the first ten natural numbers is, -- (1 + 2 + ... + 10)2 = 552 = 3025 -- Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 385 = 2640. -- Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum. LIMIT = 100 sum, sum_squares = 0, 0 for ii = 1, LIMIT do sum, sum_squares = sum + ii, sum_squares + (ii * ii) end answer = (sum*sum) - sum_squares print(answer) return answer luerl-1.2.3/examples/euler/problem_007.lua0000664000175000017500000000147014677012037020714 0ustar debalancedebalance-- By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13. -- What is the 10 001st prime number? -- LIMIT = 10001 LIMIT = 113 function primes(count) found_primes = { 2 } local function divisible_by_known_primes(num) for _, v in ipairs(found_primes) do if num % v == 0 then return true end end return false end local function next_prime(found_primes, _) val = found_primes[#found_primes] repeat val = (val == 2) and 3 or val + 2 until(not divisible_by_known_primes(val)) table.insert(found_primes, val) if #found_primes > count then return nil else return val end end return next_prime, found_primes, 3 end for ii in primes(LIMIT) do highest = ii end print(highest) return highest luerl-1.2.3/examples/euler/problem_009.lua0000664000175000017500000000063514677012037020720 0ustar debalancedebalance-- A Pythagorean triplet is a set of three natural numbers, a b c, for which, -- a2 + b2 = c2 -- For example, 32 + 42 = 9 + 16 = 25 = 52. -- There exists exactly one Pythagorean triplet for which a + b + c = 1000. -- Find the product abc. for a = 2, 499 do for b = 2, 499 do c = (1000 - a) - b if a^2 + b^2 == c^2 then answer = a*b*c print(answer) return answer end end end luerl-1.2.3/examples/euler/problem_010.lua0000664000175000017500000000160414677012037020705 0ustar debalancedebalance-- The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17. -- Find the sum of all the primes below two million. -- LIMIT = 2000000 LIMIT = 2000 function primes_below(limit) found_primes = { } local function divisible_by_known_primes(num) for _, v in ipairs(found_primes) do if num % v == 0 then return true end end return false end local function next_prime(found_primes, last_prime) if last_prime == nil then table.insert(found_primes, 2) return 2 end val = found_primes[#found_primes] repeat val = (val == 2) and 3 or val + 2 until(not divisible_by_known_primes(val)) table.insert(found_primes, val) if val > limit then return nil else return val end end return next_prime, found_primes, nil end sum = 0 for ii in primes_below(LIMIT) do sum = sum + ii end print(sum) return sum luerl-1.2.3/examples/euler/problem_004.lua0000664000175000017500000000121214677012037020703 0ustar debalancedebalance-- A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 99. -- Find the largest palindrome made from the product of two 3-digit numbers. function is_palindrome(number) local str = number .. '' for ii = 1, (#str / 2) do if string.byte(str,ii) ~= string.byte(str, -ii) then return false end end return true end LOW = 100 --HIGH = 999 HIGH = 199 highest = 0 for ii = LOW, HIGH do for jj = LOW, HIGH do num = ii * jj if is_palindrome(num) then highest = (num > highest) and num or highest end end end print(highest) return highest luerl-1.2.3/examples/euler/problem_008.lua0000664000175000017500000000263714677012037020723 0ustar debalancedebalance-- Find the greatest product of five consecutive digits in the 1000-digit number. -- NUMBER = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450" NUMBER = "11111222221" largest = 0 for ii = 1, (#NUMBER-5) do digits = string.sub(NUMBER, ii, ii+5) sum = string.sub(digits, 1, 1) * string.sub(digits, 2, 2) * string.sub(digits, 3, 3) * string.sub(digits, 4, 4) * string.sub(digits, 5, 5) largest = (sum > largest) and sum or largest end print(largest) return largest luerl-1.2.3/examples/euler/problem_005.lua0000664000175000017500000000210714677012037020710 0ustar debalancedebalance-- 2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder. -- What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20? LIMIT = 20 function prime_factors(n) local function factor(_, val) if n > 1 then while n % val > 0 do val = val + ( val == 2 and 1 or 2) if val * val > n then val = n end end n = n / val return val end end return factor, nil, 2 end function factorize(number) factors = {} for p in prime_factors(number) do factors[p] = factors[p] and factors[p] + 1 or 1 end return factors end function collapse(dict1, dict2) dict = {} for key, val in pairs(dict1) do dict[key] = math.max(val, dict2[key] or 0) end for key, val in pairs(dict2) do dict[key] = math.max(val, dict1[key] or 0) end return dict end factors = {} for ii = 2, LIMIT do factors = collapse(factors, factorize(ii)) end product = 1 for key, val in pairs(factors) do product = product * (key ^ val) end print(product) return product luerl-1.2.3/examples/minibench/0000775000175000017500000000000014677012037017001 5ustar debalancedebalanceluerl-1.2.3/examples/minibench/Makefile0000664000175000017500000000046514677012037020446 0ustar debalancedebalanceEXAMPLES = minibench \ minibench2 ROOTDIR = ../.. SRCDIR = $(ROOTDIR)/src BEAMDIR = $(ROOTDIR)/ebin all: $(EXAMPLES) clean: rm -f *.beam erl_crash.dump .SECONDARY: %.beam: %.erl $(SRCDIR)/*.hrl erlc -I $(SRCDIR) $< %: %.beam erl -pa $(BEAMDIR) -s $@ run -s init stop -noshell .PHONY: all clean luerl-1.2.3/examples/minibench/minibench2.erl0000664000175000017500000001460014677012037021524 0ustar debalancedebalance%% File : minibench2.erl %% Author : Henning Diedrich %% File : luerl/examples/minibench/minibench.erl %% Purpose : Benchmark for frequent calls to small Luerl scripts %% Author : Henning Diedrich %% Use $ cd ./examples/minibench %% $ erlc minibench.erl %% $ erl -pa ../../ebin -s minibench run -s init stop -noshell %% Or $ make minibench -module(minibench2). -export([run/0]). run() -> io:format("----------------------------------------------------------~n"), io:format("This is a benchmark of frequent fast calls into Luerl.~n"), % I. eval and execute io:format("----------------------------------------------------------~n"), io:format("Init state, parse and execute 'a = 7.33; b = 9000; c = (33 * a / b) ^ 15 * a + b'~n"), I1 = 10000, {T1,_State} = timer:tc(fun() -> do_loop(I1, "a = 7.33; b = 9000; c = (33 * a / b) ^ 15 * a + b; return c") end), io:format("Adding Up: ~p microseconds for ~p x calling Lua and returning the result of a = 7.33; b = 9000; c = (33 * a / b) ^ 15 * a + b.~n", [T1,I1]), io:format("Per call: ~p microseconds.~n", [T1/I1]), % II. eval once, then only execute io:format("----------------------------------------------------------~n"), io:format("Init state, and execute pre-parsed 'a = 7.33; b = 9000; c = (33 * a / b) ^ 15 * a + b'~n"), I2 = 10000, {ok, Chunk2, State2} = luerl:load("a = 7.33; b = 9000; c = (33 * a / b) ^ 15 * a + b; return c", luerl:init()), {T2,_State21} = timer:tc(fun() -> do_loop_state(I2, Chunk2, State2) end), io:format("Adding Up: ~p microseconds for ~p x calling Lua and returning the result of a = 7.33; b = 9000; c = (33 * a / b) ^ 15 * a + b.~n", [T2,I2]), io:format("Per call: ~p microseconds.~n", [T2/I2]), % III. eval once, then only execute io:format("----------------------------------------------------------~n"), io:format("Execute pre-parse execute 'a = 7.33; b = 9000; c = (33 * a / b) ^ 15 * a + b', re-using same state~n"), I3 = 10000, {ok, Chunk3, State3} = luerl:load("a = 7.33; b = 9000; c = (33 * a / b) ^ 15 * a + b; return c", luerl:init()), {T3,_State31} = timer:tc(fun() -> do_loop_state(I3, Chunk3, State3) end), io:format("Adding Up: ~p microseconds for ~p x calling Lua and returning the result of a = 7.33; b = 9000; c = (33 * a / b) ^ 15 * a + b.~n", [T3,I3]), io:format("Per call: ~p microseconds.~n", [T3/I3]), % IV. measure but state initialization io:format("----------------------------------------------------------~n"), io:format("Pure initialization of Lua state~n"), I4 = 10000, {T4,_State41} = timer:tc(fun() -> [luerl:init() || _ <- lists:seq(1,I4)] end), io:format("Adding Up: ~p microseconds for ~p x initializing a Lua state.~n", [T4,I4]), io:format("Per call: ~p microseconds.~n", [T4/I4]), % V. eval once, then only execute, re-use previous state io:format("----------------------------------------------------------~n"), io:format("Execute pre-parsed 'a = 7.33; b = 9000; c = (33 * a / b) ^ 15 * a + b', re-using state from last result~n"), I5 = 10000, {ok, Chunk5, State5} = luerl:load("a = 7.33; b = 9000; c = (33 * a / b) ^ 15 * a + b; return c", luerl:init()), {T5,_State51} = timer:tc(fun() -> do_loop_chain(I5, Chunk5, State5) end), io:format("Adding Up: ~p microseconds for ~p x calling Lua and returning the result of a = 7.33; b = 9000; c = (33 * a / b) ^ 15 * a + b.~n", [T5,I5]), io:format("Per call: ~p microseconds.~n", [T5/I5]), % Vb. function call, re-use previous state io:format("----------------------------------------------------------~n"), io:format("Execute pre-parsed function with 'a = 7.33; b = 9000; c = (33 * a / b) ^ 15 * a + b', re-using state from last result~n"), I5b = 10000, State5b = luerl:init(), {[],State5b1} = luerl:do("function OneAndOne() a = 7.33; b = 9000; c = (33 * a / b) ^ 15 * a + b; return c end", State5b), io:format("-"), {T5b,_State5b1} = timer:tc(fun() -> do_loop_state(I5b, "return OneAndOne()", State5b1) end), io:format("Adding Up: ~p microseconds for ~p x calling Lua and returning the result of a = 7.33; b = 9000; c = (33 * a / b) ^ 15 * a + b.~n", [T5b,I5b]), io:format("Per call: ~p microseconds.~n", [T5b/I5b]), % Vc. empty function call, re-use previous state io:format("----------------------------------------------------------~n"), io:format("Execute empty function, re-using state from last result~n"), I5c = 10000, State5c = luerl:init(), {[],State5c1} = luerl:do("function EmptyFunc() end", State5c), io:format("-"), {T5c,_State5c1} = timer:tc(fun() -> do_loop_state(I5c, "EmptyFunc()", State5c1) end), io:format("Adding Up: ~p microseconds for ~p x calling empty function.~n", [T5c,I5c]), io:format("Per call: ~p microseconds.~n", [T5c/I5c]), % VI. measure but parsing io:format("----------------------------------------------------------~n"), io:format("Pure parsing~n"), I6 = 10000, {T6,_State61} = timer:tc(fun() -> [luerl:load("a = 7.33; b = 9000; c = (33 * a / b) ^ 15 * a + b; return c", luerl:init()) || _ <- lists:seq(1,I6)] end), io:format("Adding Up: ~p microseconds for ~p x calling Lua and returning the result of a = 7.33; b = 9000; c = (33 * a / b) ^ 15 * a + b.~n", [T6,I6]), io:format("Per call: ~p microseconds.~n", [T6/I6]), % VII. Parse and execute io:format("----------------------------------------------------------~n"), io:format("Parse and execute 'a = 7.33; b = 9000; c = (33 * a / b) ^ 15 * a + b', re-using state~n"), I7 = 10000, State7 = luerl:init(), {T7,_State71} = timer:tc(fun() -> do_loop_state(I7, "a = 7.33; b = 9000; c = (33 * a / b) ^ 15 * a + b; return c", State7) end), io:format("Adding Up: ~p microseconds for ~p x calling Lua and returning the result of a = 7.33; b = 9000; c = (33 * a / b) ^ 15 * a + b.~n", [T7,I7]), io:format("Per call: ~p microseconds.~n", [T7/I7]), done. % helper do_loop(N, Chunk) when N > 0 -> luerl:do(Chunk, luerl:init()), do_loop(N-1, Chunk); do_loop(0, _) -> ok. do_loop_state(N, Chunk, State) when N > 0 -> luerl:do(Chunk, State), do_loop_state(N-1, Chunk, State); do_loop_state(0, _, _) -> ok. do_loop_chain(N, Chunk, State0) when N > 0 -> {_,State1} = luerl:do(Chunk, State0), do_loop_chain(N-1, Chunk, State1); do_loop_chain(0, _, _) -> ok. luerl-1.2.3/examples/minibench/minibench.erl0000664000175000017500000001054414677012037021445 0ustar debalancedebalance%% File : mini.erl %% Author : Henning Diedrich %% File : luerl/examples/minibench/minibench.erl %% Purpose : Benchmark for frequent calls to small Luerl scripts %% Author : Henning Diedrich %% Use $ cd ./examples/minibench %% $ erlc minibench.erl %% $ erl -pa ../../ebin -s minibench run -s init stop -noshell %% Or $ make minibench -module(minibench). -export([run/0]). run() -> io:format("----------------------------------------------------------~n"), io:format("This is a benchmark of frequent fast calls into Luerl.~n"), % I. eval and execute io:format("----------------------------------------------------------~n"), io:format("Init state, parse and execute '1 + 1'~n"), I1 = 100000, {T1,_State} = timer:tc(fun() -> do_loop(I1, "return 1 + 1") end), io:format("Adding Up: ~p microseconds for ~p x calling Lua and returning the result of 1 + 1.~n", [T1,I1]), io:format("Per call: ~p microseconds.~n", [T1/I1]), % II. eval once, then only execute io:format("----------------------------------------------------------~n"), io:format("Init state, and execute pre-parsed '1 + 1'~n"), I2 = 100000, {ok, Chunk2, State2} = luerl:load("return 1 + 1", luerl:init()), {T2,_State21} = timer:tc(fun() -> do_loop_state(I2, Chunk2, State2) end), io:format("Adding Up: ~p microseconds for ~p x calling Lua and returning the result of 1 + 1.~n", [T2,I2]), io:format("Per call: ~p microseconds.~n", [T2/I2]), % III. eval once, then only execute io:format("----------------------------------------------------------~n"), io:format("Execute pre-parse execute '1 + 1', re-using same state~n"), I3 = 100000, State3 = luerl:init(), {ok, Chunk3, State31} = luerl:load("return 1 + 1", State3), {T3,_State31} = timer:tc(fun() -> do_loop_state(I3, Chunk3, State31) end), io:format("Adding Up: ~p microseconds for ~p x calling Lua and returning the result of 1 + 1.~n", [T3,I3]), io:format("Per call: ~p microseconds.~n", [T3/I3]), % IV. measure but state initialization io:format("----------------------------------------------------------~n"), io:format("Pure initialization of Lua state~n"), I4 = 100000, {T4,_State41} = timer:tc(fun() -> [luerl:init() || _ <- lists:seq(1,I4)] end), io:format("Adding Up: ~p microseconds for ~p x initializing Lua state.~n", [T4,I4]), io:format("Per call: ~p microseconds.~n", [T4/I4]), % V. eval once, then only execute, re-use previous state io:format("----------------------------------------------------------~n"), io:format("Execute pre-parsed '1 + 1', re-using state from last result~n"), I5 = 100000, State5 = luerl:init(), {ok, Chunk5, State51} = luerl:load("return 1 + 1", State5), {T5,_State51} = timer:tc(fun() -> do_loop_chain(I5, Chunk5, State51) end), io:format("Adding Up: ~p microseconds for ~p x calling Lua and returning the result of 1 + 1.~n", [T5,I5]), io:format("Per call: ~p microseconds.~n", [T5/I5]), % VI. measure but parsing io:format("----------------------------------------------------------~n"), io:format("Pure parsing~n"), I6 = 100000, {T6,_State61} = timer:tc(fun() -> [luerl:load("return 1 + 1", luerl:init()) || _ <- lists:seq(1,I6)] end), io:format("Adding Up: ~p microseconds for ~p x calling Lua and returning the result of 1 + 1.~n", [T6,I6]), io:format("Per call: ~p microseconds.~n", [T6/I6]), % VII. Parse and execute io:format("----------------------------------------------------------~n"), io:format("Parse and execute '1 + 1', re-using state~n"), I7 = 100000, State7 = luerl:init(), {T7,_State71} = timer:tc(fun() -> do_loop_state(I7, "return 1 + 1", State7) end), io:format("Adding Up: ~p microseconds for ~p x calling Lua and returning the result of 1 + 1.~n", [T7,I7]), io:format("Per call: ~p microseconds.~n", [T7/I7]), done. % helper do_loop(N, Chunk) when N > 0 -> luerl:do(Chunk, luerl:init()), do_loop(N-1, Chunk); do_loop(0, _) -> ok. do_loop_state(N, Chunk, State) when N > 0 -> luerl:do(Chunk, State), do_loop_state(N-1, Chunk, State); do_loop_state(0, _, _) -> ok. do_loop_chain(N, Chunk, State0) when N > 0 -> {_,State1} = luerl:do(Chunk, State0), do_loop_chain(N-1, Chunk, State1); do_loop_chain(0, _, _) -> ok. luerl-1.2.3/get_comp_opts.escript0000664000175000017500000000465114677012037017472 0ustar debalancedebalance#! /usr/bin/env escript %% -*- mode: erlang; indent-tabs-mode: nil -*- %% Define a number of compiler options. We first work out the current %% Erlang version and from the we can define the various options. %% Define the makefile variables HAS_MAPS, HAS_FULL_KEYS, %% NEW_REC_CORE, NEW_RAND, HAS_FLOOR, HAS_CEIL and NEW_STACKTRACE %% depending on version of Erlang. main(_) -> Version = otp_release(), CompOpts = comp_opts(Version), file:write_file("comp_opts.mk", "COMP_OPTS = " ++ CompOpts ++ "\n"). %% Get the release number. %% We have stolen the idea and most of the code from rebar3. otp_release() -> case erlang:system_info(otp_release) of [$R,N1|Rest] when is_integer(N1) -> %% If OTP <= R16, take the digits. [N1|Rest]; Rel -> %% If OTP >= 17.x, erlang:system_info(otp_release) returns %% just the major version number. File = filename:join([code:root_dir(),"releases",Rel,"OTP_VERSION"]), case file:read_file(File) of {error, _} -> Rel; {ok, Vsn} -> Size = byte_size(Vsn), %% The shortest vsn string consists of at least %% two digits followed by "\n". Therefore, it's %% safe to assume Size >= 3. case binary:part(Vsn, {Size, -3}) of <<"**\n">> -> binary:bin_to_list(Vsn, {0, Size - 3}); _ -> binary:bin_to_list(Vsn, {0, Size - 1}) end end end. comp_opts(Version) -> Copts0 = "-DERLANG_VERSION=\\\"" ++ Version ++ "\\\"" ++ " ", Copts0 ++ append_copts(Version, [{"17","HAS_MAPS"}, {"18","HAS_FULL_KEYS"}, {"19","NEW_REC_CORE"}, {"19","NEW_RAND"}, {"20","NEW_BOOL_GUARD"}, {"20","HAS_FLOOR"}, {"20","HAS_CEIL"}, {"21","NEW_STACKTRACE"}, {"23","EEP48"}]). append_copts(Version, [{Ver,Opt}|Opts]) -> Rest = append_copts(Version, Opts), if Version >= Ver -> "-D" ++ Opt ++ "=true" ++ " " ++ Rest; true -> Rest end; append_copts(_Version, []) -> []. luerl-1.2.3/include/0000775000175000017500000000000014677012037014652 5ustar debalancedebalanceluerl-1.2.3/include/luerl.hrl0000664000175000017500000001642214677012037016511 0ustar debalancedebalance%% Copyright (c) 2013-2019 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% File : luerl.hrl %% Author : Robert Virding %% Purpose : The basic macros/records for Luerl. %% We include the whole environment in one structure even if fields %% come from logically different parts. This make it easier to pass %% around but does mean that there will be more explicit fiddleling to %% get it right. See block/2 and functioncall/4 for examples of this. -record(luerl, {tabs, %Table table envs, %Environment table usds, %Userdata table fncs, %Function table g, %Global table %% stk=[], %Current stack cs=[], %Current call stack %% meta=[], %Data type metatables rand, %Random state tag, %Unique tag trace_func=none, %Trace function trace_data %Trace data }). %% Table structure. -record(tstruct, {data, %Data table/array free, %Index free list next %Next index }). %% Metatables for atomic datatypes. -record(meta, {nil=nil, boolean=nil, number=nil, string=nil }). %% Frames for the call stack. %% Call return frame -record(call_frame, {func,args, %Function, arguments lvs, %Local variables env, %Environment is=[], %Instructions cont=[] %Continuation }). %% Loop break frame -record(loop_frame, {lvs, %Local variables stk, %Stack env, %Environment is=[], %Instructions cont=[] %Continuation }). %% Current line -record(current_line, {line, %Line file %File name }). %% Return -record(return, {rets %Return values }). %% Data types. -record(tref, {i}). %Table reference, index -define(IS_TREF(T), is_record(T, tref)). -record(table, {a,d=[],meta=nil}). %Table type, array, dict, meta -record(eref, {i}). %Environment reference, index -define(IS_EREF(E), is_record(E, eref)). -record(usdref, {i}). %Userdata reference, index -define(IS_USDREF(U), is_record(U, usdref)). -record(userdata, {d,meta=nil}). %Userdata type, data and meta -record(thread, {}). %Thread type %% There are two function types, the Lua one, and the Erlang one. %% The environment with upvalues is defined when the function is %% referenced and can vary if the function is referenced many %% times. Hence it is in the reference not in the the definition. -record(funref, {i,env=[]}). %Function reference -define(IS_FUNREF(F), is_record(F, funref)). -record(lua_func,{anno=[], %Annotation funrefs=[], %Functions directly referenced lsz, %Local var size %% loc=not_used, %Local var block template esz, %Env var size %% env=not_used, %Local env block template pars, %Parameter types body}). %Code block -define(IS_LUAFUNC(F), is_record(F, lua_func)). -record(erl_func,{code}). %Erlang code (fun) -define(IS_ERLFUNC(F), is_record(F, erl_func)). -record(erl_mfa,{m,f,a}). %Erlang code (MFA) -define(IS_ERLMFA(F), is_record(F, erl_mfa)). %% Test if it a function, of either sort. -define(IS_FUNCTION(F), (?IS_FUNREF(F) orelse ?IS_ERLFUNC(F) orelse ?IS_ERLMFA(F))). %% Testing for integers/integer floats or booleans. -define(IS_FLOAT_INT(N), (round(N) == N)). -define(IS_FLOAT_INT(N,I), ((I=round(N)) == N)). -define(IS_TRUE(X), (((X) =/= nil) and ((X) =/= false))). %% Different methods for storing tables in the global data #luerl{}. %% Access through macros to allow testing with different storage %% methods. This is inefficient with ETS tables where it would %% probably be better to use bags and access with match/select. %% Set which table store to use. We check if we have full maps before %% we use them just to protect ourselves. -ifdef(HAS_FULL_KEYS). -define(TS_USE_MAPS, true). -else. -define(TS_USE_ARRAY, true). -endif. %% -define(TS_USE_ARRAY, true). -ifdef(TS_USE_MAPS). -define(MAKE_TABLE(), maps:new()). -define(GET_TABLE(N, Ts), maps:get(N, Ts)). -define(SET_TABLE(N, T, Ts), maps:put(N, T, Ts)). -define(UPD_TABLE(N, Upd, Ts), maps:update_with(N, Upd, Ts)). -define(DEL_TABLE(N, Ts), maps:remove(N, Ts)). -define(FILTER_TABLES(Pred, Ts), maps:filter(Pred, Ts)). -define(FOLD_TABLES(Fun, Acc, Ts), maps:fold(Fun, Acc, Ts)). -endif. -ifdef(TS_USE_ARRAY). %% Use arrays to handle tables. -define(MAKE_TABLE(), array:new()). -define(GET_TABLE(N, Ar), array:get(N, Ar)). -define(SET_TABLE(N, T, Ar), array:set(N, T, Ar)). -define(UPD_TABLE(N, Upd, Ar), array:set(N, (Upd)(array:get(N, Ar)), Ar)). -define(DEL_TABLE(N, Ar), array:reset(N, Ar)). -define(FILTER_TABLES(Pred, Ar), ((fun (___Def) -> ___Fil = fun (___K, ___V) -> case Pred(___K, ___V) of true -> ___V; false -> ___Def end end, array:sparse_map(___Fil, Ar) end)(array:default(Ar)))). -define(FOLD_TABLES(Fun, Acc, Ar), array:sparse_foldl(Fun, Acc, Ar)). -endif. -ifdef(TS_USE_ORDDICT). %% Using orddict to handle tables. -define(MAKE_TABLE(), orddict:new()). -define(GET_TABLE(N, Ts), orddict:fetch(N, Ts)). -define(SET_TABLE(N, T, Ts), orddict:store(N, T, Ts)). -define(UPD_TABLE(N, Upd, Ts), orddict:update(N, Upd, Ts)). -define(DEL_TABLE(N, Ts), orddict:erase(N, Ts)). -define(FILTER_TABLES(Pred, Ts), orddict:filter(Pred, Ts)). -define(FOLD_TABLES(Fun, Acc, Ts), orddict:fold(Fun, Acc, Ts)). -endif. -ifdef(TS_USE_PD). %% Use the process dictionary to handle tables. -define(MAKE_TABLE(), ok). -define(GET_TABLE(N, Pd), get(N)). -define(SET_TABLE(N, T, Pd), put(N, T)). -define(UPD_TABLE(N, Upd, Pd), put(N, (Upd)(get(N)))). -define(DEL_TABLE(N, Pd), erase(N)). -define(FILTER_TABLES(Pred, Pd), Pd). %This needs work -define(FOLD_TABLES(Fun, Acc, Pd), Pd). %This needs work -endif. -ifdef(TS_USE_ETS). %% Use ETS to handle tables. Must get return values right! -define(MAKE_TABLE(),ets:new(luerl_tables, [set])). -define(GET_TABLE(N, E), ets:lookup_element(E, N, 2)). -define(SET_TABLE(N, T, E), begin ets:insert(E, {N,T}), E end). -define(UPD_TABLE(N, Upd, E), begin ets:update_element(E, N, {2,(Upd)(ets:lookup_element(E, N, 2))}), E end). -define(DEL_TABLE(N, E), begin ets:delete(E, N), E end). -define(FILTER_TABLES(Pred, E), E). %This needs work -define(FOLD_TABLES(Fun, Acc, E), ets:foldl(fun ({___K, ___T}, ___Acc) -> Fun(___K, ___T, ___Acc) end, Acc, E)). -endif. %% Define CATCH to handle deprecated get_stacktrace/0 -ifdef(NEW_STACKTRACE). -define(CATCH(C, E, S), C:E:S ->). -else. -define(CATCH(C, E, S), C:E -> S = erlang:get_stacktrace(),). -endif.