1<?php
2
3/*
4   ------------------------------------------------------------------------
5   FusionInventory
6   Copyright (C) 2010-2016 by the FusionInventory Development Team.
7
8   http://www.fusioninventory.org/   http://forge.fusioninventory.org/
9   ------------------------------------------------------------------------
10
11   LICENSE
12
13   This file is part of FusionInventory project.
14
15   FusionInventory is free software: you can redistribute it and/or modify
16   it under the terms of the GNU Affero General Public License as published by
17   the Free Software Foundation, either version 3 of the License, or
18   (at your option) any later version.
19
20   FusionInventory is distributed in the hope that it will be useful,
21   but WITHOUT ANY WARRANTY; without even the implied warranty of
22   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23   GNU Affero General Public License for more details.
24
25   You should have received a copy of the GNU Affero General Public License
26   along with FusionInventory. If not, see <http://www.gnu.org/licenses/>.
27
28   ------------------------------------------------------------------------
29
30   @package   FusionInventory
31   @author    David Durieux
32   @co-author
33   @copyright Copyright (c) 2010-2016 FusionInventory team
34   @license   AGPL License 3.0 or (at your option) any later version
35              http://www.gnu.org/licenses/agpl-3.0-standalone.html
36   @link      http://www.fusioninventory.org/
37   @link      http://forge.fusioninventory.org/projects/fusioninventory-for-glpi/
38   @since     2010
39
40   ------------------------------------------------------------------------
41 */
42
43if (!defined('GLPI_ROOT')) {
44   die("Sorry. You can't access directly to this file");
45}
46
47class PluginFusioninventoryStaticmisc {
48
49   /**
50   * Get task methods of this plugin fusioninventory
51   *
52   * @return array ('module'=>'value', 'method'=>'value')
53   *   module value name of plugin
54   *   method value name of method
55   **/
56   static function task_methods() {
57
58      $a_tasks = array(
59            array(   'module'         => 'fusioninventory',
60                     'classname'      => 'PluginFusioninventoryWakeonlan',
61                     'method'         => 'wakeonlan',
62                     'name'           => __('Wake On LAN', 'fusioninventory'),
63                     'use_rest'       => FALSE
64            ),
65
66            array(   'module'         => 'fusioninventory',
67                     'method'         => 'inventory',
68                     'selection_type' => 'devices',
69                     'hidetask'       => 1,
70                     'name'           => __('Computer Inventory', 'fusioninventory'),
71                     'use_rest'       => FALSE
72            ),
73
74            array(   'module'         => 'fusioninventory',
75                     'classname'      => 'PluginFusioninventoryInventoryComputerESX',
76                     'method'         => 'InventoryComputerESX',
77                     'selection_type' => 'devices',
78                     'name'           => __('VMware host remote inventory', 'fusioninventory'),
79                     'task'           => 'ESX',
80                     'use_rest'       => TRUE
81            ),
82
83            array(   'module'         => 'fusioninventory',
84                     'classname'      => 'PluginFusioninventoryNetworkDiscovery',
85                     'method'         => 'networkdiscovery',
86                     'name'           => __('Network discovery', 'fusioninventory')
87            ),
88
89            array(   'module'         => 'fusioninventory',
90                     'classname'      => 'PluginFusioninventoryNetworkInventory',
91                     'method'         => 'networkinventory',
92                     'name'           => __('Network inventory (SNMP)', 'fusioninventory')
93            ),
94
95            array(   'module'         => 'fusioninventory',
96                     'classname'      => 'PluginFusioninventoryDeployCommon',
97                     'method'         => 'deployinstall',
98                     'name'           => __('Package install', 'fusioninventory'),
99                     'task'           => "DEPLOY",
100                     'use_rest'       => TRUE
101            ),
102
103            array(   'module'         => 'fusioninventory',
104                     'classname'      => 'PluginFusioninventoryDeployCommon',
105                     'method'         => 'deployuninstall',
106                     'name'           => __('Package uninstall', 'fusioninventory'),
107                     'task'           => "DEPLOY",
108                     'use_rest'       => TRUE
109            ),
110
111            array(   'module'         => 'fusioninventory',
112                     'classname'      => 'PluginFusioninventoryCollect',
113                     'method'         => 'collect',
114                     'name'           => __('Collect data', 'fusioninventory'),
115                     'task'           => "Collect",
116                     'use_rest'       => TRUE
117            )
118      );
119      return $a_tasks;
120   }
121
122   /**
123   * Display methods availables
124   *
125   * @param $myname value name of dropdown
126   * @param $value value name of the method (used for edit taskjob)
127   * @param $entity_restrict restriction of entity if required
128   *
129   * @return value rand of the dropdown
130   *
131   **/
132   static function getModulesMethods() {
133
134      $methods = PluginFusioninventoryStaticmisc::getmethods();
135
136      $modules_methods = array();
137      $modules_methods[''] = "------";
138      foreach ($methods as $method) {
139         if (!((isset($method['hidetask']) AND $method['hidetask'] == '1'))) {
140            if (isset($method['name'])) {
141               $modules_methods[$method['method']] = $method['name'];
142            } else {
143               $modules_methods[$method['method']] = $method['method'];
144            }
145         }
146      }
147      return $modules_methods;
148   }
149
150
151   /**
152   * Get types of datas available to select for taskjob definition for WakeOnLan method
153   *
154   * @param $a_itemtype array types yet added for definitions
155   *
156   * @return array ('itemtype'=>'value', 'itemtype'=>'value'...)
157   *   itemtype itemtype of object
158   *   value name of the itemtype
159   **/
160   static function task_definitiontype_wakeonlan($a_itemtype) {
161
162      $a_itemtype['Computer'] = Computer::getTypeName();
163      $a_itemtype['PluginFusioninventoryDeployGroup'] = __('Dynamic Group');
164      return $a_itemtype;
165   }
166
167
168
169   /**
170   * Get all devices of definition type 'Computer' defined in task_definitiontype_wakeonlan
171   *
172   * @param $title value ???(not used I think)
173   *
174   * @return dropdown list of computers
175   *
176   **/
177   static function task_definitionselection_Computer_wakeonlan($title) {
178
179      $options = array();
180      $options['entity'] = $_SESSION['glpiactive_entity'];
181      $options['entity_sons'] = 1;
182      $options['name'] = 'definitionselectiontoadd';
183      $rand = Dropdown::show("Computer", $options);
184      return $rand;
185   }
186
187
188
189   static function task_definitionselection_PluginFusioninventoryDeployGroup_wakeonlan($title) {
190      $options = array();
191      $options['entity']      = $_SESSION['glpiactive_entity'];
192      $options['entity_sons'] = 1;
193      $options['name']        = 'definitionselectiontoadd';
194      return Dropdown::show("PluginFusioninventoryDeployGroup", $options);
195   }
196
197
198
199   /**
200   * Get all methods of this plugin
201   *
202   * @return array ('module'=>'value', 'method'=>'value')
203   *   module value name of plugin
204   *   method value name of method
205   *
206   **/
207   static function getmethods() {
208      $a_methods = call_user_func(array('PluginFusioninventoryStaticmisc', 'task_methods'));
209      $a_modules = PluginFusioninventoryModule::getAll();
210      foreach ($a_modules as $data) {
211         $class = $class= PluginFusioninventoryStaticmisc::getStaticmiscClass($data['directory']);
212         if (is_callable(array($class, 'task_methods'))) {
213            $a_methods = array_merge($a_methods,
214               call_user_func(array($class, 'task_methods')));
215         }
216      }
217      return $a_methods;
218   }
219
220
221
222   /**
223    * Get name of the staticmisc class for a module
224    * @param module the module name
225    *
226    * @return the name of the staticmisc class associated with it
227    */
228   static function getStaticMiscClass($module) {
229      return "Plugin".ucfirst($module)."Staticmisc";
230   }
231
232
233
234   /**
235   * Get types of datas available to select for taskjob definition for ESX method
236   *
237   * @param $a_itemtype array types yet added for definitions
238   *
239   * @return array ('itemtype'=>'value', 'itemtype'=>'value'...)
240   *   itemtype itemtype of object
241   *   value name of the itemtype
242   **/
243   static function task_definitiontype_InventoryComputerESX($a_itemtype) {
244      $a_itemtype['PluginFusioninventoryCredentialIp'] =
245                       PluginFusioninventoryCredentialIp::getTypeName();
246      return $a_itemtype;
247   }
248
249
250
251   /**
252   * Get all devices of definition type 'Computer' defined in task_definitiontype_wakeonlan
253   *
254   * @param $title value ???(not used I think)
255   *
256   * @return dropdown list of computers
257   *
258   **/
259   static function task_definitionselection_PluginFusioninventoryCredentialIp_InventoryComputerESX($title) {
260      global $DB;
261
262      $query = "SELECT `a`.`id`, `a`.`name`
263                FROM `glpi_plugin_fusioninventory_credentialips` as `a`
264                LEFT JOIN `glpi_plugin_fusioninventory_credentials` as `c`
265                   ON `c`.`id` = `a`.`plugin_fusioninventory_credentials_id`
266                WHERE `c`.`itemtype`='PluginFusioninventoryInventoryComputerESX'";
267      $query.= getEntitiesRestrictRequest(' AND', 'a');
268      $results = $DB->query($query);
269
270      $agents = array();
271      //$agents['.1'] = __('All');
272
273      while ($data = $DB->fetch_array($results)) {
274         $agents[$data['id']] = $data['name'];
275      }
276      if (!empty($agents)) {
277         return Dropdown::showFromArray('definitionselectiontoadd', $agents);
278      }
279   }
280
281
282
283   //------------------------------------------ Actions-------------------------------------//
284
285   static function task_actiontype_InventoryComputerESX($a_itemtype) {
286      return array ('' => Dropdown::EMPTY_VALUE ,
287                    'PluginFusioninventoryAgent' => __('Agents', 'fusioninventory'));
288
289   }
290
291
292
293   /**
294   * Get all devices of definition type 'Computer' defined in task_definitiontype_wakeonlan
295   *
296   * @return dropdown list of computers
297   *
298   **/
299   static function task_actionselection_PluginFusioninventoryCredentialIp_InventoryComputerESX() {
300      global $DB;
301
302      $options = array();
303      $options['name'] = 'definitionactiontoadd';
304
305      $module = new PluginFusioninventoryAgentmodule();
306      $module_infos = $module->getActivationExceptions('InventoryComputerESX');
307      $exceptions = json_decode($module_infos['exceptions'], TRUE);
308
309      $in = "";
310      if (!empty($exceptions)) {
311         $in = " AND `a`.`id` NOT IN (".implode($exceptions, ', ').")";
312      }
313
314      $query = "SELECT `a`.`id`, `a`.`name`
315                FROM `glpi_plugin_fusioninventory_credentialips` as `a`
316                LEFT JOIN `glpi_plugin_fusioninventory_credentials` as `c`
317                   ON `c`.`id` = `a`.`plugin_fusioninventory_credentials_id`
318                WHERE `c`.`itemtype`='PluginFusioninventoryInventoryComputerESX'";
319      $query.= getEntitiesRestrictRequest(' AND', 'glpi_plugin_fusioninventory_credentialips');
320
321      $results = $DB->query($query);
322      $credentialips = array();
323      while ($data = $DB->fetch_array($results)) {
324         $credentialips[$data['id']] = $data['name'];
325      }
326      return Dropdown::showFromArray('actionselectiontoadd', $credentialips);
327   }
328
329
330
331   static function task_actionselection_PluginFusioninventoryAgent_InventoryComputerESX() {
332
333      $array = array();
334      $pfAgentmodule = new PluginFusioninventoryAgentmodule();
335      $array1 = $pfAgentmodule->getAgentsCanDo(strtoupper("InventoryComputerESX"));
336      foreach ($array1 as $id => $data) {
337         $array[$id] = $data['name'];
338      }
339      asort($array);
340      return Dropdown::showFromArray('actionselectiontoadd', $array);
341   }
342
343
344
345   //------------------------------------------ ---------------------------------------------//
346   //------------------------------------------ REST PARAMS---------------------------------//
347   //------------------------------------------ -------------------------------------------//
348
349   /**
350    * Get ESX task parameters to send to the agent
351    * For the moment it's hardcoded, but in a future release it may be in DB
352    * @return an array of parameters
353    */
354   static function task_ESX_getParameters($entities_id) {
355      return array ('periodicity' => 3600, 'delayStartup' => 3600, 'task' => 'ESX',
356                    "remote" => PluginFusioninventoryAgentmodule::getUrlForModule('ESX', $entities_id));
357
358   }
359
360
361
362   //------------------------------- Network tools ------------------------------------//
363
364   // *** NETWORKDISCOVERY ***
365   static function task_definitiontype_networkdiscovery($a_itemtype) {
366      $a_itemtype['PluginFusioninventoryIPRange'] = __('IP Ranges', 'fusioninventory');
367      return $a_itemtype;
368   }
369
370
371
372   static function task_definitionselection_PluginFusioninventoryIPRange_networkdiscovery($title) {
373
374      $options = array();
375      $options['entity'] = $_SESSION['glpiactive_entity'];
376      $options['entity_sons'] = 1;
377      $options['name'] = 'definitionselectiontoadd';
378      $rand = Dropdown::show("PluginFusioninventoryIPRange", $options);
379      return $rand;
380   }
381
382
383
384   // *** NETWORKINVENTORY ***
385   static function task_definitiontype_networkinventory($a_itemtype) {
386
387      $a_itemtype['PluginFusioninventoryIPRange'] = __('IP Ranges', 'fusioninventory');
388
389      $a_itemtype['NetworkEquipment'] = NetworkEquipment::getTypeName();
390      $a_itemtype['Printer'] = Printer::getTypeName();
391
392      return $a_itemtype;
393   }
394
395
396
397   static function task_definitionselection_PluginFusioninventoryIPRange_networkinventory($title) {
398      $rand = PluginFusioninventoryStaticmisc::task_definitionselection_PluginFusioninventoryIPRange_networkdiscovery($title);
399      return $rand;
400   }
401
402
403
404   static function task_definitionselection_NetworkEquipment_networkinventory($title) {
405
406      $options = array();
407      $options['entity'] = $_SESSION['glpiactive_entity'];
408      $options['entity_sons'] = 1;
409      $options['name'] = 'definitionselectiontoadd';
410      $rand = Dropdown::show("NetworkEquipment", $options);
411      return $rand;
412   }
413
414
415
416   static function task_definitionselection_Printer_networkinventory($title) {
417
418      $options = array();
419      $options['entity'] = $_SESSION['glpiactive_entity'];
420      $options['entity_sons'] = 1;
421      $options['name'] = 'definitionselectiontoadd';
422      $rand = Dropdown::show("Printer", $options);
423      return $rand;
424   }
425
426
427
428   static function task_networkdiscovery_agents() {
429
430      $array = array();
431      $array["-.1"] = __('Auto managenement dynamic of agents', 'fusioninventory');
432
433      $pfAgentmodule = new PluginFusioninventoryAgentmodule();
434      $array1 = $pfAgentmodule->getAgentsCanDo('NETWORKDISCOVERY');
435      foreach ($array1 as $id => $data) {
436         $array["PluginFusioninventoryAgent-".$id] =
437                 __('Auto managenement dynamic of agents', 'fusioninventory')." - ".$data['name'];
438      }
439      return $array;
440   }
441
442
443
444   # Actions with itemtype autorized
445   static function task_action_networkinventory() {
446      $a_itemtype = array();
447      $a_itemtype[] = "Printer";
448      $a_itemtype[] = "NetworkEquipment";
449      $a_itemtype[] = 'PluginFusioninventoryIPRange';
450
451      return $a_itemtype;
452   }
453
454
455
456   # Selection type for actions
457   static function task_selection_type_networkinventory($itemtype) {
458      $selection_type = '';
459      switch ($itemtype) {
460
461         case 'PluginFusioninventoryIPRange':
462            $selection_type = 'iprange';
463            break;
464
465         case "Printer";
466         case "NetworkEquipment";
467            $selection_type = 'devices';
468            break;
469
470      }
471      return $selection_type;
472   }
473
474
475
476   static function task_selection_type_networkdiscovery($itemtype) {
477      $selection_type = '';
478      switch ($itemtype) {
479
480         case 'PluginFusioninventoryIPRange':
481            $selection_type = 'iprange';
482            break;
483
484         // __('Auto managenement dynamic of agents', 'fusioninventory')
485
486
487      }
488
489      return $selection_type;
490   }
491
492
493
494   /*
495    * Deploy definitions
496    */
497
498   static function task_definitiontype_deployinstall($a_itemtype) {
499      return array('' => Dropdown::EMPTY_VALUE,
500                   'PluginFusioninventoryDeployPackage' => __('Package'));
501   }
502
503
504
505   static function task_definitiontype_deployuninstall($a_itemtype) {
506      return array('' => Dropdown::EMPTY_VALUE,
507                   'PluginFusioninventoryDeployPackage' => __('Package'));
508   }
509
510
511
512   static function task_definitionselection_PluginFusioninventoryDeployPackage_deployinstall() {
513      $options['entity']      = $_SESSION['glpiactive_entity'];
514      $options['entity_sons'] = 1;
515      $options['name']        = 'definitionselectiontoadd';
516      return Dropdown::show("PluginFusioninventoryDeployPackage", $options);
517   }
518
519
520
521   static function task_definitionselection_PluginFusioninventoryDeployPackage_deployuninstall() {
522      $options['entity']      = $_SESSION['glpiactive_entity'];
523      $options['entity_sons'] = 1;
524      $options['name']        = 'definitionselectiontoadd';
525      return Dropdown::show("PluginFusioninventoryDeployPackage", $options);
526   }
527
528   /*
529    *  Deploy Actions
530    */
531
532   static function task_actiontype_deployinstall($a_itemtype) {
533      return array('' => Dropdown::EMPTY_VALUE,
534                   'Computer'                         => __('Computers'),
535                   'PluginFusioninventoryDeployGroup' => __('Fusinv', 'fusioninventory'). ' - ' .__('Group'),
536                   'Group'                            => __('Group')
537                  );
538   }
539
540
541
542   static function task_actiontype_deployuninstall($a_itemtype) {
543      return array('' => Dropdown::EMPTY_VALUE,
544                   'Computer'                         => __('Computers'),
545                   'PluginFusioninventoryDeployGroup' => __('Fusinv'). ' - ' .__('Group'),
546                   'Group'                            => __('Group')
547
548                  );
549   }
550
551   static function task_actionselection_Computer_deployinstall() {
552      $options = array();
553      $options['entity']      = $_SESSION['glpiactive_entity'];
554      $options['entity_sons'] = 1;
555      $options['name']        = 'actionselectiontoadd';
556      $options['condition']   =
557         implode( " ",
558            array(
559               '`id` IN ( ',
560               '  SELECT agents.`computers_id`',
561               '  FROM `glpi_plugin_fusioninventory_agents` as agents',
562               '  LEFT JOIN `glpi_plugin_fusioninventory_agentmodules` as module',
563               '  ON module.modulename = "DEPLOY"',
564               '  WHERE',
565               '        (  module.is_active=1',
566               '           AND module.exceptions NOT LIKE CONCAT(\'%"\',agents.`id`,\'"%\') )',
567               '     OR (  module.is_active=0',
568               '           AND module.exceptions LIKE CONCAT(\'%"\',agents.`id`,\'"%\') )',
569               ')'
570            )
571         );
572      return Dropdown::show("Computer", $options);
573   }
574
575
576
577   static function task_actionselection_Computer_deployuninstall() {
578      $options = array();
579      $options['entity']      = $_SESSION['glpiactive_entity'];
580      $options['entity_sons'] = 1;
581      $options['name']        = 'actionselectiontoadd';
582      $options['condition']   =
583         implode( " ",
584            array(
585               '`id` IN ( ',
586               '  SELECT agents.`computers_id`',
587               '  FROM `glpi_plugin_fusioninventory_agents` as agents',
588               '  LEFT JOIN `glpi_plugin_fusioninventory_agentmodules` as module',
589               '  ON module.modulename = "DEPLOY"',
590               '  WHERE',
591               '        (  module.is_active=1',
592               '           AND module.exceptions NOT LIKE CONCAT(\'%"\',agents.`id`,\'"%\') )',
593               '     OR (  module.is_active=0',
594               '           AND module.exceptions LIKE CONCAT(\'%"\',agents.`id`,\'"%\') )',
595               ')'
596            )
597         );
598      return Dropdown::show("Computer", $options);
599   }
600
601
602
603   static function task_actionselection_Group_deployinstall() {
604      $options = array();
605      $options['entity']      = $_SESSION['glpiactive_entity'];
606      $options['entity_sons'] = 1;
607      $options['name']        = 'actionselectiontoadd';
608      return Dropdown::show("Group", $options);
609   }
610
611
612
613   static function task_actionselection_Group_deployuninstall() {
614      $options = array();
615      $options['entity']      = $_SESSION['glpiactive_entity'];
616      $options['entity_sons'] = 1;
617      $options['name']        = 'actionselectiontoadd';
618      return Dropdown::show("Group", $options);
619   }
620
621
622
623   static function task_actionselection_PluginFusioninventoryDeployGroup_deployinstall() {
624      $options = array();
625      $options['entity']      = $_SESSION['glpiactive_entity'];
626      $options['entity_sons'] = 1;
627      $options['name']        = 'actionselectiontoadd';
628      return Dropdown::show("PluginFusioninventoryDeployGroup", $options);
629   }
630
631
632
633   static function task_actionselection_PluginFusioninventoryDeployGroup_deployuninstall() {
634      $options = array();
635      $options['entity']      = $_SESSION['glpiactive_entity'];
636      $options['entity_sons'] = 1;
637      $options['name']        = 'actionselectiontoadd';
638      return Dropdown::show("PluginFusioninventoryDeployGroup", $options);
639   }
640
641
642
643   static function task_deploy_getParameters($entities_id) {
644      return array(
645         "task" => "Deploy",
646         "remote" => PluginFusioninventoryAgentmodule::getUrlForModule('Deploy', $entities_id)
647      );
648   }
649
650
651
652   /*
653    * Collect
654    */
655   static function task_definitiontype_collect($a_itemtype) {
656      return array('' => Dropdown::EMPTY_VALUE,
657                   'PluginFusioninventoryCollect' => __('Collect information', 'fusioninventory'));
658   }
659
660
661
662   static function task_definitionselection_PluginFusioninventoryCollect_collect() {
663      $options['entity']      = $_SESSION['glpiactive_entity'];
664      $options['entity_sons'] = 1;
665      $options['name']        = 'definitionselectiontoadd';
666      return Dropdown::show("PluginFusioninventoryCollect", $options);
667   }
668
669
670
671   static function task_actiontype_collect($a_itemtype) {
672      return array('' => Dropdown::EMPTY_VALUE,
673                   'Computer'                         => __('Computers'),
674                   'PluginFusioninventoryDeployGroup' => __('Dynamic Group'),
675                   'Group'                            => __('Group')
676                  );
677   }
678
679
680
681   static function task_actionselection_Computer_collect() {
682      $options = array();
683      $options['entity']      = $_SESSION['glpiactive_entity'];
684      $options['entity_sons'] = 1;
685      $options['name']        = 'actionselectiontoadd';
686      $options['condition']   =
687         implode( " ",
688            array(
689               '`id` IN ( ',
690               '  SELECT agents.`computers_id`',
691               '  FROM `glpi_plugin_fusioninventory_agents` as agents',
692               '  LEFT JOIN `glpi_plugin_fusioninventory_agentmodules` as module',
693               '  ON module.modulename = "Collect"',
694               '  WHERE',
695               '        (  module.is_active=1',
696               '           AND module.exceptions NOT LIKE CONCAT(\'%"\',agents.`id`,\'"%\') )',
697               '     OR (  module.is_active=0',
698               '           AND module.exceptions LIKE CONCAT(\'%"\',agents.`id`,\'"%\') )',
699               ')'
700            )
701         );
702      return Dropdown::show("Computer", $options);
703   }
704
705
706
707   static function task_actionselection_Group_collect() {
708      $options = array();
709      $options['entity']      = $_SESSION['glpiactive_entity'];
710      $options['entity_sons'] = 1;
711      $options['name']        = 'actionselectiontoadd';
712      return Dropdown::show("Group", $options);
713   }
714
715
716
717   static function task_actionselection_PluginFusioninventoryDeployGroup_collect() {
718      $options = array();
719      $options['entity']      = $_SESSION['glpiactive_entity'];
720      $options['entity_sons'] = 1;
721      $options['name']        = 'actionselectiontoadd';
722      return Dropdown::show("PluginFusioninventoryDeployGroup", $options);
723   }
724
725
726
727   static function task_collect_getParameters($entities_id) {
728      return array(
729         "task" => "Collect",
730         "remote" => PluginFusioninventoryAgentmodule::getUrlForModule('Collect', $entities_id)
731      );
732   }
733
734}
735
736?>
737