fzeet 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,9 +6,33 @@ module Fzeet
6
6
 
7
7
  def LOWORD(l) l & 0xffff end
8
8
  def HIWORD(l) (l >> 16) & 0xffff end
9
+ def GET_X_LPARAM(lp) ((w = LOWORD(lp)) > 0x7fff) ? w - 0x1_0000 : w end
10
+ def GET_Y_LPARAM(lp) ((w = HIWORD(lp)) > 0x7fff) ? w - 0x1_0000 : w end
9
11
 
10
- module_function :LOWORD, :HIWORD
12
+ module_function \
13
+ :LOWORD, :HIWORD,
14
+ :GET_X_LPARAM, :GET_Y_LPARAM
11
15
 
12
16
  INVALID_HANDLE_VALUE = FFI::Pointer.new(-1)
17
+
18
+ class POINT < FFI::Struct
19
+ layout \
20
+ :x, :long,
21
+ :y, :long
22
+ end
23
+
24
+ class SIZE < FFI::Struct
25
+ layout \
26
+ :cx, :long,
27
+ :cy, :long
28
+ end
29
+
30
+ class RECT < FFI::Struct
31
+ layout \
32
+ :left, :long,
33
+ :top, :long,
34
+ :right, :long,
35
+ :bottom, :long
36
+ end
13
37
  end
14
38
  end
@@ -10,5 +10,8 @@ module Fzeet
10
10
  attach_function :GetStockObject, [:int], :pointer
11
11
  attach_function :CreateFontIndirect, :CreateFontIndirectA, [:pointer], :pointer
12
12
  attach_function :DeleteObject, [:pointer], :int
13
+
14
+ attach_function :MoveToEx, [:pointer, :int, :int, :pointer], :int
15
+ attach_function :LineTo, [:pointer, :int, :int], :int
13
16
  end
14
17
  end
@@ -5,23 +5,60 @@ module Fzeet
5
5
  ffi_lib 'user32'
6
6
  ffi_convention :stdcall
7
7
 
8
+ #{ MB_xxx
8
9
  MB_OK = 0x00000000
9
10
  MB_OKCANCEL = 0x00000001
11
+ MB_ABORTRETRYIGNORE = 0x00000002
10
12
  MB_YESNOCANCEL = 0x00000003
11
13
  MB_YESNO = 0x00000004
14
+ MB_RETRYCANCEL = 0x00000005
15
+ MB_CANCELTRYCONTINUE = 0x00000006
12
16
  MB_ICONHAND = 0x00000010
13
17
  MB_ICONQUESTION = 0x00000020
14
18
  MB_ICONEXCLAMATION = 0x00000030
15
19
  MB_ICONASTERISK = 0x00000040
20
+ MB_USERICON = 0x00000080
21
+ MB_ICONWARNING = MB_ICONEXCLAMATION
16
22
  MB_ICONERROR = MB_ICONHAND
17
23
  MB_ICONINFORMATION = MB_ICONASTERISK
24
+ MB_ICONSTOP = MB_ICONHAND
25
+ MB_DEFBUTTON1 = 0x00000000
18
26
  MB_DEFBUTTON2 = 0x00000100
19
27
  MB_DEFBUTTON3 = 0x00000200
20
-
28
+ MB_DEFBUTTON4 = 0x00000300
29
+ MB_APPLMODAL = 0x00000000
30
+ MB_SYSTEMMODAL = 0x00001000
31
+ MB_TASKMODAL = 0x00002000
32
+ MB_HELP = 0x00004000
33
+ MB_NOFOCUS = 0x00008000
34
+ MB_SETFOREGROUND = 0x00010000
35
+ MB_DEFAULT_DESKTOP_ONLY = 0x00020000
36
+ MB_TOPMOST = 0x00040000
37
+ MB_RIGHT = 0x00080000
38
+ MB_RTLREADING = 0x00100000
39
+ MB_SERVICE_NOTIFICATION = 0x00200000
40
+ MB_SERVICE_NOTIFICATION_NT3X = 0x00040000
41
+ MB_TYPEMASK = 0x0000000F
42
+ MB_ICONMASK = 0x000000F0
43
+ MB_DEFMASK = 0x00000F00
44
+ MB_MODEMASK = 0x00003000
45
+ MB_MISCMASK = 0x0000C000
46
+ #}
47
+
48
+ #{ IDxxx
21
49
  IDOK = 1
22
50
  IDCANCEL = 2
51
+ IDABORT = 3
52
+ IDRETRY = 4
53
+ IDIGNORE = 5
23
54
  IDYES = 6
24
55
  IDNO = 7
56
+ IDCLOSE = 8
57
+ IDHELP = 9
58
+ IDTRYAGAIN = 10
59
+ IDCONTINUE = 11
60
+ IDTIMEOUT = 32000
61
+ #}
25
62
 
26
63
  attach_function :MessageBox, :MessageBoxA, [:pointer, :string, :string, :uint], :int
27
64
 
@@ -29,15 +66,102 @@ module Fzeet
29
66
 
30
67
  attach_function :DefWindowProc, :DefWindowProcA, [:pointer, :uint, :uint, :long], :long
31
68
 
69
+ callback :DLGPROC, [:pointer, :uint, :uint, :long], :int
70
+
71
+ attach_function :DefDlgProc, :DefDlgProcA, [:pointer, :uint, :uint, :long], :long
72
+
73
+ #{ IDI_xxx
32
74
  IDI_APPLICATION = FFI::Pointer.new(32512)
75
+ IDI_HAND = FFI::Pointer.new(32513)
76
+ IDI_QUESTION = FFI::Pointer.new(32514)
77
+ IDI_EXCLAMATION = FFI::Pointer.new(32515)
78
+ IDI_ASTERISK = FFI::Pointer.new(32516)
79
+ IDI_WINLOGO = FFI::Pointer.new(32517)
80
+ IDI_SHIELD = FFI::Pointer.new(32518)
81
+ IDI_WARNING = IDI_EXCLAMATION
82
+ IDI_ERROR = IDI_HAND
83
+ IDI_INFORMATION = IDI_ASTERISK
84
+ #}
33
85
 
34
86
  attach_function :LoadIcon, :LoadIconA, [:pointer, :pointer], :pointer
35
87
 
88
+ #{ IDC_xxx
36
89
  IDC_ARROW = FFI::Pointer.new(32512)
90
+ IDC_IBEAM = FFI::Pointer.new(32513)
91
+ IDC_WAIT = FFI::Pointer.new(32514)
92
+ IDC_CROSS = FFI::Pointer.new(32515)
93
+ IDC_UPARROW = FFI::Pointer.new(32516)
94
+ IDC_SIZE = FFI::Pointer.new(32640)
95
+ IDC_ICON = FFI::Pointer.new(32641)
96
+ IDC_SIZENWSE = FFI::Pointer.new(32642)
97
+ IDC_SIZENESW = FFI::Pointer.new(32643)
98
+ IDC_SIZEWE = FFI::Pointer.new(32644)
99
+ IDC_SIZENS = FFI::Pointer.new(32645)
100
+ IDC_SIZEALL = FFI::Pointer.new(32646)
101
+ IDC_NO = FFI::Pointer.new(32648)
102
+ IDC_HAND = FFI::Pointer.new(32649)
103
+ IDC_APPSTARTING = FFI::Pointer.new(32650)
104
+ IDC_HELP = FFI::Pointer.new(32651)
105
+ #}
37
106
 
38
107
  attach_function :LoadCursor, :LoadCursorA, [:pointer, :pointer], :pointer
39
108
 
109
+ IMAGE_BITMAP = 0
110
+
111
+ LR_LOADFROMFILE = 0x00000010
112
+ LR_CREATEDIBSECTION = 0x00002000
113
+
114
+ attach_function :LoadImage, :LoadImageA, [:pointer, :string, :uint, :int, :int, :uint], :pointer
115
+
116
+ #{ COLOR_xxx
117
+ COLOR_SCROLLBAR = 0
118
+ COLOR_BACKGROUND = 1
119
+ COLOR_ACTIVECAPTION = 2
120
+ COLOR_INACTIVECAPTION = 3
121
+ COLOR_MENU = 4
40
122
  COLOR_WINDOW = 5
123
+ COLOR_WINDOWFRAME = 6
124
+ COLOR_MENUTEXT = 7
125
+ COLOR_WINDOWTEXT = 8
126
+ COLOR_CAPTIONTEXT = 9
127
+ COLOR_ACTIVEBORDER = 10
128
+ COLOR_INACTIVEBORDER = 11
129
+ COLOR_APPWORKSPACE = 12
130
+ COLOR_HIGHLIGHT = 13
131
+ COLOR_HIGHLIGHTTEXT = 14
132
+ COLOR_BTNFACE = 15
133
+ COLOR_BTNSHADOW = 16
134
+ COLOR_GRAYTEXT = 17
135
+ COLOR_BTNTEXT = 18
136
+ COLOR_INACTIVECAPTIONTEXT = 19
137
+ COLOR_BTNHIGHLIGHT = 20
138
+ COLOR_3DDKSHADOW = 21
139
+ COLOR_3DLIGHT = 22
140
+ COLOR_INFOTEXT = 23
141
+ COLOR_INFOBK = 24
142
+ COLOR_HOTLIGHT = 26
143
+ COLOR_GRADIENTACTIVECAPTION = 27
144
+ COLOR_GRADIENTINACTIVECAPTION = 28
145
+ COLOR_MENUHILIGHT = 29
146
+ COLOR_MENUBAR = 30
147
+ COLOR_DESKTOP = COLOR_BACKGROUND
148
+ COLOR_3DFACE = COLOR_BTNFACE
149
+ COLOR_3DSHADOW = COLOR_BTNSHADOW
150
+ COLOR_3DHIGHLIGHT = COLOR_BTNHIGHLIGHT
151
+ COLOR_3DHILIGHT = COLOR_BTNHIGHLIGHT
152
+ COLOR_BTNHILIGHT = COLOR_BTNHIGHLIGHT
153
+ #}
154
+
155
+ #{ CTLCOLOR_xxx
156
+ CTLCOLOR_MSGBOX = 0
157
+ CTLCOLOR_EDIT = 1
158
+ CTLCOLOR_LISTBOX = 2
159
+ CTLCOLOR_BTN = 3
160
+ CTLCOLOR_DLG = 4
161
+ CTLCOLOR_SCROLLBAR = 5
162
+ CTLCOLOR_STATIC = 6
163
+ CTLCOLOR_MAX = 7
164
+ #}
41
165
 
42
166
  class WNDCLASSEX < FFI::Struct
43
167
  layout \
@@ -57,16 +181,65 @@ module Fzeet
57
181
 
58
182
  attach_function :RegisterClassEx, :RegisterClassExA, [:pointer], :ushort
59
183
 
184
+ #{ WS_xxx
60
185
  WS_OVERLAPPED = 0x00000000
186
+ WS_POPUP = 0x80000000
61
187
  WS_CHILD = 0x40000000
188
+ WS_MINIMIZE = 0x20000000
62
189
  WS_VISIBLE = 0x10000000
190
+ WS_DISABLED = 0x08000000
191
+ WS_CLIPSIBLINGS = 0x04000000
63
192
  WS_CLIPCHILDREN = 0x02000000
193
+ WS_MAXIMIZE = 0x01000000
64
194
  WS_CAPTION = 0x00C00000
195
+ WS_BORDER = 0x00800000
196
+ WS_DLGFRAME = 0x00400000
197
+ WS_VSCROLL = 0x00200000
198
+ WS_HSCROLL = 0x00100000
65
199
  WS_SYSMENU = 0x00080000
66
200
  WS_THICKFRAME = 0x00040000
201
+ WS_GROUP = 0x00020000
202
+ WS_TABSTOP = 0x00010000
67
203
  WS_MINIMIZEBOX = 0x00020000
68
204
  WS_MAXIMIZEBOX = 0x00010000
205
+ WS_TILED = WS_OVERLAPPED
206
+ WS_ICONIC = WS_MINIMIZE
207
+ WS_SIZEBOX = WS_THICKFRAME
69
208
  WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX
209
+ WS_TILEDWINDOW = WS_OVERLAPPEDWINDOW
210
+ WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU
211
+ WS_CHILDWINDOW = WS_CHILD
212
+ WS_ACTIVECAPTION = 0x0001
213
+ #}
214
+
215
+ #{ WS_EX_xxx
216
+ WS_EX_DLGMODALFRAME = 0x00000001
217
+ WS_EX_NOPARENTNOTIFY = 0x00000004
218
+ WS_EX_TOPMOST = 0x00000008
219
+ WS_EX_ACCEPTFILES = 0x00000010
220
+ WS_EX_TRANSPARENT = 0x00000020
221
+ WS_EX_MDICHILD = 0x00000040
222
+ WS_EX_TOOLWINDOW = 0x00000080
223
+ WS_EX_WINDOWEDGE = 0x00000100
224
+ WS_EX_CLIENTEDGE = 0x00000200
225
+ WS_EX_CONTEXTHELP = 0x00000400
226
+ WS_EX_RIGHT = 0x00001000
227
+ WS_EX_LEFT = 0x00000000
228
+ WS_EX_RTLREADING = 0x00002000
229
+ WS_EX_LTRREADING = 0x00000000
230
+ WS_EX_LEFTSCROLLBAR = 0x00004000
231
+ WS_EX_RIGHTSCROLLBAR = 0x00000000
232
+ WS_EX_CONTROLPARENT = 0x00010000
233
+ WS_EX_STATICEDGE = 0x00020000
234
+ WS_EX_APPWINDOW = 0x00040000
235
+ WS_EX_OVERLAPPEDWINDOW = WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE
236
+ WS_EX_PALETTEWINDOW = WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST
237
+ WS_EX_LAYERED = 0x00080000
238
+ WS_EX_NOINHERITLAYOUT = 0x00100000
239
+ WS_EX_LAYOUTRTL = 0x00400000
240
+ WS_EX_COMPOSITED = 0x02000000
241
+ WS_EX_NOACTIVATE = 0x08000000
242
+ #}
70
243
 
71
244
  CW_USEDEFAULT = -0x80000000
72
245
 
@@ -87,17 +260,70 @@ module Fzeet
87
260
  end
88
261
 
89
262
  attach_function :CreateWindowEx, :CreateWindowExA, [:ulong, :string, :string, :ulong, :int, :int, :int, :int, :pointer, :pointer, :pointer, :pointer], :pointer
263
+ attach_function :CreateDialogIndirectParam, :CreateDialogIndirectParamA, [:pointer, :pointer, :pointer, :DLGPROC, :long], :pointer
90
264
  attach_function :DestroyWindow, [:pointer], :int
91
265
 
266
+ #{ DS_xxx
267
+ DS_ABSALIGN = 0x01
268
+ DS_SYSMODAL = 0x02
269
+ DS_LOCALEDIT = 0x20
270
+ DS_SETFONT = 0x40
271
+ DS_MODALFRAME = 0x80
272
+ DS_NOIDLEMSG = 0x100
273
+ DS_SETFOREGROUND = 0x200
274
+ DS_3DLOOK = 0x0004
275
+ DS_FIXEDSYS = 0x0008
276
+ DS_NOFAILCREATE = 0x0010
277
+ DS_CONTROL = 0x0400
278
+ DS_CENTER = 0x0800
279
+ DS_CENTERMOUSE = 0x1000
280
+ DS_CONTEXTHELP = 0x2000
281
+ DS_SHELLFONT = DS_SETFONT | DS_FIXEDSYS
282
+ DS_USEPIXELS = 0x8000
283
+ #}
284
+
285
+ class DLGTEMPLATE < FFI::Struct
286
+ layout \
287
+ :style, :ulong,
288
+ :dwExtendedStyle, :ulong,
289
+ :cdit, :ushort,
290
+ :x, :short,
291
+ :y, :short,
292
+ :cx, :short,
293
+ :cy, :short,
294
+ :menu, :ushort,
295
+ :windowClass, :ushort,
296
+ :title, :ushort
297
+ end
298
+
299
+ attach_function :DialogBoxIndirectParam, :DialogBoxIndirectParamA, [:pointer, :pointer, :pointer, :DLGPROC, :long], :int
300
+ attach_function :EndDialog, [:pointer, :int], :int
301
+
92
302
  SW_SHOWNORMAL = 1
93
303
 
94
304
  attach_function :ShowWindow, [:pointer, :int], :int
95
305
 
96
306
  attach_function :UpdateWindow, [:pointer], :int
97
307
 
308
+ attach_function :GetWindowTextLength, :GetWindowTextLengthA, [:pointer], :int
309
+ attach_function :GetWindowText, :GetWindowTextA, [:pointer, :pointer, :int], :int
310
+ attach_function :SetWindowText, :SetWindowTextA, [:pointer, :string], :int
311
+
98
312
  attach_function :IsWindowEnabled, [:pointer], :int
99
313
  attach_function :EnableWindow, [:pointer, :int], :int
100
314
 
315
+ attach_function :GetCursorPos, [:pointer], :int
316
+
317
+ attach_function :ScreenToClient, [:pointer, :pointer], :int
318
+ attach_function :ClientToScreen, [:pointer, :pointer], :int
319
+
320
+ attach_function :GetCapture, [], :pointer
321
+ attach_function :SetCapture, [:pointer], :pointer
322
+ attach_function :ReleaseCapture, [], :int
323
+
324
+ attach_function :GetDC, [:pointer], :pointer
325
+ attach_function :ReleaseDC, [:pointer, :pointer], :int
326
+
101
327
  attach_function :GetDlgItem, [:pointer, :int], :pointer
102
328
 
103
329
  callback :WNDENUMPROC, [:pointer, :long], :int
@@ -121,12 +347,37 @@ module Fzeet
121
347
  MF_POPUP = 0x00000010
122
348
  MF_RIGHTJUSTIFY = 0x00004000
123
349
 
350
+ MFT_RADIOCHECK = 0x00000200
351
+
124
352
  attach_function :AppendMenu, :AppendMenuA, [:pointer, :uint, :uint, :string], :int
125
353
  attach_function :GetMenuState, [:pointer, :uint, :uint], :uint
126
354
  attach_function :EnableMenuItem, [:pointer, :uint, :uint], :int
127
355
  attach_function :CheckMenuItem, [:pointer, :uint, :uint], :ulong
128
356
  attach_function :CheckMenuRadioItem, [:pointer, :uint, :uint, :uint, :uint], :int
129
357
 
358
+ MIIM_BITMAP = 0x00000080
359
+
360
+ class MENUITEMINFO < FFI::Struct
361
+ layout \
362
+ :cbSize, :uint,
363
+ :fMask, :uint,
364
+ :fType, :uint,
365
+ :fState, :uint,
366
+ :wID, :uint,
367
+ :hSubMenu, :pointer,
368
+ :hbmpChecked, :pointer,
369
+ :hbmpUnchecked, :pointer,
370
+ :dwItemData, :ulong,
371
+ :dwTypeData, :pointer,
372
+ :cch, :uint,
373
+ :hbmpItem, :pointer
374
+ end
375
+
376
+ attach_function :GetMenuItemInfo, :GetMenuItemInfoA, [:pointer, :uint, :int, :pointer], :int
377
+ attach_function :SetMenuItemInfo, :SetMenuItemInfoA, [:pointer, :uint, :int, :pointer], :int
378
+
379
+ attach_function :TrackPopupMenu, [:pointer, :uint, :int, :int, :int, :pointer, :pointer], :int
380
+
130
381
  FVIRTKEY = 1
131
382
  FSHIFT = 0x04
132
383
  FCONTROL = 0x08
@@ -142,39 +393,6 @@ module Fzeet
142
393
  attach_function :CreateAcceleratorTable, :CreateAcceleratorTableA, [:pointer, :int], :pointer
143
394
  attach_function :DestroyAcceleratorTable, [:pointer], :int
144
395
 
145
- WM_CREATE = 0x0001
146
- WM_DESTROY = 0x0002
147
- WM_CLOSE = 0x0010
148
- WM_SETFONT = 0x0030
149
- WM_NCCREATE = 0x0081
150
- WM_NCDESTROY = 0x0082
151
- WM_COMMAND = 0x0111
152
- WM_APP = 0x8000
153
-
154
- class POINT < FFI::Struct
155
- layout \
156
- :x, :long,
157
- :y, :long
158
- end
159
-
160
- class MSG < FFI::Struct
161
- layout \
162
- :hwnd, :pointer,
163
- :message, :uint,
164
- :wParam, :uint,
165
- :lParam, :long,
166
- :time, :ulong,
167
- :pt, POINT
168
- end
169
-
170
- attach_function :GetMessage, :GetMessageA, [:pointer, :pointer, :uint, :uint], :int
171
- attach_function :TranslateAccelerator, :TranslateAcceleratorA, [:pointer, :pointer, :pointer], :int
172
- attach_function :TranslateMessage, [:pointer], :int
173
- attach_function :DispatchMessage, :DispatchMessageA, [:pointer], :long
174
- attach_function :SendMessage, :SendMessageA, [:pointer, :uint, :uint, :long], :long
175
- attach_function :PostMessage, :PostMessageA, [:pointer, :uint, :uint, :long], :int
176
- attach_function :PostQuitMessage, [:int], :void
177
-
178
396
  SPI_GETNONCLIENTMETRICS = 0x0029
179
397
 
180
398
  class LOGFONT < FFI::Struct
@@ -0,0 +1,68 @@
1
+ require_relative 'common'
2
+
3
+ module Fzeet
4
+ module Windows
5
+ if __FILE__ == $0
6
+ ffi_lib 'user32'
7
+ ffi_convention :stdcall
8
+ end
9
+
10
+ class NMHDR < FFI::Struct
11
+ layout \
12
+ :hwndFrom, :pointer,
13
+ :idFrom, :uint,
14
+ :code, :uint
15
+ end
16
+
17
+ BS_PUSHBUTTON = 0x00000000
18
+ BS_DEFPUSHBUTTON = 0x00000001
19
+ BS_CHECKBOX = 0x00000002
20
+ BS_AUTOCHECKBOX = 0x00000003
21
+ BS_RADIOBUTTON = 0x00000004
22
+ BS_3STATE = 0x00000005
23
+ BS_AUTO3STATE = 0x00000006
24
+ BS_GROUPBOX = 0x00000007
25
+ BS_USERBUTTON = 0x00000008
26
+ BS_AUTORADIOBUTTON = 0x00000009
27
+ BS_PUSHBOX = 0x0000000A
28
+ BS_OWNERDRAW = 0x0000000B
29
+ BS_TYPEMASK = 0x0000000F
30
+ BS_LEFTTEXT = 0x00000020
31
+ BS_TEXT = 0x00000000
32
+ BS_ICON = 0x00000040
33
+ BS_BITMAP = 0x00000080
34
+ BS_LEFT = 0x00000100
35
+ BS_RIGHT = 0x00000200
36
+ BS_CENTER = 0x00000300
37
+ BS_TOP = 0x00000400
38
+ BS_BOTTOM = 0x00000800
39
+ BS_VCENTER = 0x00000C00
40
+ BS_PUSHLIKE = 0x00001000
41
+ BS_MULTILINE = 0x00002000
42
+ BS_NOTIFY = 0x00004000
43
+ BS_FLAT = 0x00008000
44
+ BS_RIGHTBUTTON = BS_LEFTTEXT
45
+
46
+ BM_GETCHECK = 0x00F0
47
+ BM_SETCHECK = 0x00F1
48
+ BM_GETSTATE = 0x00F2
49
+ BM_SETSTATE = 0x00F3
50
+ BM_SETSTYLE = 0x00F4
51
+ BM_CLICK = 0x00F5
52
+ BM_GETIMAGE = 0x00F6
53
+ BM_SETIMAGE = 0x00F7
54
+ BM_SETDONTCLICK = 0x00F8
55
+
56
+ BN_CLICKED = 0
57
+ BN_PAINT = 1
58
+ BN_HILITE = 2
59
+ BN_UNHILITE = 3
60
+ BN_DISABLE = 4
61
+ BN_DOUBLECLICKED = 5
62
+ BN_PUSHED = BN_HILITE
63
+ BN_UNPUSHED = BN_UNHILITE
64
+ BN_DBLCLK = BN_DOUBLECLICKED
65
+ BN_SETFOCUS = 6
66
+ BN_KILLFOCUS = 7
67
+ end
68
+ end