2
0

DataList.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829
  1. /**
  2. * Namespace: System.Web.UI.WebControls
  3. * Class: DataList
  4. *
  5. * Author: Gaurav Vaish
  6. * Maintainer: [email protected]
  7. * Contact: <[email protected]>, <[email protected]>
  8. * Implementation: yes
  9. * Status: 70%
  10. *
  11. * (C) Gaurav Vaish (2001)
  12. */
  13. using System;
  14. using System.Collections;
  15. using System.ComponentModel;
  16. using System.Web;
  17. using System.Web.UI;
  18. namespace System.Web.UI.WebControls
  19. {
  20. //TODO: [Designer("??")]
  21. //TODO: [Editor("??")]
  22. [DefaultEvent("SelectedIndexChanged")]
  23. [DefaultProperty("DataSource")]
  24. [ParseChildren(true)]
  25. [PersistChildren(false)]
  26. public class DataList: BaseDataList, INamingContainer, IRepeatInfoUser
  27. {
  28. public const string CancelCommandName = "Cancel";
  29. public const string DeleteCommandName = "Delete";
  30. public const string EditCommandName = "Edit";
  31. public const string SelectCommandName = "Select";
  32. public const string UpdateCommandName = "Update";
  33. private static readonly object CancelCommandEvent = new object();
  34. private static readonly object DeleteCommandEvent = new object();
  35. private static readonly object EditCommandEvent = new object();
  36. private static readonly object ItemCommandEvent = new object();
  37. private static readonly object ItemCreatedEvent = new object();
  38. private static readonly object ItemDataBoundEvent = new object();
  39. private static readonly object UpdateCommandEvent = new object();
  40. private TableItemStyle alternatingItemStyle;
  41. private TableItemStyle editItemStyle;
  42. private TableItemStyle footerStyle;
  43. private TableItemStyle headerStyle;
  44. private TableItemStyle itemStyle;
  45. private TableItemStyle selectedItemStyle;
  46. private TableItemStyle separatorStyle;
  47. private ITemplate alternatingItemTemplate;
  48. private ITemplate editItemTemplate;
  49. private ITemplate footerTemplate;
  50. private ITemplate headerTemplate;
  51. private ITemplate itemTemplate;
  52. private ITemplate selectedItemTemplate;
  53. private ITemplate separatorTemplate;
  54. private ITemplate separatorItemTemplate;
  55. private ArrayList itemsArray;
  56. private DataListItemCollection items;
  57. private bool extractTemplateRows;
  58. public DataList(): base()
  59. {
  60. }
  61. public virtual TableItemStyle AlternatingItemStyle
  62. {
  63. get
  64. {
  65. if(alternatingItemStyle == null)
  66. {
  67. alternatingItemStyle = new TableItemStyle();
  68. if(IsTrackingViewState)
  69. alternatingItemStyle.TrackViewState();
  70. }
  71. return alternatingItemStyle;
  72. }
  73. }
  74. public virtual ITemplate AlternatingItemTemplate
  75. {
  76. get
  77. {
  78. return alternatingItemTemplate;
  79. }
  80. set
  81. {
  82. alternatingItemTemplate = value;
  83. }
  84. }
  85. public virtual int EditItemIndex
  86. {
  87. get
  88. {
  89. object o = ViewState["EditItemIndex"];
  90. if(o != null)
  91. return (int)o;
  92. return -1;
  93. }
  94. set
  95. {
  96. ViewState["EditItemIndex"] = value;
  97. }
  98. }
  99. public virtual TableItemStyle EditItemStyle
  100. {
  101. get
  102. {
  103. if(editItemStyle == null)
  104. {
  105. editItemStyle = new TableItemStyle();
  106. if(IsTrackingViewState)
  107. editItemStyle.TrackViewState();
  108. }
  109. return editItemStyle;
  110. }
  111. }
  112. public virtual ITemplate EditItemTemplate
  113. {
  114. get
  115. {
  116. return editItemTemplate;
  117. }
  118. set
  119. {
  120. editItemTemplate = value;
  121. }
  122. }
  123. public virtual bool ExtractTemplateRows
  124. {
  125. get
  126. {
  127. object o = ViewState["ExtractTemplateRows"];
  128. if(o != null)
  129. return (bool)o;
  130. return false;
  131. }
  132. set
  133. {
  134. ViewState["ExtractTemplateRows"] = value;
  135. }
  136. }
  137. public virtual TableItemStyle FooterStyle
  138. {
  139. get
  140. {
  141. if(footerStyle == null)
  142. {
  143. footerStyle = new TableItemStyle();
  144. if(IsTrackingViewState)
  145. footerStyle.TrackViewState();
  146. }
  147. return footerStyle;
  148. }
  149. }
  150. public virtual ITemplate FooterTemplate
  151. {
  152. get
  153. {
  154. return footerTemplate;
  155. }
  156. set
  157. {
  158. footerTemplate = value;
  159. }
  160. }
  161. public override GridLines GridLines
  162. {
  163. get
  164. {
  165. return GridLines;
  166. }
  167. set
  168. {
  169. GridLines = value;
  170. }
  171. }
  172. public virtual TableItemStyle HeaderStyle
  173. {
  174. get
  175. {
  176. if(headerStyle == null)
  177. {
  178. headerStyle = new TableItemStyle();
  179. if(IsTrackingViewState)
  180. headerStyle.TrackViewState();
  181. }
  182. return headerStyle;
  183. }
  184. }
  185. public virtual ITemplate HeaderTemplate
  186. {
  187. get
  188. {
  189. return headerTemplate;
  190. }
  191. set
  192. {
  193. headerTemplate = value;
  194. }
  195. }
  196. public virtual DataListItemCollection Items
  197. {
  198. get
  199. {
  200. if(items == null)
  201. {
  202. if(itemsArray == null)
  203. {
  204. EnsureChildControls();
  205. itemsArray = new ArrayList();
  206. }
  207. items = new DataListItemCollection(itemsArray);
  208. }
  209. return items;
  210. }
  211. }
  212. public virtual TableItemStyle ItemStyle
  213. {
  214. get
  215. {
  216. if(itemStyle == null)
  217. {
  218. itemStyle = new TableItemStyle();
  219. if(IsTrackingViewState)
  220. itemStyle.TrackViewState();
  221. }
  222. return itemStyle;
  223. }
  224. }
  225. public virtual ITemplate ItemTemplate
  226. {
  227. get
  228. {
  229. return itemTemplate;
  230. }
  231. set
  232. {
  233. itemTemplate = value;
  234. }
  235. }
  236. public virtual int RepeatColumns
  237. {
  238. get
  239. {
  240. object o = ViewState["RepeatColumns"];
  241. if(o != null)
  242. return (int)o;
  243. return 0;
  244. }
  245. set
  246. {
  247. if(value < 0)
  248. throw new ArgumentOutOfRangeException("value");
  249. ViewState["RepeatColumns"] = value;
  250. }
  251. }
  252. public virtual RepeatDirection RepeatDirection
  253. {
  254. get
  255. {
  256. object o = ViewState["RepeatDirection"];
  257. if(o != null)
  258. return (RepeatDirection)o;
  259. return RepeatDirection.Vertical;
  260. }
  261. set
  262. {
  263. if(!Enum.IsDefined(typeof(RepeatDirection), value))
  264. throw new ArgumentException();
  265. ViewState["RepeatDirection"] = value;
  266. }
  267. }
  268. public virtual RepeatLayout RepeatLayout
  269. {
  270. get
  271. {
  272. object o = ViewState["RepeatLayout"];
  273. if(o != null)
  274. return (RepeatLayout)o;
  275. return RepeatLayout.Table;
  276. }
  277. set
  278. {
  279. if(!Enum.IsDefined(typeof(RepeatLayout), value))
  280. throw new ArgumentException();
  281. ViewState["RepeatLayout"] = value;
  282. }
  283. }
  284. public virtual int SelectedIndex
  285. {
  286. get
  287. {
  288. object o = ViewState["SelectedIndex"];
  289. if(o != null)
  290. return (int)o;
  291. return -1;
  292. }
  293. set
  294. {
  295. //FIXME: Looks like a bug in Microsoft's specs.
  296. // Exception is missing in document. I haven't tested the case
  297. // But I think exception should follow
  298. if(value < -1)
  299. throw new ArgumentOutOfRangeException("value");
  300. int prevSel = SelectedIndex;
  301. ViewState["SelectedIndex"] = value;
  302. DataListItem prevSelItem;
  303. ListItemType liType;
  304. if(itemsArray != null)
  305. {
  306. if(prevSel >= 0 && prevSel < itemsArray.Count)
  307. {
  308. prevSelItem = (DataListItem)itemsArray[prevSel];
  309. if(prevSelItem.ItemType != ListItemType.EditItem)
  310. {
  311. liType = ( (prevSel % 2) == 0 ? ListItemType.AlternatingItem : ListItemType.Item );
  312. prevSelItem.SetItemType(liType);
  313. }
  314. }
  315. if(value >= 0 && value < itemsArray.Count)
  316. {
  317. prevSelItem = (DataListItem) itemsArray[value];
  318. if(prevSelItem.ItemType != ListItemType.EditItem)
  319. {
  320. prevSelItem.SetItemType(ListItemType.SelectedItem);
  321. }
  322. }
  323. }
  324. }
  325. }
  326. public virtual DataListItem SelectedItem
  327. {
  328. get
  329. {
  330. if(SelectedIndex == -1)
  331. return null;
  332. return Items[SelectedIndex];
  333. }
  334. }
  335. public virtual TableItemStyle SelectedItemStyle
  336. {
  337. get
  338. {
  339. if(selectedItemStyle == null)
  340. {
  341. selectedItemStyle = new TableItemStyle();
  342. if(IsTrackingViewState)
  343. selectedItemStyle.TrackViewState();
  344. }
  345. return selectedItemStyle;
  346. }
  347. }
  348. public virtual ITemplate SelectedItemTemplate
  349. {
  350. get
  351. {
  352. return selectedItemTemplate;
  353. }
  354. set
  355. {
  356. selectedItemTemplate = value;
  357. }
  358. }
  359. public virtual TableItemStyle SeparatorStyle
  360. {
  361. get
  362. {
  363. if(separatorStyle == null)
  364. {
  365. separatorStyle = new TableItemStyle();
  366. if(IsTrackingViewState)
  367. separatorStyle.TrackViewState();
  368. }
  369. return separatorStyle;
  370. }
  371. }
  372. public virtual ITemplate SeparatorTemplate
  373. {
  374. get
  375. {
  376. return separatorTemplate;
  377. }
  378. set
  379. {
  380. separatorTemplate = value;
  381. }
  382. }
  383. public virtual ITemplate SeparatorItemTemplate
  384. {
  385. get
  386. {
  387. return separatorItemTemplate;
  388. }
  389. set
  390. {
  391. separatorItemTemplate = value;
  392. }
  393. }
  394. public virtual bool ShowHeader
  395. {
  396. get
  397. {
  398. object o = ViewState["ShowHeader"];
  399. if(o!=null)
  400. return (bool)o;
  401. return true;
  402. }
  403. set
  404. {
  405. ViewState["ShowHeader"] = value;
  406. }
  407. }
  408. public virtual bool ShowFooter
  409. {
  410. get
  411. {
  412. object o = ViewState["ShowFooter"];
  413. if(o!=null)
  414. return (bool)o;
  415. return true;
  416. }
  417. set
  418. {
  419. ViewState["ShowFooter"] = value;
  420. }
  421. }
  422. public event DataListCommandEventHandler CancelCommand
  423. {
  424. add
  425. {
  426. Events.AddHandler(CancelCommandEvent, value);
  427. }
  428. remove
  429. {
  430. Events.RemoveHandler(CancelCommandEvent, value);
  431. }
  432. }
  433. public event DataListCommandEventHandler DeleteCommand
  434. {
  435. add
  436. {
  437. Events.AddHandler(DeleteCommandEvent, value);
  438. }
  439. remove
  440. {
  441. Events.RemoveHandler(DeleteCommandEvent, value);
  442. }
  443. }
  444. public event DataListCommandEventHandler EditCommand
  445. {
  446. add
  447. {
  448. Events.AddHandler(EditCommandEvent, value);
  449. }
  450. remove
  451. {
  452. Events.RemoveHandler(EditCommandEvent, value);
  453. }
  454. }
  455. public event DataListCommandEventHandler ItemCommand
  456. {
  457. add
  458. {
  459. Events.AddHandler(ItemCommandEvent, value);
  460. }
  461. remove
  462. {
  463. Events.RemoveHandler(ItemCommandEvent, value);
  464. }
  465. }
  466. public event DataListCommandEventHandler ItemCreated
  467. {
  468. add
  469. {
  470. Events.AddHandler(ItemCreatedEvent, value);
  471. }
  472. remove
  473. {
  474. Events.RemoveHandler(ItemCreatedEvent, value);
  475. }
  476. }
  477. public event DataListCommandEventHandler ItemDataBound
  478. {
  479. add
  480. {
  481. Events.AddHandler(ItemDataBoundEvent, value);
  482. }
  483. remove
  484. {
  485. Events.RemoveHandler(ItemDataBoundEvent, value);
  486. }
  487. }
  488. public event DataListCommandEventHandler UpdateCommand
  489. {
  490. add
  491. {
  492. Events.AddHandler(UpdateCommandEvent, value);
  493. }
  494. remove
  495. {
  496. Events.RemoveHandler(UpdateCommandEvent, value);
  497. }
  498. }
  499. protected override Style CreateControlStyle()
  500. {
  501. TableStyle retVal = new TableStyle(ViewState);
  502. retVal.CellSpacing = 0;
  503. return retVal;
  504. }
  505. protected override void LoadViewState(object savedState)
  506. {
  507. object[] states;
  508. if(savedState != null && (states = (object[])savedState) != null)
  509. {
  510. if(states[0] != null)
  511. LoadViewState(states[0]);
  512. if(states[1] != null)
  513. alternatingItemStyle.LoadViewState(states[1]);
  514. if(states[2] != null)
  515. editItemStyle.LoadViewState(states[2]);
  516. if(states[3] != null)
  517. footerStyle.LoadViewState(states[3]);
  518. if(states[4] != null)
  519. headerStyle.LoadViewState(states[4]);
  520. if(states[5] != null)
  521. itemStyle.LoadViewState(states[5]);
  522. if(states[6] != null)
  523. selectedItemStyle.LoadViewState(states[6]);
  524. if(states[7] != null)
  525. separatorStyle.LoadViewState(states[7]);
  526. }
  527. }
  528. protected override object SaveViewState()
  529. {
  530. object[] states = new object[8];
  531. states[0] = SaveViewState();
  532. states[1] = (alternatingItemStyle == null ? null : alternatingItemStyle.SaveViewState());
  533. states[2] = (editItemStyle == null ? null : editItemStyle.SaveViewState());
  534. states[3] = (footerStyle == null ? null : footerStyle.SaveViewState());
  535. states[4] = (headerStyle == null ? null : headerStyle.SaveViewState());
  536. states[5] = (itemStyle == null ? null : itemStyle.SaveViewState());
  537. states[6] = (selectedItemStyle == null ? null : selectedItemStyle.SaveViewState());
  538. states[7] = (separatorStyle == null ? null : separatorStyle.SaveViewState());
  539. return states;
  540. }
  541. protected override void TrackViewState()
  542. {
  543. TrackViewState();
  544. if(alternatingItemStyle != null)
  545. alternatingItemStyle.TrackViewState();
  546. if(editItemStyle != null)
  547. editItemStyle.TrackViewState();
  548. if(footerStyle != null)
  549. footerStyle.TrackViewState();
  550. if(headerStyle != null)
  551. headerStyle.TrackViewState();
  552. if(itemStyle != null)
  553. itemStyle.TrackViewState();
  554. if(selectedItemStyle != null)
  555. selectedItemStyle.TrackViewState();
  556. if(separatorStyle != null)
  557. separatorStyle.TrackViewState();
  558. }
  559. protected override bool OnBubbleEvent(object source, EventArgs e)
  560. {
  561. bool retVal = false;
  562. if(e is DataListCommandEventArgs)
  563. {
  564. DataListCommandEventArgs dlcea = (DataListCommandEventArgs)e;
  565. OnItemCommand(dlcea);
  566. retVal = true;
  567. if(String.Compare(dlcea.CommandName, "Cancel") == 0)
  568. {
  569. OnCancelCommand(dlcea);
  570. }
  571. if(String.Compare(dlcea.CommandName, "Delete") == 0)
  572. {
  573. OnDeleteCommand(dlcea);
  574. }
  575. if(String.Compare(dlcea.CommandName, "Edit") == 0)
  576. {
  577. OnEditCommand(dlcea);
  578. }
  579. if(String.Compare(dlcea.CommandName, "Select") == 0)
  580. {
  581. SelectedIndex = dlcea.Item.ItemIndex;
  582. OnSelectedIndexChanged(EventArgs.Empty);
  583. }
  584. if(String.Compare(dlcea.CommandName, "Update") == 0)
  585. {
  586. OnUpdateCommand(dlcea);
  587. }
  588. }
  589. return retVal;
  590. }
  591. protected virtual void OnCancelCommand(DataListCommandEventArgs e)
  592. {
  593. if(Events != null)
  594. {
  595. DataListCommandEventHandler dlceh = (DataListCommandEventHandler)(Events[CancelCommandEvent]);
  596. if(dlceh != null)
  597. dlceh(this, e);
  598. }
  599. }
  600. protected virtual void OnDeleteCommand(DataListCommandEventArgs e)
  601. {
  602. if(Events != null)
  603. {
  604. DataListCommandEventHandler dlceh = (DataListCommandEventHandler)(Events[DeleteCommandEvent]);
  605. if(dlceh != null)
  606. dlceh(this, e);
  607. }
  608. }
  609. protected virtual void OnEditCommand(DataListCommandEventArgs e)
  610. {
  611. if(Events != null)
  612. {
  613. DataListCommandEventHandler dlceh = (DataListCommandEventHandler)(Events[EditCommandEvent]);
  614. if(dlceh != null)
  615. dlceh(this, e);
  616. }
  617. }
  618. protected virtual void OnItemCommand(DataListCommandEventArgs e)
  619. {
  620. if(Events != null)
  621. {
  622. DataListCommandEventHandler dlceh = (DataListCommandEventHandler)(Events[ItemCommandEvent]);
  623. if(dlceh != null)
  624. dlceh(this, e);
  625. }
  626. }
  627. protected virtual void OnItemCreated(DataListItemEventArgs e)
  628. {
  629. if(Events != null)
  630. {
  631. DataListItemEventHandler dlceh = (DataListItemEventHandler)(Events[ItemCreatedEvent]);
  632. if(dlceh != null)
  633. dlceh(this, e);
  634. }
  635. }
  636. protected virtual void OnItemDataBound(DataListItemEventArgs e)
  637. {
  638. if(Events != null)
  639. {
  640. DataListItemEventHandler dlceh = (DataListItemEventHandler)(Events[ItemDataBoundEvent]);
  641. if(dlceh != null)
  642. dlceh(this, e);
  643. }
  644. }
  645. protected virtual void OnUpdateCommand(DataListCommandEventArgs e)
  646. {
  647. if(Events != null)
  648. {
  649. DataListCommandEventHandler dlceh = (DataListCommandEventHandler)(Events[UpdateCommandEvent]);
  650. if(dlceh != null)
  651. dlceh(this, e);
  652. }
  653. }
  654. [MonoTODO]
  655. protected override void RenderContents(HtmlTextWriter writer)
  656. {
  657. throw new NotImplementedException();
  658. }
  659. [MonoTODO]
  660. private DataListItem GetItem(ListItemType itemType, int repeatIndex)
  661. {
  662. DataListItem retVal = null;
  663. switch(itemType)
  664. {
  665. case ListItemType.Header: retVal = (DataListItem)Controls[0];
  666. break;
  667. case ListItemType.Footer: retVal = (DataListItem)Controls[Controls.Count - 1];
  668. break;
  669. case ListItemType.Item: goto case ListItemType.EditItem;
  670. case ListItemType.AlternatingItem: goto case ListItemType.EditItem;
  671. case ListItemType.SelectedItem: goto case ListItemType.EditItem;
  672. case ListItemType.EditItem: retVal = (DataListItem)Controls[repeatIndex];
  673. break;
  674. case ListItemType.Separator: int index = 2 * repeatIndex + 1;
  675. if(headerTemplate != null)
  676. index ++;
  677. retVal = (DataListItem)Controls[index];
  678. break;
  679. }
  680. return retVal;
  681. }
  682. /// <summary>
  683. /// Undocumented
  684. /// </summary>
  685. [MonoTODO]
  686. protected override void CreateControlHierarchy(bool create)
  687. {
  688. throw new NotImplementedException();
  689. }
  690. /// <summary>
  691. /// Undocumented
  692. /// </summary>
  693. [MonoTODO]
  694. protected virtual DataListItem CreateItem(int itemIndex, ListItemType itemType)
  695. {
  696. throw new NotImplementedException();
  697. }
  698. [MonoTODO]
  699. private DataListItem CreateItem(int itemIndex, ListItemType itemType, bool dataBind, object dataItem)
  700. {
  701. throw new NotImplementedException();
  702. }
  703. /// <summary>
  704. /// Undocumented
  705. /// </summary>
  706. [MonoTODO]
  707. protected override void PrepareControlHierarchy()
  708. {
  709. throw new NotImplementedException();
  710. }
  711. /// <summary>
  712. /// Undocumented
  713. /// </summary>
  714. [MonoTODO]
  715. protected virtual void InitializeItem(DataListItem item)
  716. {
  717. throw new NotImplementedException();
  718. }
  719. bool IRepeatInfoUser.HasFooter
  720. {
  721. get
  722. {
  723. return !(ShowFooter && footerTemplate!=null);
  724. }
  725. }
  726. bool IRepeatInfoUser.HasHeader
  727. {
  728. get
  729. {
  730. return !(ShowHeader && headerTemplate!=null);
  731. }
  732. }
  733. bool IRepeatInfoUser.HasSeparators
  734. {
  735. get
  736. {
  737. return (separatorItemTemplate!=null);
  738. }
  739. }
  740. int IRepeatInfoUser.RepeatedItemCount
  741. {
  742. get
  743. {
  744. if(itemsArray!=null)
  745. return itemsArray.Count;
  746. return 0;
  747. }
  748. }
  749. void IRepeatInfoUser.RenderItem(ListItemType itemType, int repeatIndex, RepeatInfo repeatInfo, HtmlTextWriter writer)
  750. {
  751. DataListItem item = GetItem(itemType, repeatIndex);
  752. if(item!=null)
  753. {
  754. item.RenderItem(writer, extractTemplateRows, repeatInfo.RepeatLayout == RepeatLayout.Table);
  755. }
  756. }
  757. Style IRepeatInfoUser.GetItemStyle(ListItemType itemType, int repeatIndex)
  758. {
  759. if(GetItem(itemType, repeatIndex)!=null && ControlStyleCreated)
  760. return ControlStyle;
  761. return null;
  762. }
  763. }
  764. }