vanilla-wow-addons – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | --[[-------------------------------------------------------------------------------- |
2 | ItemSyncCore Core Framework |
||
3 | |||
4 | Author: Derkyle |
||
5 | Website: http://www.manaflux.com |
||
6 | -----------------------------------------------------------------------------------]] |
||
7 | |||
8 | BINDING_HEADER_ITEMSYNC_HEADER = "ItemSync"; |
||
9 | |||
10 | --Hook chat messages |
||
11 | local ISync_ChatMessageTypes = { |
||
12 | "CHAT_MSG_SYSTEM", |
||
13 | "CHAT_MSG_SAY", |
||
14 | "CHAT_MSG_TEXT_EMOTE", |
||
15 | "CHAT_MSG_YELL", |
||
16 | "CHAT_MSG_WHISPER", |
||
17 | "CHAT_MSG_PARTY", |
||
18 | "CHAT_MSG_GUILD", |
||
19 | "CHAT_MSG_OFFICER", |
||
20 | "CHAT_MSG_CHANNEL", |
||
21 | "CHAT_MSG_RAID", |
||
22 | "CHAT_MSG", |
||
23 | "CHAT_MSG_LOOT", |
||
24 | "CHAT_MSG_EMOTE", |
||
25 | "CHAT_MSG_WHISPER_INFORM", |
||
26 | "CHAT_MSG_MONSTER_EMOTE", |
||
27 | "CHAT_MSG_MONSTER_SAY", |
||
28 | "CHAT_MSG_MONSTER_WHISPER", |
||
29 | "CHAT_MSG_MONSTER_YELL", |
||
30 | |||
31 | }; |
||
32 | |||
33 | local ISync_lOriginal_MerchantFrame_Update; |
||
34 | local ISync_lOriginal_ChatEdit_OnTextChanged; |
||
35 | |||
36 | --------------------------------------------------- |
||
37 | -- ISync:OnLoad() |
||
38 | --------------------------------------------------- |
||
39 | function ISync:OnLoad() |
||
40 | |||
41 | this:RegisterEvent("VARIABLES_LOADED"); |
||
42 | this:RegisterEvent("PLAYER_ENTERING_WORLD"); |
||
43 | this:RegisterEvent("PLAYER_LEAVING_WORLD"); |
||
44 | this:RegisterEvent("PLAYER_TARGET_CHANGED"); |
||
45 | this:RegisterEvent("BANKFRAME_OPENED"); |
||
46 | this:RegisterEvent("AUCTION_ITEM_LIST_UPDATE"); |
||
47 | this:RegisterEvent("MERCHANT_SHOW"); |
||
48 | this:RegisterEvent("BAG_UPDATE"); |
||
49 | this:RegisterEvent("UPDATE_MOUSEOVER_UNIT"); |
||
50 | this:RegisterEvent("ADDON_LOADED"); |
||
51 | |||
52 | --register chat types |
||
53 | for index, value in ISync_ChatMessageTypes do |
||
54 | this:RegisterEvent(value); |
||
55 | end |
||
56 | |||
57 | --Hook ChatEdit_OnTextChanged for type links |
||
58 | ISync_lOriginal_ChatEdit_OnTextChanged = ChatEdit_OnTextChanged; |
||
59 | ChatEdit_OnTextChanged = ISyncCore_ChatEdit_OnTextChanged; |
||
60 | |||
61 | --Hook for the Merchant Prices |
||
62 | ISync_lOriginal_MerchantFrame_Update = MerchantFrame_Update; |
||
63 | MerchantFrame_Update = ISyncCore_MerchantFrame_Update; |
||
64 | |||
65 | --load primary |
||
66 | ISync:PrimaryLoad(); |
||
67 | |||
68 | end |
||
69 | |||
70 | |||
71 | |||
72 | |||
73 | ----------------------------------------------------------------------------------------------------- |
||
74 | ----------------------------------------------------------------------------------------------------- |
||
75 | ----------------------------------------------------------------------------------------------------- |
||
76 | ----------------------------------------------------------------------------------------------------- |
||
77 | ----------------------------------------------------------------------------------------------------- |
||
78 | ----------------------------------------------------------------------------------------------------- |
||
79 | |||
80 | --------------------------------------------------- |
||
81 | -- ISync:GrabDataProfile() |
||
82 | --------------------------------------------------- |
||
83 | function ISync:GrabDataProfile() |
||
84 | |||
85 | --main attributes |
||
86 | local RlmCount = ISync:SetVar({"REALMS","REALMCOUNT"}, 0); --check if not on |
||
87 | ISync:SetVar({"OPT","SERVER_MERGE"}, 1); --check if not on |
||
88 | |||
89 | --first check realm stuff |
||
90 | if(not GetCVar("realmName")) then return nil; end |
||
91 | |||
92 | --get data |
||
93 | local sRlm = string.gsub(GetCVar("realmName"), "^%s*(.-)%s*$", "%1"); |
||
94 | if(not sRlm) then return nil; end |
||
95 | |||
96 | sRlm = string.upper(sRlm); --convert to uppercase |
||
97 | |||
98 | if(not ISync:SetVar({"REALMS",sRlm}, RlmCount, "CHK")) then |
||
99 | ISync:SetVar({"REALMS",sRlm}, RlmCount); --save |
||
100 | ISync:SetVar({"REALMS","REALMCOUNT"}, RlmCount + 1, "TRUE"); --increment, TRUE = force |
||
101 | end |
||
102 | |||
103 | --create database if it doesn't exist |
||
104 | if(not ISyncDB[RlmCount]) then ISyncDB[RlmCount] = { }; end |
||
105 | |||
106 | --check if merged, if so then use the zero first realm |
||
107 | if(ISync:SetVar({"OPT","SERVER_MERGE"}, 1) == 1) then return 0; else return tonumber(ISync:SetVar({"REALMS",sRlm}, RlmCount)); end |
||
108 | |||
109 | |||
110 | end |
||
111 | |||
112 | |||
113 | ----------------------------------------------------------------------------------------------------- |
||
114 | ----------------------------------------------------------------------------------------------------- |
||
115 | ----------------------------------------------------------------------------------------------------- |
||
116 | ----------------------------------------------------------------------------------------------------- |
||
117 | ----------------------------------------------------------------------------------------------------- |
||
118 | ----------------------------------------------------------------------------------------------------- |
||
119 | |||
120 | |||
121 | --------------------------------------------------- |
||
122 | -- ISync:SetVar() |
||
123 | --------------------------------------------------- |
||
124 | function ISync:SetVar(sArgs, nBool, sOpt) |
||
125 | |||
126 | if(not sArgs or not nBool) then return nil; end |
||
127 | if(type(sArgs) ~= "table") then return nil; end |
||
128 | if(getn(sArgs) <= 0) then return nil; end |
||
129 | if(getn(sArgs) > 2) then return nil; end |
||
130 | |||
131 | |||
132 | if(sOpt and sOpt == "CHK") then |
||
133 | if(ISyncOpt and ISyncOpt[sArgs[1]] and ISyncOpt[sArgs[1]][sArgs[2]]) then return 1; else return nil; end |
||
134 | end |
||
135 | |||
136 | |||
137 | if(sOpt and sOpt == "COMPARE") then |
||
138 | |||
139 | if(ISyncOpt and ISyncOpt[sArgs[1]] and ISyncOpt[sArgs[1]][sArgs[2]]) then |
||
140 | |||
141 | if(tostring(ISyncOpt[sArgs[1]][sArgs[2]]) == tostring(nBool)) then |
||
142 | return 1; |
||
143 | else |
||
144 | return nil; |
||
145 | end |
||
146 | |||
147 | else |
||
148 | return nil; |
||
149 | end |
||
150 | end |
||
151 | |||
152 | |||
153 | if(not ISyncOpt) then ISyncOpt = {}; end |
||
154 | if(not ISyncOpt[sArgs[1]]) then ISyncOpt[sArgs[1]] = {}; end |
||
155 | if(not ISyncOpt[sArgs[1]][sArgs[2]]) then ISyncOpt[sArgs[1]][sArgs[2]] = nBool; end |
||
156 | |||
157 | --force it |
||
158 | if(sOpt) then |
||
159 | |||
160 | sOpt = tostring(sOpt); --convert to string |
||
161 | |||
162 | if( sOpt == "TRUE" or string.upper(sOpt) == "TRUE") then |
||
163 | |||
164 | --force the change |
||
165 | ISyncOpt[sArgs[1]][sArgs[2]] = nBool; |
||
166 | |||
167 | return ISyncOpt[sArgs[1]][sArgs[2]]; |
||
168 | |||
169 | end |
||
170 | end |
||
171 | |||
172 | return ISyncOpt[sArgs[1]][sArgs[2]]; |
||
173 | end |
||
174 | |||
175 | |||
176 | |||
177 | --------------------------------------------------- |
||
178 | -- ISync:SetOpt() |
||
179 | --------------------------------------------------- |
||
180 | function ISync:SetOpt(sFrame, sType, sArgs, nBool) |
||
181 | |||
182 | if(not sFrame or not sType or not sArgs or not nBool) then return nil; end |
||
183 | if(type(sArgs) ~= "table") then return nil; end |
||
184 | if(getn(sArgs) <= 0) then return nil; end |
||
185 | if(getn(sArgs) > 2) then return nil; end |
||
186 | if(not tonumber(nBool)) then return nil; end |
||
187 | |||
188 | nBool = tonumber(nBool) or 0; |
||
189 | |||
190 | local iChk; |
||
191 | |||
192 | --check if it's created or not, if so then return value |
||
193 | if(not ISyncOpt or not ISyncOpt[sArgs[1]] or not ISyncOpt[sArgs[1]][sArgs[2]]) then |
||
194 | iChk = ISync:SetVar(sArgs, nBool); |
||
195 | else |
||
196 | iChk = ISync:SetVar(sArgs, nBool, "TRUE"); |
||
197 | end |
||
198 | |||
199 | if(not iChk) then iChk = 0; else iChk = tonumber(iChk); end |
||
200 | |||
201 | --check types |
||
202 | if(sType == "checkbutton") then |
||
203 | sFrame:SetChecked(iChk); |
||
204 | elseif(sType == "slider") then |
||
205 | sFrame:SetValue(iChk); |
||
206 | elseif(sType == "frame") then |
||
207 | if(iChk == 0) then sFrame:Hide(); end |
||
208 | if(iChk == 1) then sFrame:Show(); end |
||
209 | end |
||
210 | |||
211 | |||
212 | return iChk; |
||
213 | |||
214 | end |
||
215 | |||
216 | |||
217 | |||
218 | --------------------------------------------------- |
||
219 | -- ISync:Chk() |
||
220 | --------------------------------------------------- |
||
221 | function ISync:Chk(sName, sGet, sOperator, sNum) |
||
222 | |||
223 | if(not ISyncDB) then return nil; end |
||
224 | if(not sName or not sGet) then return nil; end |
||
225 | |||
226 | if(not ISYNC_REALM_NUM) then ISync:GrabDataProfile(); end |
||
227 | if(not ISYNC_REALM_NUM) then return nil; end |
||
228 | |||
229 | if(not ISyncDB[ISYNC_REALM_NUM]) then return nil; end |
||
230 | if(not ISyncDB[ISYNC_REALM_NUM][sName]) then return nil; end |
||
231 | |||
232 | --if only sGet |
||
233 | if(sGet and not sOperator) then |
||
234 | return ISync:FetchDB(sName, sGet) or nil; |
||
235 | |||
236 | --if get and operator then preform proper action |
||
237 | elseif(sGet and sOperator) then |
||
238 | |||
239 | local getNum = ISync:FetchDB(sName, sGet) or nil; |
||
240 | |||
241 | if(not tonumber(sNum)) then return nil; end |
||
242 | if(not getNum) then return nil; end |
||
243 | if(not tonumber(getNum)) then return nil; end |
||
244 | |||
245 | getNum = tonumber(getNum); --convert |
||
246 | |||
247 | if(sOperator == "==") then |
||
248 | if(getNum == sNum) then return 1; else return nil; end |
||
249 | |||
250 | elseif(sOperator == "~=") then |
||
251 | if(getNum ~= sNum) then return 1; else return nil; end |
||
252 | |||
253 | elseif(sOperator == ">") then |
||
254 | if(getNum > sNum) then return 1; else return nil; end |
||
255 | |||
256 | elseif(sOperator == "<") then |
||
257 | if(getNum < sNum) then return 1; else return nil; end |
||
258 | |||
259 | elseif(sOperator == ">=") then |
||
260 | if(getNum >= sNum) then return 1; else return nil; end |
||
261 | |||
262 | elseif(sOperator == "<=") then |
||
263 | if(getNum <= sNum) then return 1; else return nil; end |
||
264 | else |
||
265 | return nil; |
||
266 | end |
||
267 | |||
268 | |||
269 | else |
||
270 | --we cannot have empty operators or empty values to compare. |
||
271 | return nil; |
||
272 | end |
||
273 | |||
274 | |||
275 | return nil; |
||
276 | end |
||
277 | |||
278 | |||
279 | |||
280 | ----------------------------------------------------------------------------------------------------- |
||
281 | ----------------------------------------------------------------------------------------------------- |
||
282 | ----------------------------------------------------------------------------------------------------- |
||
283 | ----------------------------------------------------------------------------------------------------- |
||
284 | ----------------------------------------------------------------------------------------------------- |
||
285 | ----------------------------------------------------------------------------------------------------- |
||
286 | |||
287 | --------------------------------------------------- |
||
288 | -- ISync:Print() |
||
289 | --------------------------------------------------- |
||
290 | function ISync:Print(sMsg) |
||
291 | if(DEFAULT_CHAT_FRAME) then DEFAULT_CHAT_FRAME:AddMessage(sMsg); end |
||
292 | end |
||
293 | |||
294 | |||
295 | --------------------------------------------------- |
||
296 | -- ISync:NameFromLink |
||
297 | --------------------------------------------------- |
||
298 | function ISync:NameFromLink(sLink) |
||
299 | |||
300 | local item, name; |
||
301 | |||
302 | --check for link first |
||
303 | if(not sLink) then return nil; end |
||
304 | |||
305 | |||
306 | for item, name in string.gfind(sLink, "|Hitem:(%d+:%d+:%d+:%d+)|h%[(.-)%]|h") do |
||
307 | |||
308 | if(name) then return name; end |
||
309 | |||
310 | end--end for |
||
311 | |||
312 | |||
313 | --try a different way |
||
314 | for name in string.gfind(link, "|h%[(.-)%]|h") do |
||
315 | |||
316 | if(name) then return name; end |
||
317 | end |
||
318 | |||
319 | |||
320 | return nil; |
||
321 | |||
322 | end |
||
323 | |||
324 | |||
325 | --------------------------------------------------- |
||
326 | -- ISync:ReturnHexColor() |
||
327 | --------------------------------------------------- |
||
328 | function ISync:ReturnHexColor(sNumQuality) |
||
329 | |||
330 | sNumQuality = tonumber(sNumQuality); |
||
331 | |||
332 | local QL_Colors = { "ff9d9d9d", "ffffffff", "ff1eff00", "ff0070dd", "ffa335ee", "ffff8000", "ffffcc9d"}; |
||
333 | |||
334 | local color = QL_Colors[sNumQuality + 1]; |
||
335 | |||
336 | return color; |
||
337 | end |
||
338 | |||
339 | |||
340 | --------------------------------------------------- |
||
341 | -- ISync:ReturnHexColor() |
||
342 | --------------------------------------------------- |
||
343 | function ISync:HexReturnQuality(sHexColor) |
||
344 | |||
345 | local QL_Colors = {}; |
||
346 | QL_Colors["ff9d9d9d"] = 0; |
||
347 | QL_Colors["ffffffff"] = 1; |
||
348 | QL_Colors["ff1eff00"] = 2; |
||
349 | QL_Colors["ff0070dd"] = 3; |
||
350 | QL_Colors["ffa335ee"] = 4; |
||
351 | QL_Colors["ffff8000"] = 5; |
||
352 | QL_Colors["ffffcc9d"] = 6; |
||
353 | |||
354 | local color = QL_Colors[sHexColor]; |
||
355 | |||
356 | if(not color) then color = 0; end |
||
357 | |||
358 | return color; |
||
359 | end |
||
360 | |||
361 | |||
362 | --------------------------------------------------- |
||
363 | -- ISync:GetItemID |
||
364 | --------------------------------------------------- |
||
365 | function ISync:GetItemID(sLink) |
||
366 | |||
367 | --check for link first |
||
368 | if(not sLink) then return nil; end |
||
369 | |||
370 | local item, name; |
||
371 | |||
372 | if(string.find(sLink, "Hitem:")) then |
||
373 | |||
374 | for item in string.gfind(sLink, "|Hitem:(%d+:%d+:%d+:%d+)|") do |
||
375 | |||
376 | local item = string.gsub(item, "^(%d+):(%d+):(%d+):(%d+)$", "%1:0:%3:0"); |
||
377 | |||
378 | if(item) then |
||
379 | return item; |
||
380 | end |
||
381 | |||
382 | end--end for |
||
383 | end |
||
384 | |||
385 | if(string.find(sLink, "item:")) then |
||
386 | --try another way "item:0:0:0:0" |
||
387 | item = string.gsub(sLink, "item:(%d+):(%d+):(%d+):(%d+)$", "%1:0:%3:0") |
||
388 | if(item) then return item; end |
||
389 | end |
||
390 | |||
391 | --try another way "0:0:0:0" |
||
392 | item = string.gsub(sLink, "(%d+):(%d+):(%d+):(%d+)$", "%1:0:%3:0") |
||
393 | if(item) then return item; end |
||
394 | |||
395 | --everything has failed so just ignore |
||
396 | return nil; |
||
397 | |||
398 | end |
||
399 | |||
400 | |||
401 | |||
402 | |||
403 | --------------------------------------------------- |
||
404 | -- ISync:GetCoreID |
||
405 | --------------------------------------------------- |
||
406 | function ISync:GetCoreID(sLink) |
||
407 | |||
408 | --check for link first |
||
409 | if(not sLink) then return nil; end |
||
410 | |||
411 | local item, name; |
||
412 | |||
413 | if(string.find(sLink, "Hitem:")) then |
||
414 | |||
415 | for item in string.gfind(sLink, "|Hitem:(%d+:%d+:%d+:%d+)|") do |
||
416 | |||
417 | local item = string.gsub(item, "^(%d+):(%d+):(%d+):(%d+)$", "%1"); |
||
418 | |||
419 | if(item) then |
||
420 | return tonumber(item); |
||
421 | end |
||
422 | |||
423 | end--end for |
||
424 | |||
425 | end |
||
426 | |||
427 | if(string.find(sLink, "item:")) then |
||
428 | --try another way "item:0:0:0:0" |
||
429 | item = string.gsub(sLink, "item:(%d+):(%d+):(%d+):(%d+)$", "%1") |
||
430 | if(item) then return tonumber(item); end |
||
431 | end |
||
432 | |||
433 | --try another way "0:0:0:0" |
||
434 | item = string.gsub(sLink, "(%d+):(%d+):(%d+):(%d+)$", "%1") |
||
435 | if(item) then return tonumber(item); end |
||
436 | |||
437 | --everything has failed so just ignore |
||
438 | return nil; |
||
439 | |||
440 | end |
||
441 | |||
442 | |||
443 | |||
444 | ----------------------------------------------------------------------------------------------------- |
||
445 | ----------------------------------------------------------------------------------------------------- |
||
446 | ----------------------------------------------------------------------------------------------------- |
||
447 | ----------------------------------------------------------------------------------------------------- |
||
448 | ----------------------------------------------------------------------------------------------------- |
||
449 | ----------------------------------------------------------------------------------------------------- |
||
450 | |||
451 | --------------------------------------------------- |
||
452 | -- ISyncCore_MerchantFrame_Update |
||
453 | --------------------------------------------------- |
||
454 | function ISyncCore_MerchantFrame_Update() |
||
455 | ISync_lOriginal_MerchantFrame_Update(); --do original |
||
456 | |||
457 | ISync:VendorScan(); --do a vendor scan |
||
458 | end |
||
459 | |||
460 | |||
461 | |||
462 | --------------------------------------------------- |
||
463 | -- ISync:OnEvent() |
||
464 | --------------------------------------------------- |
||
465 | function ISync:OnEvent() |
||
466 | |||
467 | if( event == "PLAYER_LEAVING_WORLD" ) then |
||
468 | ISync_CoreFrame:UnregisterEvent("UNIT_INVENTORY_CHANGED"); |
||
469 | ISync_CoreFrame:UnregisterEvent("BAG_UPDATE"); |
||
470 | end |
||
471 | if( event == "PLAYER_ENTERING_WORLD" ) then |
||
472 | ISync_CoreFrame:RegisterEvent("UNIT_INVENTORY_CHANGED"); |
||
473 | ISync_CoreFrame:RegisterEvent("BAG_UPDATE"); |
||
474 | end |
||
475 | |||
476 | --pass to main framework |
||
477 | ISync:OnPrimaryEvent(event,arg1,arg2,arg3,arg4,arg5); |
||
478 | |||
479 | end |
||
480 | |||
481 | |||
482 | --------------------------------------------------- |
||
483 | -- ISync:OnUpdate() |
||
484 | --------------------------------------------------- |
||
485 | function ISync:OnUpdate(elapsed) |
||
486 | |||
487 | if(ISync and ISync.OnUpdateTriggered) then ISync:OnUpdateTriggered(elapsed); end |
||
488 | |||
489 | end |
||
490 | |||
491 | ----------------------------------------------------------------------------------------------------- |
||
492 | ----------------------------------------------------------------------------------------------------- |
||
493 | ----------------------------------------------------------------------------------------------------- |
||
494 | ----------------------------------------------------------------------------------------------------- |
||
495 | ----------------------------------------------------------------------------------------------------- |
||
496 | ----------------------------------------------------------------------------------------------------- |
||
497 | |||
498 | |||
499 | --TYPELINKS FUNCTIONS |
||
500 | --Inspired by Gazmik Fizzwidget |
||
501 | |||
502 | --------------------------------------------------- |
||
503 | -- ISyncCore_ChatEdit_OnTextChanged() |
||
504 | --------------------------------------------------- |
||
505 | function ISyncCore_ChatEdit_OnTextChanged() |
||
506 | |||
507 | --check for options |
||
508 | if(ISync:SetVar({"OPT","LINKFETCH"}, 1, "COMPARE")) then--show the tooltip icon |
||
509 | |||
510 | local text = this:GetText(); |
||
511 | text = ISync:FetchLink_ParseChatMSG(text); |
||
512 | this:SetText(text); |
||
513 | |||
514 | end |
||
515 | |||
516 | return ISync_lOriginal_ChatEdit_OnTextChanged(); |
||
517 | end |
||
518 | |||
519 | |||
520 | |||
521 | --------------------------------------------------- |
||
522 | -- ISync:FetchLink_ParseChatMSG |
||
523 | --------------------------------------------------- |
||
524 | function ISync:FetchLink_ParseChatMSG(text) |
||
525 | return string.gsub(text, "([|]?[h]?)%[(.-)%]([|]?[h]?)", ISync_FetchLink_SetTextLink); |
||
526 | end |
||
527 | |||
528 | |||
529 | |||
530 | --------------------------------------------------- |
||
531 | -- ISync_FetchLink_SetTextLink |
||
532 | --------------------------------------------------- |
||
533 | function ISync_FetchLink_SetTextLink(head, text, tail) |
||
534 | if (head ~= "|h" and tail ~= "|h") then |
||
535 | local link = ISync:FetchLink_ReturnLink(text); |
||
536 | if (link) then return link; end |
||
537 | end |
||
538 | return head.."["..text.."]"..tail; |
||
539 | end |
||
540 | |||
541 | |||
542 | |||
543 | |||
544 | --------------------------------------------------- |
||
545 | -- ISync:FetchLink_ReturnLink |
||
546 | --------------------------------------------------- |
||
547 | function ISync:FetchLink_ReturnLink(text) |
||
548 | |||
549 | if(not ISyncDB_Names) then return nil; end |
||
550 | |||
551 | --check |
||
552 | for index, value in ISyncDB_Names do |
||
553 | |||
554 | if(string.lower(value) == string.lower(text)) then |
||
555 | |||
556 | local name_X, link_X, quality_X, minLevel_X, class_X, subclass_X, maxStack_X, equipType_X, iconTexture_X = GetItemInfo("item:"..index..":0:0:0"); |
||
557 | |||
558 | if(name_X and link_X) then |
||
559 | |||
560 | return "|c"..ISync:ReturnHexColor(quality_X).."|H"..link_X.."|h["..name_X.."]|h|r"; |
||
561 | |||
562 | end |
||
563 | |||
564 | end--if(string.lower(value) == string.lower(text)) then |
||
565 | |||
566 | end |
||
567 | |||
568 | return nil; |
||
569 | |||
570 | end |
||
571 | |||
572 |