~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to src/core/MonoDevelop.Ide/MonoDevelop.Components.Docking/DockItemTitleTab.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// DockItemTitleTab.cs
 
3
//
 
4
// Author:
 
5
//       Lluis Sanchez Gual <lluis@xamarin.com>
 
6
//
 
7
// Copyright (c) 2012 Xamarin Inc. (http://xamarin.com)
 
8
// Copyright (C) 2007 Novell, Inc (http://www.novell.com)
 
9
//
 
10
// Permission is hereby granted, free of charge, to any person obtaining a copy
 
11
// of this software and associated documentation files (the "Software"), to deal
 
12
// in the Software without restriction, including without limitation the rights
 
13
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
14
// copies of the Software, and to permit persons to whom the Software is
 
15
// furnished to do so, subject to the following conditions:
 
16
//
 
17
// The above copyright notice and this permission notice shall be included in
 
18
// all copies or substantial portions of the Software.
 
19
//
 
20
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
21
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
22
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
23
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
24
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
25
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
26
// THE SOFTWARE.
 
27
 
 
28
using Gtk; 
 
29
 
 
30
using System;
 
31
using MonoDevelop.Ide.Gui;
 
32
using System.Linq;
 
33
using MonoDevelop.Core;
 
34
using MonoDevelop.Ide;
 
35
using Mono.TextEditor;
 
36
using MonoDevelop.Components;
 
37
 
 
38
namespace MonoDevelop.Components.Docking
 
39
{
 
40
        
 
41
        class DockItemTitleTab: Gtk.EventBox
 
42
        {
 
43
                bool active;
 
44
                Gtk.Widget page;
 
45
                ExtendedLabel labelWidget;
 
46
                int labelWidth;
 
47
                DockVisualStyle visualStyle;
 
48
                Image tabIcon;
 
49
                DockFrame frame;
 
50
                string label;
 
51
                ImageButton btnDock;
 
52
                ImageButton btnClose;
 
53
                DockItem item;
 
54
                bool allowPlaceholderDocking;
 
55
                bool mouseOver;
 
56
 
 
57
                static Gdk.Cursor fleurCursor = new Gdk.Cursor (Gdk.CursorType.Fleur);
 
58
 
 
59
                static Gdk.Pixbuf pixClose;
 
60
                static Gdk.Pixbuf pixAutoHide;
 
61
                static Gdk.Pixbuf pixDock;
 
62
 
 
63
                const int TopPadding = 5;
 
64
                const int BottomPadding = 7;
 
65
                const int TopPaddingActive = 5;
 
66
                const int BottomPaddingActive = 7;
 
67
                const int LeftPadding = 11;
 
68
                const int RightPadding = 9;
 
69
 
 
70
                static DockItemTitleTab ()
 
71
                {
 
72
                        pixClose = Gdk.Pixbuf.LoadFromResource ("stock-close-12.png");
 
73
                        pixAutoHide = Gdk.Pixbuf.LoadFromResource ("stock-auto-hide.png");
 
74
                        pixDock = Gdk.Pixbuf.LoadFromResource ("stock-dock.png");
 
75
                }
 
76
                
 
77
                public DockItemTitleTab (DockItem item, DockFrame frame)
 
78
                {
 
79
                        this.item = item;
 
80
                        this.frame = frame;
 
81
                        this.VisibleWindow = false;
 
82
                        UpdateVisualStyle ();
 
83
                        NoShowAll = true;
 
84
 
 
85
 
 
86
                        Events |= Gdk.EventMask.EnterNotifyMask | Gdk.EventMask.LeaveNotifyMask | Gdk.EventMask.ButtonPressMask | Gdk.EventMask.ButtonReleaseMask | Gdk.EventMask.PointerMotionMask;
 
87
                        KeyPressEvent += HeaderKeyPress;
 
88
                        KeyReleaseEvent += HeaderKeyRelease;
 
89
 
 
90
                        this.SubscribeLeaveEvent (OnLeave);
 
91
                }
 
92
 
 
93
                public DockVisualStyle VisualStyle {
 
94
                        get { return visualStyle; }
 
95
                        set {
 
96
                                visualStyle = value;
 
97
                                UpdateVisualStyle ();
 
98
                                QueueDraw ();
 
99
                        }
 
100
                }
 
101
 
 
102
                void UpdateVisualStyle ()
 
103
                {
 
104
                        if (labelWidget != null && label != null) {
 
105
                                if (visualStyle.UppercaseTitles.Value)
 
106
                                        labelWidget.Text = label.ToUpper ();
 
107
                                else
 
108
                                        labelWidget.Text = label;
 
109
                                labelWidget.UseMarkup = true;
 
110
                                if (visualStyle.ExpandedTabs.Value)
 
111
                                        labelWidget.Xalign = 0.5f;
 
112
 
 
113
                                if (!(Parent is TabStrip.TabStripBox))
 
114
                                        labelWidget.Xalign = 0;
 
115
                        }
 
116
 
 
117
                        if (tabIcon != null)
 
118
                                tabIcon.Visible = visualStyle.ShowPadTitleIcon.Value;
 
119
                        if (IsRealized) {
 
120
                                if (labelWidget != null)
 
121
                                        labelWidget.ModifyFg (StateType.Normal, visualStyle.PadTitleLabelColor.Value);
 
122
                        }
 
123
                        var r = WidthRequest;
 
124
                        WidthRequest = -1;
 
125
                        labelWidth = SizeRequest ().Width + 1;
 
126
                        WidthRequest = r;
 
127
 
 
128
                        if (visualStyle != null)
 
129
                                HeightRequest = visualStyle.PadTitleHeight != null ? visualStyle.PadTitleHeight.Value : -1;
 
130
                }
 
131
 
 
132
                public void SetLabel (Gtk.Widget page, Gdk.Pixbuf icon, string label)
 
133
                {
 
134
                        this.label = label;
 
135
                        this.page = page;
 
136
                        if (Child != null) {
 
137
                                Gtk.Widget oc = Child;
 
138
                                Remove (oc);
 
139
                                oc.Destroy ();
 
140
                        }
 
141
                        
 
142
                        Gtk.HBox box = new HBox ();
 
143
                        box.Spacing = 2;
 
144
                        
 
145
                        if (icon != null) {
 
146
                                tabIcon = new Gtk.Image (icon);
 
147
                                tabIcon.Show ();
 
148
                                box.PackStart (tabIcon, false, false, 0);
 
149
                        } else
 
150
                                tabIcon = null;
 
151
 
 
152
                        if (!string.IsNullOrEmpty (label)) {
 
153
                                labelWidget = new ExtendedLabel (label);
 
154
                                labelWidget.DropShadowVisible = true;
 
155
                                labelWidget.UseMarkup = true;
 
156
                                box.PackStart (labelWidget, true, true, 0);
 
157
                        } else {
 
158
                                labelWidget = null;
 
159
                        }
 
160
 
 
161
                        btnDock = new ImageButton ();
 
162
                        btnDock.Image = pixAutoHide;
 
163
                        btnDock.TooltipText = GettextCatalog.GetString ("Auto Hide");
 
164
                        btnDock.CanFocus = false;
 
165
//                      btnDock.WidthRequest = btnDock.HeightRequest = 17;
 
166
                        btnDock.Clicked += OnClickDock;
 
167
                        btnDock.ButtonPressEvent += (o, args) => args.RetVal = true;
 
168
                        btnDock.WidthRequest = btnDock.SizeRequest ().Width;
 
169
 
 
170
                        btnClose = new ImageButton ();
 
171
                        btnClose.Image = pixClose;
 
172
                        btnClose.TooltipText = GettextCatalog.GetString ("Close");
 
173
                        btnClose.CanFocus = false;
 
174
//                      btnClose.WidthRequest = btnClose.HeightRequest = 17;
 
175
                        btnClose.WidthRequest = btnDock.SizeRequest ().Width;
 
176
                        btnClose.Clicked += delegate {
 
177
                                item.Visible = false;
 
178
                        };
 
179
                        btnClose.ButtonPressEvent += (o, args) => args.RetVal = true;
 
180
 
 
181
                        Gtk.Alignment al = new Alignment (0, 0, 1, 1);
 
182
                        HBox btnBox = new HBox (false, 3);
 
183
                        btnBox.PackStart (btnDock, false, false, 0);
 
184
                        btnBox.PackStart (btnClose, false, false, 0);
 
185
                        al.Add (btnBox);
 
186
                        al.LeftPadding = 3;
 
187
                        al.TopPadding = 1;
 
188
                        box.PackEnd (al, false, false, 0);
 
189
 
 
190
                        Add (box);
 
191
                        
 
192
                        // Get the required size before setting the ellipsize property, since ellipsized labels
 
193
                        // have a width request of 0
 
194
                        box.ShowAll ();
 
195
                        Show ();
 
196
 
 
197
                        UpdateBehavior ();
 
198
                        UpdateVisualStyle ();
 
199
                }
 
200
                
 
201
                void OnClickDock (object s, EventArgs a)
 
202
                {
 
203
                        if (item.Status == DockItemStatus.AutoHide || item.Status == DockItemStatus.Floating)
 
204
                                item.Status = DockItemStatus.Dockable;
 
205
                        else
 
206
                                item.Status = DockItemStatus.AutoHide;
 
207
                }
 
208
 
 
209
                public int LabelWidth {
 
210
                        get { return labelWidth; }
 
211
                }
 
212
                
 
213
                public bool Active {
 
214
                        get {
 
215
                                return active;
 
216
                        }
 
217
                        set {
 
218
                                if (active != value) {
 
219
                                        active = value;
 
220
                                        this.QueueResize ();
 
221
                                        QueueDraw ();
 
222
                                        UpdateBehavior ();
 
223
                                }
 
224
                        }
 
225
                }
 
226
 
 
227
                public Widget Page {
 
228
                        get {
 
229
                                return page;
 
230
                        }
 
231
                }
 
232
                
 
233
                public void UpdateBehavior ()
 
234
                {
 
235
                        if (btnClose == null)
 
236
                                return;
 
237
 
 
238
                        btnClose.Visible = (item.Behavior & DockItemBehavior.CantClose) == 0;
 
239
                        btnDock.Visible = (item.Behavior & DockItemBehavior.CantAutoHide) == 0;
 
240
                        
 
241
                        if (active || mouseOver) {
 
242
                                if (btnClose.Image == null)
 
243
                                        btnClose.Image = pixClose;
 
244
                                if (item.Status == DockItemStatus.AutoHide || item.Status == DockItemStatus.Floating) {
 
245
                                        btnDock.Image = pixDock;
 
246
                                        btnDock.TooltipText = GettextCatalog.GetString ("Dock");
 
247
                                } else {
 
248
                                        btnDock.Image = pixAutoHide;
 
249
                                        btnDock.TooltipText = GettextCatalog.GetString ("Auto Hide");
 
250
                                }
 
251
                        } else {
 
252
                                btnDock.Image = null;
 
253
                                btnClose.Image = null;
 
254
                        }
 
255
                }
 
256
 
 
257
                bool tabPressed, tabActivated;
 
258
                double pressX, pressY;
 
259
 
 
260
                protected override bool OnButtonPressEvent (Gdk.EventButton evnt)
 
261
                {
 
262
                        if (evnt.TriggersContextMenu ()) {
 
263
                                item.ShowDockPopupMenu (evnt.Time);
 
264
                                return false;
 
265
                        } else if (evnt.Button == 1) {
 
266
                                if (evnt.Type == Gdk.EventType.ButtonPress) {
 
267
                                        tabPressed = true;
 
268
                                        pressX = evnt.X;
 
269
                                        pressY = evnt.Y;
 
270
                                } else if (evnt.Type == Gdk.EventType.TwoButtonPress) {
 
271
                                        tabActivated = true;
 
272
                                }
 
273
                        }
 
274
                        return base.OnButtonPressEvent (evnt);
 
275
                }
 
276
 
 
277
                protected override bool OnButtonReleaseEvent (Gdk.EventButton evnt)
 
278
                {
 
279
                        if (tabActivated) {
 
280
                                tabActivated = false;
 
281
                                if (item.Status == DockItemStatus.AutoHide)
 
282
                                        item.Status = DockItemStatus.Dockable;
 
283
                                else
 
284
                                        item.Status = DockItemStatus.AutoHide;
 
285
                        }
 
286
                        else if (!evnt.TriggersContextMenu () && evnt.Button == 1) {
 
287
                                frame.DockInPlaceholder (item);
 
288
                                frame.HidePlaceholder ();
 
289
                                if (GdkWindow != null)
 
290
                                        GdkWindow.Cursor = null;
 
291
                                frame.Toplevel.KeyPressEvent -= HeaderKeyPress;
 
292
                                frame.Toplevel.KeyReleaseEvent -= HeaderKeyRelease;
 
293
                        }
 
294
                        tabPressed = false;
 
295
                        return base.OnButtonReleaseEvent (evnt);
 
296
                }
 
297
 
 
298
                protected override bool OnMotionNotifyEvent (Gdk.EventMotion evnt)
 
299
                {
 
300
                        if (tabPressed && Math.Abs (evnt.X - pressX) > 3 && Math.Abs (evnt.Y - pressY) > 3) {
 
301
                                frame.ShowPlaceholder (item);
 
302
                                GdkWindow.Cursor = fleurCursor;
 
303
                                frame.Toplevel.KeyPressEvent += HeaderKeyPress;
 
304
                                frame.Toplevel.KeyReleaseEvent += HeaderKeyRelease;
 
305
                                allowPlaceholderDocking = true;
 
306
                                tabPressed = false;
 
307
                        }
 
308
                        frame.UpdatePlaceholder (item, Allocation.Size, allowPlaceholderDocking);
 
309
                        return base.OnMotionNotifyEvent (evnt);
 
310
                }
 
311
 
 
312
                protected override bool OnEnterNotifyEvent (Gdk.EventCrossing evnt)
 
313
                {
 
314
                        mouseOver = true;
 
315
                        UpdateBehavior ();
 
316
                        return base.OnEnterNotifyEvent (evnt);
 
317
                }
 
318
 
 
319
                void OnLeave ()
 
320
                {
 
321
                        mouseOver = false;
 
322
                        UpdateBehavior ();
 
323
                }
 
324
 
 
325
                [GLib.ConnectBeforeAttribute]
 
326
                void HeaderKeyPress (object ob, Gtk.KeyPressEventArgs a)
 
327
                {
 
328
                        if (a.Event.Key == Gdk.Key.Control_L || a.Event.Key == Gdk.Key.Control_R) {
 
329
                                allowPlaceholderDocking = false;
 
330
                                frame.UpdatePlaceholder (item, Allocation.Size, false);
 
331
                        }
 
332
                        if (a.Event.Key == Gdk.Key.Escape) {
 
333
                                frame.HidePlaceholder ();
 
334
                                frame.Toplevel.KeyPressEvent -= HeaderKeyPress;
 
335
                                frame.Toplevel.KeyReleaseEvent -= HeaderKeyRelease;
 
336
                                Gdk.Pointer.Ungrab (0);
 
337
                        }
 
338
                }
 
339
                
 
340
                [GLib.ConnectBeforeAttribute]
 
341
                void HeaderKeyRelease (object ob, Gtk.KeyReleaseEventArgs a)
 
342
                {
 
343
                        if (a.Event.Key == Gdk.Key.Control_L || a.Event.Key == Gdk.Key.Control_R) {
 
344
                                allowPlaceholderDocking = true;
 
345
                                frame.UpdatePlaceholder (item, Allocation.Size, true);
 
346
                        }
 
347
                }
 
348
 
 
349
                protected override void OnRealized ()
 
350
                {
 
351
                        base.OnRealized ();
 
352
                        UpdateVisualStyle ();
 
353
                }
 
354
                
 
355
                protected override void OnSizeRequested (ref Gtk.Requisition req)
 
356
                {
 
357
                        if (Child != null) {
 
358
                                req = Child.SizeRequest ();
 
359
                                req.Width += LeftPadding + RightPadding;
 
360
                                if (active)
 
361
                                        req.Height += TopPaddingActive + BottomPaddingActive;
 
362
                                else
 
363
                                        req.Height += TopPadding + BottomPadding;
 
364
                        }
 
365
                }
 
366
                                        
 
367
                protected override void OnSizeAllocated (Gdk.Rectangle rect)
 
368
                {
 
369
                        base.OnSizeAllocated (rect);
 
370
 
 
371
                        int leftPadding = LeftPadding;
 
372
                        int rightPadding = RightPadding;
 
373
                        if (rect.Width < labelWidth) {
 
374
                                int red = (labelWidth - rect.Width) / 2;
 
375
                                leftPadding -= red;
 
376
                                rightPadding -= red;
 
377
                                if (leftPadding < 2) leftPadding = 2;
 
378
                                if (rightPadding < 2) rightPadding = 2;
 
379
                        }
 
380
                        
 
381
                        rect.X += leftPadding;
 
382
                        rect.Width -= leftPadding + rightPadding;
 
383
 
 
384
                        if (Child != null) {
 
385
                                if (active) {
 
386
                                        rect.Y += TopPaddingActive;
 
387
                                        rect.Height = Child.SizeRequest ().Height;
 
388
                                }
 
389
                                else {
 
390
                                        rect.Y += TopPadding;
 
391
                                        rect.Height = Child.SizeRequest ().Height;
 
392
                                }
 
393
                                Child.SizeAllocate (rect);
 
394
                        }
 
395
                }
 
396
 
 
397
                protected override bool OnExposeEvent (Gdk.EventExpose evnt)
 
398
                {
 
399
                        if (VisualStyle.TabStyle == DockTabStyle.Normal)
 
400
                                DrawAsBrowser (evnt);
 
401
                        else
 
402
                                DrawNormal (evnt);
 
403
                        return base.OnExposeEvent (evnt);
 
404
                }
 
405
 
 
406
                void DrawAsBrowser (Gdk.EventExpose evnt)
 
407
                {
 
408
                        var alloc = Allocation;
 
409
 
 
410
                        Gdk.GC bgc = new Gdk.GC (GdkWindow);
 
411
                        var c = new HslColor (VisualStyle.PadBackgroundColor.Value);
 
412
                        c.L *= 0.7;
 
413
                        bgc.RgbFgColor = c;
 
414
                        bool first = true;
 
415
                        bool last = true;
 
416
                        TabStrip tabStrip = null;
 
417
                        if (Parent is TabStrip.TabStripBox) {
 
418
                                var tsb = (TabStrip.TabStripBox) Parent;
 
419
                                var cts = tsb.Children;
 
420
                                first = cts[0] == this;
 
421
                                last = cts[cts.Length - 1] == this;
 
422
                                tabStrip = tsb.TabStrip;
 
423
                        }
 
424
 
 
425
                        if (Active || (first && last)) {
 
426
                                Gdk.GC gc = new Gdk.GC (GdkWindow);
 
427
                                gc.RgbFgColor = VisualStyle.PadBackgroundColor.Value;
 
428
                                evnt.Window.DrawRectangle (gc, true, alloc);
 
429
                                if (!first)
 
430
                                        evnt.Window.DrawLine (bgc, alloc.X, alloc.Y, alloc.X, alloc.Y + alloc.Height - 1);
 
431
                                if (!(last && first) && !(tabStrip != null && tabStrip.VisualStyle.ExpandedTabs.Value && last))
 
432
                                        evnt.Window.DrawLine (bgc, alloc.X + alloc.Width - 1, alloc.Y, alloc.X + alloc.Width - 1, alloc.Y + alloc.Height - 1);
 
433
                                gc.Dispose ();
 
434
 
 
435
                        } else {
 
436
                                Gdk.GC gc = new Gdk.GC (GdkWindow);
 
437
                                gc.RgbFgColor = tabStrip != null ? tabStrip.VisualStyle.InactivePadBackgroundColor.Value : frame.DefaultVisualStyle.InactivePadBackgroundColor.Value;
 
438
                                evnt.Window.DrawRectangle (gc, true, alloc);
 
439
                                gc.Dispose ();
 
440
                                evnt.Window.DrawLine (bgc, alloc.X, alloc.Y + alloc.Height - 1, alloc.X + alloc.Width - 1, alloc.Y + alloc.Height - 1);
 
441
                        }
 
442
                        bgc.Dispose ();
 
443
                }
 
444
 
 
445
                void DrawNormal (Gdk.EventExpose evnt)
 
446
                {
 
447
                        using (var ctx = Gdk.CairoHelper.Create (GdkWindow)) {
 
448
                                var x = Allocation.X;
 
449
                                var y = Allocation.Y;
 
450
 
 
451
                                ctx.Rectangle (x, y + 1, Allocation.Width, Allocation.Height - 1);
 
452
                                using (var g = new Cairo.LinearGradient (x, y + 1, x, y + Allocation.Height - 1)) {
 
453
                                        g.AddColorStop (0, Styles.DockTabBarGradientStart);
 
454
                                        g.AddColorStop (1, Styles.DockTabBarGradientEnd);
 
455
                                        ctx.Pattern = g;
 
456
                                        ctx.Fill ();
 
457
                                }
 
458
 
 
459
                                ctx.MoveTo (x + 0.5, y + 0.5);
 
460
                                ctx.LineTo (x + Allocation.Width - 0.5d, y + 0.5);
 
461
                                ctx.Color = Styles.DockTabBarGradientTop;
 
462
                                ctx.Stroke ();
 
463
 
 
464
                                if (active) {
 
465
 
 
466
                                        ctx.Rectangle (x, y + 1, Allocation.Width, Allocation.Height - 1);
 
467
                                        using (var g = new Cairo.LinearGradient (x, y + 1, x, y + Allocation.Height - 1)) {
 
468
                                                g.AddColorStop (0, new Cairo.Color (0, 0, 0, 0.01));
 
469
                                                g.AddColorStop (0.5, new Cairo.Color (0, 0, 0, 0.08));
 
470
                                                g.AddColorStop (1, new Cairo.Color (0, 0, 0, 0.01));
 
471
                                                ctx.Pattern = g;
 
472
                                                ctx.Fill ();
 
473
                                        }
 
474
 
 
475
/*                                      double offset = Allocation.Height * 0.25;
 
476
                                        var rect = new Cairo.Rectangle (x - Allocation.Height + offset, y, Allocation.Height, Allocation.Height);
 
477
                                        var cg = new Cairo.RadialGradient (rect.X + rect.Width / 2, rect.Y + rect.Height / 2, 0, rect.X, rect.Y + rect.Height / 2, rect.Height / 2);
 
478
                                        cg.AddColorStop (0, Styles.DockTabBarShadowGradientStart);
 
479
                                        cg.AddColorStop (1, Styles.DockTabBarShadowGradientEnd);
 
480
                                        ctx.Pattern = cg;
 
481
                                        ctx.Rectangle (rect);
 
482
                                        ctx.Fill ();
 
483
 
 
484
                                        rect = new Cairo.Rectangle (x + Allocation.Width - offset, y, Allocation.Height, Allocation.Height);
 
485
                                        cg = new Cairo.RadialGradient (rect.X + rect.Width / 2, rect.Y + rect.Height / 2, 0, rect.X, rect.Y + rect.Height / 2, rect.Height / 2);
 
486
                                        cg.AddColorStop (0, Styles.DockTabBarShadowGradientStart);
 
487
                                        cg.AddColorStop (1, Styles.DockTabBarShadowGradientEnd);
 
488
                                        ctx.Pattern = cg;
 
489
                                        ctx.Rectangle (rect);
 
490
                                        ctx.Fill ();*/
 
491
                                }
 
492
                        }
 
493
                }
 
494
        }
 
495
}