[NUI]Remove some unused APIs.
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / UIComponents / ScrollBar.cs
1 /*
2  * Copyright(c) 2017 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 using System;
18 using System.ComponentModel;
19 using System.Runtime.InteropServices;
20 using Tizen.NUI.BaseComponents;
21
22 namespace Tizen.NUI.UIComponents
23 {
24     /// <summary>
25     /// The ScrollBar is a UI component that can be linked to the scrollable objects
26     /// indicating the current scroll position of the scrollable object.<br />
27     /// </summary>
28     /// <since_tizen> 3 </since_tizen>
29     public class ScrollBar : View
30     {
31         private global::System.Runtime.InteropServices.HandleRef swigCPtr;
32
33         internal ScrollBar(global::System.IntPtr cPtr, bool cMemoryOwn) : base(NDalicPINVOKE.ScrollBar_SWIGUpcast(cPtr), cMemoryOwn)
34         {
35             swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
36         }
37
38         internal static global::System.Runtime.InteropServices.HandleRef getCPtr(ScrollBar obj)
39         {
40             return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
41         }
42
43         /// <summary>
44         /// To dispose the ScrollBar instance.
45         /// </summary>
46         /// <since_tizen> 3 </since_tizen>
47         protected override void Dispose(DisposeTypes type)
48         {
49             if (disposed)
50             {
51                 return;
52             }
53
54             if(type == DisposeTypes.Explicit)
55             {
56                 //Called by User
57                 //Release your own managed resources here.
58                 //You should release all of your own disposable objects here.
59             }
60
61             //Release your own unmanaged resources here.
62             //You should not access any managed member here except static instance.
63             //because the execution order of Finalizes is non-deterministic.
64
65             if (_scrollBarScrollPositionIntervalReachedEventCallbackDelegate != null)
66             {
67                 ScrollPositionIntervalReachedSignal().Disconnect(_scrollBarScrollPositionIntervalReachedEventCallbackDelegate);
68             }
69
70             if (_scrollBarPanFinishedEventCallbackDelegate != null)
71             {
72                 PanFinishedSignal().Disconnect(_scrollBarPanFinishedEventCallbackDelegate);
73             }
74
75             if (swigCPtr.Handle != global::System.IntPtr.Zero)
76             {
77                 if (swigCMemOwn)
78                 {
79                     swigCMemOwn = false;
80                     NDalicPINVOKE.delete_ScrollBar(swigCPtr);
81                 }
82                 swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
83             }
84
85             base.Dispose(type);
86         }
87
88         /// <summary>
89         /// Event arguments that passed via the PanFinished event.
90         /// </summary>
91         /// <since_tizen> 3 </since_tizen>
92         public class PanFinishedEventArgs : EventArgs
93         {
94         }
95
96         /// <summary>
97         /// Event arguments that passed via the ScrollPositionIntervalReached event.
98         /// </summary>
99         /// <since_tizen> 3 </since_tizen>
100         public class ScrollIntervalEventArgs : EventArgs
101         {
102             private float _currentScrollPosition;
103
104             /// <summary>
105             /// The current scroll position of the scrollable content.
106             /// </summary>
107             /// <since_tizen> 3 </since_tizen>
108             public float CurrentScrollPosition
109             {
110                 get
111                 {
112                     return _currentScrollPosition;
113                 }
114                 set
115                 {
116                     _currentScrollPosition = value;
117                 }
118             }
119         }
120
121         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
122         private delegate void PanFinishedEventCallbackDelegate();
123         private EventHandler<PanFinishedEventArgs> _scrollBarPanFinishedEventHandler;
124         private PanFinishedEventCallbackDelegate _scrollBarPanFinishedEventCallbackDelegate;
125
126         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
127         private delegate void ScrollPositionIntervalReachedEventCallbackDelegate();
128         private EventHandler<ScrollIntervalEventArgs> _scrollBarScrollPositionIntervalReachedEventHandler;
129         private ScrollPositionIntervalReachedEventCallbackDelegate _scrollBarScrollPositionIntervalReachedEventCallbackDelegate;
130
131         /// <summary>
132         /// The event emitted when panning is finished on the scroll indicator.
133         /// </summary>
134         /// <since_tizen> 3 </since_tizen>
135         public event EventHandler<PanFinishedEventArgs> PanFinished
136         {
137             add
138             {
139                 if (_scrollBarPanFinishedEventHandler == null)
140                 {
141                     _scrollBarPanFinishedEventCallbackDelegate = (OnScrollBarPanFinished);
142                     PanFinishedSignal().Connect(_scrollBarPanFinishedEventCallbackDelegate);
143                 }
144                 _scrollBarPanFinishedEventHandler += value;
145             }
146             remove
147             {
148                 _scrollBarPanFinishedEventHandler -= value;
149                 if (_scrollBarPanFinishedEventHandler == null && PanFinishedSignal().Empty() == false)
150                 {
151                     PanFinishedSignal().Disconnect(_scrollBarPanFinishedEventCallbackDelegate);
152                 }
153             }
154         }
155
156         // Callback for ScrollBar PanFinishedSignal
157         private void OnScrollBarPanFinished()
158         {
159             PanFinishedEventArgs e = new PanFinishedEventArgs();
160
161             if (_scrollBarPanFinishedEventHandler != null)
162             {
163                 //here we send all data to user event handlers
164                 _scrollBarPanFinishedEventHandler(this, e);
165             }
166         }
167
168
169         /// <summary>
170         /// This is the event emitted when the current scroll position of the scrollable content.
171         /// </summary>
172         /// <since_tizen> 3 </since_tizen>
173         public event EventHandler<ScrollIntervalEventArgs> ScrollInterval
174         {
175             add
176             {
177                 if (_scrollBarScrollPositionIntervalReachedEventHandler == null)
178                 {
179                     _scrollBarScrollPositionIntervalReachedEventCallbackDelegate = (OnScrollBarScrollPositionIntervalReached);
180                     ScrollPositionIntervalReachedSignal().Connect(_scrollBarScrollPositionIntervalReachedEventCallbackDelegate);
181                 }
182                 _scrollBarScrollPositionIntervalReachedEventHandler += value;
183             }
184             remove
185             {
186                 _scrollBarScrollPositionIntervalReachedEventHandler -= value;
187                 if (_scrollBarScrollPositionIntervalReachedEventHandler == null && ScrollPositionIntervalReachedSignal().Empty() == false)
188                 {
189                     ScrollPositionIntervalReachedSignal().Disconnect(_scrollBarScrollPositionIntervalReachedEventCallbackDelegate);
190                 }
191             }
192         }
193
194         // Callback for ScrollBar ScrollPositionIntervalReachedSignal
195         private void OnScrollBarScrollPositionIntervalReached()
196         {
197             ScrollIntervalEventArgs e = new ScrollIntervalEventArgs();
198
199             if (_scrollBarScrollPositionIntervalReachedEventHandler != null)
200             {
201                 //here we send all data to user event handlers
202                 _scrollBarScrollPositionIntervalReachedEventHandler(this, e);
203             }
204         }
205
206
207         internal new class Property
208         {
209             internal static readonly int SCROLL_DIRECTION = NDalicPINVOKE.ScrollBar_Property_SCROLL_DIRECTION_get();
210             internal static readonly int INDICATOR_HEIGHT_POLICY = NDalicPINVOKE.ScrollBar_Property_INDICATOR_HEIGHT_POLICY_get();
211             internal static readonly int INDICATOR_FIXED_HEIGHT = NDalicPINVOKE.ScrollBar_Property_INDICATOR_FIXED_HEIGHT_get();
212             internal static readonly int INDICATOR_SHOW_DURATION = NDalicPINVOKE.ScrollBar_Property_INDICATOR_SHOW_DURATION_get();
213             internal static readonly int INDICATOR_HIDE_DURATION = NDalicPINVOKE.ScrollBar_Property_INDICATOR_HIDE_DURATION_get();
214             internal static readonly int SCROLL_POSITION_INTERVALS = NDalicPINVOKE.ScrollBar_Property_SCROLL_POSITION_INTERVALS_get();
215             internal static readonly int INDICATOR_MINIMUM_HEIGHT = NDalicPINVOKE.ScrollBar_Property_INDICATOR_MINIMUM_HEIGHT_get();
216             internal static readonly int INDICATOR_START_PADDING = NDalicPINVOKE.ScrollBar_Property_INDICATOR_START_PADDING_get();
217             internal static readonly int INDICATOR_END_PADDING = NDalicPINVOKE.ScrollBar_Property_INDICATOR_END_PADDING_get();
218         }
219
220         /// <summary>
221         /// Creates an initialized scrollbar.
222         /// </summary>
223         /// <param name="direction">The direction of the scrollbar (either vertically or horizontally).</param>
224         /// <since_tizen> 3 </since_tizen>
225         public ScrollBar(ScrollBar.Direction direction) : this(NDalicPINVOKE.ScrollBar_New__SWIG_0((int)direction), true)
226         {
227             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
228         }
229
230         /// <summary>
231         /// Creates an uninitialized scrollbar.
232         /// </summary>
233         /// <since_tizen> 3 </since_tizen>
234         public ScrollBar() : this(NDalicPINVOKE.ScrollBar_New__SWIG_1(), true)
235         {
236             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
237
238         }
239         internal ScrollBar(ScrollBar scrollBar) : this(NDalicPINVOKE.new_ScrollBar__SWIG_1(ScrollBar.getCPtr(scrollBar)), true)
240         {
241             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
242         }
243
244         internal void SetScrollPropertySource(Animatable handle, int propertyScrollPosition, int propertyMinScrollPosition, int propertyMaxScrollPosition, int propertyScrollContentSize)
245         {
246             NDalicPINVOKE.ScrollBar_SetScrollPropertySource(swigCPtr, Animatable.getCPtr(handle), propertyScrollPosition, propertyMinScrollPosition, propertyMaxScrollPosition, propertyScrollContentSize);
247             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
248         }
249
250         internal void SetScrollIndicator(View indicator)
251         {
252             NDalicPINVOKE.ScrollBar_SetScrollIndicator(swigCPtr, View.getCPtr(indicator));
253             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
254         }
255
256         internal View GetScrollIndicator()
257         {
258             View ret = new View(NDalicPINVOKE.ScrollBar_GetScrollIndicator(swigCPtr), true);
259             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
260             return ret;
261         }
262
263         internal void SetScrollDirection(ScrollBar.Direction direction)
264         {
265             NDalicPINVOKE.ScrollBar_SetScrollDirection(swigCPtr, (int)direction);
266             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
267         }
268
269         internal ScrollBar.Direction GetScrollDirection()
270         {
271             ScrollBar.Direction ret = (ScrollBar.Direction)NDalicPINVOKE.ScrollBar_GetScrollDirection(swigCPtr);
272             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
273             return ret;
274         }
275
276         internal void SetIndicatorHeightPolicy(ScrollBar.IndicatorHeightPolicyType policy)
277         {
278             NDalicPINVOKE.ScrollBar_SetIndicatorHeightPolicy(swigCPtr, (int)policy);
279             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
280         }
281
282         internal ScrollBar.IndicatorHeightPolicyType GetIndicatorHeightPolicy()
283         {
284             ScrollBar.IndicatorHeightPolicyType ret = (ScrollBar.IndicatorHeightPolicyType)NDalicPINVOKE.ScrollBar_GetIndicatorHeightPolicy(swigCPtr);
285             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
286             return ret;
287         }
288
289         internal void SetIndicatorFixedHeight(float height)
290         {
291             NDalicPINVOKE.ScrollBar_SetIndicatorFixedHeight(swigCPtr, height);
292             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
293         }
294
295         internal float GetIndicatorFixedHeight()
296         {
297             float ret = NDalicPINVOKE.ScrollBar_GetIndicatorFixedHeight(swigCPtr);
298             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
299             return ret;
300         }
301
302         internal void SetIndicatorShowDuration(float durationSeconds)
303         {
304             NDalicPINVOKE.ScrollBar_SetIndicatorShowDuration(swigCPtr, durationSeconds);
305             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
306         }
307
308         internal float GetIndicatorShowDuration()
309         {
310             float ret = NDalicPINVOKE.ScrollBar_GetIndicatorShowDuration(swigCPtr);
311             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
312             return ret;
313         }
314
315         internal void SetIndicatorHideDuration(float durationSeconds)
316         {
317             NDalicPINVOKE.ScrollBar_SetIndicatorHideDuration(swigCPtr, durationSeconds);
318             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
319         }
320
321         internal float GetIndicatorHideDuration()
322         {
323             float ret = NDalicPINVOKE.ScrollBar_GetIndicatorHideDuration(swigCPtr);
324             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
325             return ret;
326         }
327
328         internal void ShowIndicator()
329         {
330             NDalicPINVOKE.ScrollBar_ShowIndicator(swigCPtr);
331             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
332         }
333
334         internal void HideIndicator()
335         {
336             NDalicPINVOKE.ScrollBar_HideIndicator(swigCPtr);
337             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
338         }
339
340         internal VoidSignal PanFinishedSignal()
341         {
342             VoidSignal ret = new VoidSignal(NDalicPINVOKE.ScrollBar_PanFinishedSignal(swigCPtr), false);
343             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
344             return ret;
345         }
346
347         internal FloatSignal ScrollPositionIntervalReachedSignal()
348         {
349             FloatSignal ret = new FloatSignal(NDalicPINVOKE.ScrollBar_ScrollPositionIntervalReachedSignal(swigCPtr), false);
350             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
351             return ret;
352         }
353
354         /// <summary>
355         /// The direction of the scrollbar.
356         /// </summary>
357         /// <since_tizen> 3 </since_tizen>
358         public enum Direction
359         {
360             /// <summary>
361             /// Scroll in the vertical direction
362             /// </summary>
363             /// <since_tizen> 3 </since_tizen>
364             Vertical = 0,
365             /// <summary>
366             /// Scroll in the horizontal direction
367             /// </summary>
368             /// <since_tizen> 3 </since_tizen>
369             Horizontal
370         }
371
372         /// <summary>
373         /// The indicator height policy.
374         /// </summary>
375         /// <since_tizen> 3 </since_tizen>
376         public enum IndicatorHeightPolicyType
377         {
378             /// <summary>
379             /// Variable height changed dynamically according to the length of scroll content
380             /// </summary>
381             /// <since_tizen> 3 </since_tizen>
382             Variable = 0,
383             /// <summary>
384             /// Fixed height regardless of the length of scroll content
385             /// </summary>
386             /// <since_tizen> 3 </since_tizen>
387             Fixed
388         }
389
390         /// <summary>
391         /// The direction of the scrollbar.
392         /// </summary>
393         /// <since_tizen> 3 </since_tizen>
394         public Direction ScrollDirection
395         {
396             get
397             {
398                 string temp;
399                 if (GetProperty(ScrollBar.Property.SCROLL_DIRECTION).Get(out temp) == false)
400                 {
401                     NUILog.Error("ScrollDirection get error!");
402                 }
403
404                 switch (temp)
405                 {
406                     case "Vertical":
407                         return Direction.Vertical;
408                     case "Horizontal":
409                         return Direction.Horizontal;
410                     default:
411                         return Direction.Vertical;
412                 }
413             }
414             set
415             {
416                 string valueToString = "";
417                 switch (value)
418                 {
419                     case Direction.Vertical:
420                     {
421                         valueToString = "Vertical";
422                         break;
423                     }
424                     case Direction.Horizontal:
425                     {
426                         valueToString = "Horizontal";
427                         break;
428                     }
429                     default:
430                     {
431                         valueToString = "Vertical";
432                         break;
433                     }
434                 }
435                 SetProperty(ScrollBar.Property.SCROLL_DIRECTION, new Tizen.NUI.PropertyValue(valueToString));
436             }
437         }
438
439         /// <summary>
440         /// The indicator height policy.
441         /// </summary>
442         /// <since_tizen> 3 </since_tizen>
443         public IndicatorHeightPolicyType IndicatorHeightPolicy
444         {
445             get
446             {
447                 string temp;
448                 if (GetProperty(ScrollBar.Property.INDICATOR_HEIGHT_POLICY).Get(out temp) == false)
449                 {
450                     NUILog.Error("IndicatorHeightPolicy get error!");
451                 }
452
453                 switch (temp)
454                 {
455                     case "Variable":
456                         return IndicatorHeightPolicyType.Variable;
457                     case "Fixed":
458                         return IndicatorHeightPolicyType.Fixed;
459                     default:
460                         return IndicatorHeightPolicyType.Variable;
461                 }
462             }
463             set
464             {
465                 string valueToString = "";
466                 switch (value)
467                 {
468                     case IndicatorHeightPolicyType.Variable:
469                     {
470                         valueToString = "Variable";
471                         break;
472                     }
473                     case IndicatorHeightPolicyType.Fixed:
474                     {
475                         valueToString = "Fixed";
476                         break;
477                     }
478                     default:
479                     {
480                         valueToString = "Variable";
481                         break;
482                     }
483                 }
484                 SetProperty(ScrollBar.Property.INDICATOR_HEIGHT_POLICY, new Tizen.NUI.PropertyValue(valueToString));
485             }
486         }
487
488         /// <summary>
489         /// The fixed height of the scroll indicator.
490         /// </summary>
491         /// <since_tizen> 3 </since_tizen>
492         public float IndicatorFixedHeight
493         {
494             get
495             {
496                 float temp = 0.0f;
497                 GetProperty(ScrollBar.Property.INDICATOR_FIXED_HEIGHT).Get(out temp);
498                 return temp;
499             }
500             set
501             {
502                 SetProperty(ScrollBar.Property.INDICATOR_FIXED_HEIGHT, new Tizen.NUI.PropertyValue(value));
503             }
504         }
505
506         /// <summary>
507         /// The duration in seconds for the scroll indicator to become fully visible.
508         /// </summary>
509         /// <since_tizen> 3 </since_tizen>
510         public float IndicatorShowDuration
511         {
512             get
513             {
514                 float temp = 0.0f;
515                 GetProperty(ScrollBar.Property.INDICATOR_SHOW_DURATION).Get(out temp);
516                 return temp;
517             }
518             set
519             {
520                 SetProperty(ScrollBar.Property.INDICATOR_SHOW_DURATION, new Tizen.NUI.PropertyValue(value));
521             }
522         }
523
524         /// <summary>
525         /// The duration in seconds for the scroll indicator to become fully invisible.
526         /// </summary>
527         /// <since_tizen> 3 </since_tizen>
528         public float IndicatorHideDuration
529         {
530             get
531             {
532                 float temp = 0.0f;
533                 GetProperty(ScrollBar.Property.INDICATOR_HIDE_DURATION).Get(out temp);
534                 return temp;
535             }
536             set
537             {
538                 SetProperty(ScrollBar.Property.INDICATOR_HIDE_DURATION, new Tizen.NUI.PropertyValue(value));
539             }
540         }
541
542         /// <summary>
543         /// The list of values to get the notification when the current scroll position of the scrollable object goes above or below any of these values.
544         /// </summary>
545         /// <since_tizen> 3 </since_tizen>
546         public Tizen.NUI.PropertyArray ScrollPositionIntervals
547         {
548             get
549             {
550                 Tizen.NUI.PropertyArray temp = new Tizen.NUI.PropertyArray();
551                 GetProperty(ScrollBar.Property.SCROLL_POSITION_INTERVALS).Get(temp);
552                 return temp;
553             }
554             set
555             {
556                 SetProperty(ScrollBar.Property.SCROLL_POSITION_INTERVALS, new Tizen.NUI.PropertyValue(value));
557             }
558         }
559
560         /// <summary>
561         /// The minimum height for a variable size indicator.
562         /// </summary>
563         /// <since_tizen> 3 </since_tizen>
564         public float IndicatorMinimumHeight
565         {
566             get
567             {
568                 float temp = 0.0f;
569                 GetProperty(ScrollBar.Property.INDICATOR_MINIMUM_HEIGHT).Get(out temp);
570                 return temp;
571             }
572             set
573             {
574                 SetProperty(ScrollBar.Property.INDICATOR_MINIMUM_HEIGHT, new Tizen.NUI.PropertyValue(value));
575             }
576         }
577
578         /// <summary>
579         /// The padding at the start of the indicator. For example, the top if the scrollDirection is vertical.
580         /// </summary>
581         /// <since_tizen> 3 </since_tizen>
582         public float IndicatorStartPadding
583         {
584             get
585             {
586                 float temp = 0.0f;
587                 GetProperty(ScrollBar.Property.INDICATOR_START_PADDING).Get(out temp);
588                 return temp;
589             }
590             set
591             {
592                 SetProperty(ScrollBar.Property.INDICATOR_START_PADDING, new Tizen.NUI.PropertyValue(value));
593             }
594         }
595
596         /// <summary>
597         /// The padding at the end of the indicator. For example, the bottom if the scrollDirection is vertical.
598         /// </summary>
599         /// <since_tizen> 3 </since_tizen>
600         public float IndicatorEndPadding
601         {
602             get
603             {
604                 float temp = 0.0f;
605                 GetProperty(ScrollBar.Property.INDICATOR_END_PADDING).Get(out temp);
606                 return temp;
607             }
608             set
609             {
610                 SetProperty(ScrollBar.Property.INDICATOR_END_PADDING, new Tizen.NUI.PropertyValue(value));
611             }
612         }
613
614     }
615
616 }