ftp_paradise 1.4.5 → 1.5.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +155 -28
  3. data/bin/{iftp → ftp_paradise_shell} +1 -1
  4. data/doc/README.gen +97 -15
  5. data/doc/todo/{TODO_FOR_FTP_PARADISE_PROJECT.md → todo_for_the_ftp_paradise_project.md} +11 -1
  6. data/ftp_paradise.gemspec +30 -39
  7. data/lib/ftp_paradise/base/base.rb +375 -0
  8. data/lib/ftp_paradise/colours/colours.rb +27 -27
  9. data/lib/ftp_paradise/colours/use_colours.rb +6 -1
  10. data/lib/ftp_paradise/configuration/configuration.rb +7 -4
  11. data/lib/ftp_paradise/connection/README.md +0 -0
  12. data/lib/ftp_paradise/connection/connection.rb +2782 -15
  13. data/lib/ftp_paradise/constants/constants.rb +91 -5
  14. data/lib/ftp_paradise/entry/entry.rb +42 -5
  15. data/lib/ftp_paradise/{connection → gui/gtk3/ftp_client}/constants.rb +33 -21
  16. data/lib/ftp_paradise/gui/{shared_code/ftp_paradise/ftp_paradise_module.rb → gtk3/ftp_client/ftp_client.rb} +658 -170
  17. data/lib/ftp_paradise/gui/gtk3/ftp_client/misc.rb +27 -0
  18. data/lib/ftp_paradise/project/project.rb +11 -15
  19. data/lib/ftp_paradise/requires/require_class_connection.rb +7 -0
  20. data/lib/ftp_paradise/requires/require_net_ftp.rb +7 -0
  21. data/lib/ftp_paradise/requires/require_the_ftp_paradise_project.rb +4 -3
  22. data/lib/ftp_paradise/requires/require_the_ftp_paradise_project_with_the_GUI_bindings.rb +1 -1
  23. data/lib/ftp_paradise/requires/require_the_toplevel_methods.rb +1 -0
  24. data/lib/ftp_paradise/{interactive_ftp → shell}/menu.rb +564 -449
  25. data/lib/ftp_paradise/shell/shell.rb +2321 -0
  26. data/lib/ftp_paradise/toplevel_methods/connect.rb +3 -0
  27. data/lib/ftp_paradise/toplevel_methods/dataset.rb +111 -0
  28. data/lib/ftp_paradise/toplevel_methods/file_related_actions.rb +4 -3
  29. data/lib/ftp_paradise/toplevel_methods/ftp_object.rb +6 -5
  30. data/lib/ftp_paradise/toplevel_methods/login_name.rb +6 -4
  31. data/lib/ftp_paradise/toplevel_methods/misc.rb +19 -0
  32. data/lib/ftp_paradise/toplevel_methods/opn.rb +1 -1
  33. data/lib/ftp_paradise/toplevel_methods/password.rb +4 -2
  34. data/lib/ftp_paradise/toplevel_methods/port.rb +4 -1
  35. data/lib/ftp_paradise/toplevel_methods/remote_url.rb +11 -5
  36. data/lib/ftp_paradise/toplevel_methods/upload_and_download.rb +1 -0
  37. data/lib/ftp_paradise/version/version.rb +6 -1
  38. data/lib/ftp_paradise/www/web_interface.cgi +1 -1
  39. data/lib/ftp_paradise/yaml/automatically_connect_on_startup_of_the_interactive_ftp_shell.yml +0 -0
  40. data/lib/ftp_paradise/yaml/debug.yml +0 -0
  41. data/lib/ftp_paradise/yaml/open_in_default_editor.yml +0 -0
  42. data/lib/ftp_paradise/yaml/show_full_names.yml +0 -0
  43. data/lib/ftp_paradise/yaml/use_colours.yml +0 -0
  44. data/test/testing_minimal_pure_net_ftp_example_to_connect.rb +13 -3
  45. metadata +52 -126
  46. data/lib/ftp_paradise/base/cliner.rb +0 -23
  47. data/lib/ftp_paradise/base/colours.rb +0 -83
  48. data/lib/ftp_paradise/base/prototype.rb +0 -171
  49. data/lib/ftp_paradise/base/reset.rb +0 -29
  50. data/lib/ftp_paradise/connection/data.rb +0 -164
  51. data/lib/ftp_paradise/connection/debug.rb +0 -78
  52. data/lib/ftp_paradise/connection/directory_handling.rb +0 -271
  53. data/lib/ftp_paradise/connection/do_login.rb +0 -108
  54. data/lib/ftp_paradise/connection/download.rb +0 -86
  55. data/lib/ftp_paradise/connection/file_handling.rb +0 -174
  56. data/lib/ftp_paradise/connection/ftp_object.rb +0 -21
  57. data/lib/ftp_paradise/connection/initialize.rb +0 -88
  58. data/lib/ftp_paradise/connection/initialize_a_new_net_ftp_object_with_this_url.rb +0 -20
  59. data/lib/ftp_paradise/connection/is_connected.rb +0 -46
  60. data/lib/ftp_paradise/connection/misc.rb +0 -474
  61. data/lib/ftp_paradise/connection/notify.rb +0 -71
  62. data/lib/ftp_paradise/connection/password.rb +0 -47
  63. data/lib/ftp_paradise/connection/port.rb +0 -33
  64. data/lib/ftp_paradise/connection/remote_pwd.rb +0 -72
  65. data/lib/ftp_paradise/connection/remote_url.rb +0 -164
  66. data/lib/ftp_paradise/connection/remove.rb +0 -143
  67. data/lib/ftp_paradise/connection/reset.rb +0 -78
  68. data/lib/ftp_paradise/connection/run.rb +0 -18
  69. data/lib/ftp_paradise/connection/set_array_available_hosts.rb +0 -27
  70. data/lib/ftp_paradise/connection/set_input.rb +0 -18
  71. data/lib/ftp_paradise/connection/show.rb +0 -153
  72. data/lib/ftp_paradise/connection/sync_ftp_object_onto_the_main_namespace.rb +0 -24
  73. data/lib/ftp_paradise/connection/transfer_mode.rb +0 -163
  74. data/lib/ftp_paradise/connection/upload.rb +0 -253
  75. data/lib/ftp_paradise/connection/use_default_dataset.rb +0 -40
  76. data/lib/ftp_paradise/connection/username.rb +0 -42
  77. data/lib/ftp_paradise/constants/misc.rb +0 -57
  78. data/lib/ftp_paradise/constants/namespace.rb +0 -14
  79. data/lib/ftp_paradise/constants/newline.rb +0 -14
  80. data/lib/ftp_paradise/constants/roebe.rb +0 -31
  81. data/lib/ftp_paradise/constants/roebe_ftp_constants.rb +0 -233
  82. data/lib/ftp_paradise/gui/gtk2/ftp_paradise.rb +0 -34
  83. data/lib/ftp_paradise/gui/gtk3/ftp_paradise.rb +0 -34
  84. data/lib/ftp_paradise/interactive_ftp/constants.rb +0 -103
  85. data/lib/ftp_paradise/interactive_ftp/directory_handling.rb +0 -216
  86. data/lib/ftp_paradise/interactive_ftp/help.rb +0 -50
  87. data/lib/ftp_paradise/interactive_ftp/initialize.rb +0 -27
  88. data/lib/ftp_paradise/interactive_ftp/interactive_ftp.rb +0 -998
  89. data/lib/ftp_paradise/interactive_ftp/main_loop.rb +0 -51
  90. data/lib/ftp_paradise/interactive_ftp/misc.rb +0 -208
  91. data/lib/ftp_paradise/interactive_ftp/mode.rb +0 -124
  92. data/lib/ftp_paradise/interactive_ftp/readline.rb +0 -113
  93. data/lib/ftp_paradise/interactive_ftp/remove.rb +0 -97
  94. data/lib/ftp_paradise/interactive_ftp/reset.rb +0 -90
  95. data/lib/ftp_paradise/interactive_ftp/run.rb +0 -22
  96. data/lib/ftp_paradise/interactive_ftp/show.rb +0 -184
  97. data/lib/ftp_paradise/interactive_ftp/upload.rb +0 -90
  98. data/lib/ftp_paradise/interactive_ftp/user_input.rb +0 -53
  99. data/lib/ftp_paradise/toplevel_methods/can_connect_to_remote_site.rb +0 -28
  100. data/lib/ftp_paradise/toplevel_methods/clear_user_dataset.rb +0 -28
  101. data/lib/ftp_paradise/toplevel_methods/data.rb +0 -31
  102. data/lib/ftp_paradise/toplevel_methods/determine_user_dataset_from_this_hash.rb +0 -37
@@ -0,0 +1,375 @@
1
+ #!/usr/bin/ruby -w
2
+ # Encoding: UTF-8
3
+ # frozen_string_literal: true
4
+ # =========================================================================== #
5
+ # require 'ftp_paradise/base/base.rb'
6
+ # include FtpParadise::Base
7
+ # =========================================================================== #
8
+ module FtpParadise
9
+
10
+ module Base
11
+
12
+ require 'fileutils'
13
+ require 'tmpdir'
14
+
15
+ require 'ftp_paradise/colours/colours.rb'
16
+ require 'ftp_paradise/constants/constants.rb'
17
+ require 'ftp_paradise/project/project.rb'
18
+ # ========================================================================= #
19
+ # The next .rb file will pull in "cliner":
20
+ # ========================================================================= #
21
+ require 'ftp_paradise/requires/common_external_requires.rb'
22
+
23
+ # ========================================================================= #
24
+ # The various project's toplevel_methods files are required next:
25
+ # ========================================================================= #
26
+ require 'ftp_paradise/requires/require_the_toplevel_methods.rb'
27
+
28
+ # ========================================================================= #
29
+ # === N
30
+ # ========================================================================= #
31
+ N = "\n"
32
+
33
+ # ========================================================================= #
34
+ # === reset
35
+ # ========================================================================= #
36
+ def reset
37
+ # ======================================================================= #
38
+ # === @internal_hash
39
+ # ======================================================================= #
40
+ @internal_hash = {}
41
+ # ======================================================================= #
42
+ # === :use_colours
43
+ # ======================================================================= #
44
+ @internal_hash[:use_colours] = true
45
+ # ======================================================================= #
46
+ # === :be_verbose
47
+ # ======================================================================= #
48
+ @internal_hash[:be_verbose] = true
49
+ end
50
+
51
+ # ========================================================================= #
52
+ # === sdir
53
+ # ========================================================================= #
54
+ def sdir(i = '')
55
+ return ::FtpParadise.sdir(i) if use_colours?
56
+ return i
57
+ end
58
+
59
+ # ========================================================================= #
60
+ # === simp
61
+ # ========================================================================= #
62
+ def simp(i = '')
63
+ return ::FtpParadise.simp(i) if use_colours?
64
+ return i
65
+ end; alias simportant simp # === simportant
66
+
67
+ # ========================================================================= #
68
+ # === orange
69
+ # ========================================================================= #
70
+ def orange(i = '')
71
+ return ::Colours.orange(i) if use_colours?
72
+ return i
73
+ end
74
+
75
+ # ========================================================================= #
76
+ # === tomato
77
+ # ========================================================================= #
78
+ def tomato(i = '')
79
+ return ::Colours.tomato(i) if use_colours?
80
+ return i
81
+ end
82
+
83
+ # ========================================================================= #
84
+ # === sandybrown
85
+ # ========================================================================= #
86
+ def sandybrown(i = '')
87
+ return ::Colours.sandybrown(i) if use_colours?
88
+ return i
89
+ end
90
+
91
+ # ========================================================================= #
92
+ # === steelblue
93
+ # ========================================================================= #
94
+ def steelblue(i = '')
95
+ return ::Colours.steelblue(i) if use_colours?
96
+ return i
97
+ end
98
+
99
+ # ========================================================================= #
100
+ # === royalblue
101
+ # ========================================================================= #
102
+ def royalblue(i = '')
103
+ FtpParadise.royalblue(i)
104
+ end
105
+
106
+ # ========================================================================= #
107
+ # === slateblue
108
+ # ========================================================================= #
109
+ def slateblue(i = '')
110
+ FtpParadise.slateblue(i)
111
+ end
112
+
113
+ # ========================================================================= #
114
+ # === be_verbose?
115
+ # ========================================================================= #
116
+ def be_verbose?
117
+ @internal_hash[:be_verbose]
118
+ end
119
+
120
+ # ========================================================================= #
121
+ # === be_quiet
122
+ # ========================================================================= #
123
+ def be_quiet
124
+ @internal_hash[:be_verbose] = false
125
+ end; alias be_silent be_quiet # === be_silent
126
+
127
+ # ========================================================================= #
128
+ # === set_be_verbose
129
+ #
130
+ # Set the verbosity mode.
131
+ # ========================================================================= #
132
+ def set_be_verbose(i = true)
133
+ @internal_hash[:be_verbose] = i
134
+ end; alias be_verbose= set_be_verbose # === be_verbose=
135
+ alias be_verbose set_be_verbose # === be_verbose
136
+
137
+ # ========================================================================= #
138
+ # === opnn
139
+ # ========================================================================= #
140
+ def opnn(i = NAMESPACE)
141
+ if i.is_a? String
142
+ i = { namespace: i }
143
+ end
144
+ FtpParadise.opnn(i)
145
+ end
146
+
147
+ # ========================================================================= #
148
+ # === rds
149
+ # ========================================================================= #
150
+ def rds(i = '')
151
+ FtpParadise.rds(i)
152
+ end
153
+
154
+ # ========================================================================= #
155
+ # === touch
156
+ # ========================================================================= #
157
+ def touch(i = '')
158
+ FtpParadise.touch(i)
159
+ end
160
+
161
+ # ========================================================================= #
162
+ # === get_files
163
+ # ========================================================================= #
164
+ def get_files(i = '')
165
+ FtpParadise.get_files(i)
166
+ end
167
+
168
+ # ========================================================================= #
169
+ # === return_all_local_entries
170
+ #
171
+ # This will return an array.
172
+ # ========================================================================= #
173
+ def return_all_local_entries(
174
+ from_where = Dir.pwd
175
+ )
176
+ Dir["#{from_where}/**/**"]
177
+ end; alias return_directory_content return_all_local_entries # === return_directory_content
178
+
179
+ # ========================================================================= #
180
+ # === e
181
+ # ========================================================================= #
182
+ def e(i = '')
183
+ FtpParadise.e(i)
184
+ end
185
+
186
+ # ========================================================================= #
187
+ # === parens (parens tag)
188
+ # ========================================================================= #
189
+ def parens(i)
190
+ padding_to_use = ' ' * 5
191
+ return sfancy("#{padding_to_use}(#{i}) ")
192
+ end
193
+
194
+ # ========================================================================= #
195
+ # === pound_token
196
+ #
197
+ # Simply return a colourized pound token next, but only if we use colours.
198
+ # ========================================================================= #
199
+ def pound_token
200
+ _ = '# '
201
+ if use_colours?
202
+ return "#{Colours::CYAN}#{_}#{Colours::WHITE}"
203
+ end
204
+ _
205
+ end
206
+
207
+ # ========================================================================= #
208
+ # === return_time
209
+ # ========================================================================= #
210
+ def return_time
211
+ FtpParadise.return_time
212
+ end
213
+
214
+ # ========================================================================= #
215
+ # === do_use_colours
216
+ # ========================================================================= #
217
+ def do_use_colours
218
+ @internal_hash[:use_colours] = true
219
+ end
220
+
221
+ # ========================================================================= #
222
+ # === cd
223
+ # ========================================================================= #
224
+ def cd(i)
225
+ Dir.chdir(i) if File.directory? i
226
+ end; alias change_local_directory cd # === change_local_directory
227
+
228
+ # ========================================================================= #
229
+ # === register_sigint
230
+ # ========================================================================= #
231
+ def register_sigint
232
+ Signal.trap('SIGINT') {
233
+ e 'Please use "q" to quit.'
234
+ }
235
+ end
236
+
237
+ # ========================================================================= #
238
+ # === try_to_create_a_temporary_log_directory_and_cd_into_it_or_the_temp_directory
239
+ #
240
+ # We need a temp directory (a log directory) for this project. The method
241
+ # here tries to ensure that.
242
+ # ========================================================================= #
243
+ def try_to_create_a_temporary_log_directory_and_cd_into_it_or_the_temp_directory
244
+ _ = '/tmp/' # This will be our tmp directory, as primary default.
245
+ tmpdir = Dir.tmpdir
246
+ if tmpdir and File.directory? tmpdir
247
+ _ = tmpdir
248
+ end
249
+ unless is_on_roebe? and return_pwd.include?('/home/x/')
250
+ if File.directory? _
251
+ Dir.chdir(_)
252
+ FileUtils.mkdir_p('ftp_paradise/') unless File.directory? 'ftp_paradise/'
253
+ Dir.chdir('ftp_paradise/')
254
+ end
255
+ end
256
+ end
257
+
258
+ # ========================================================================= #
259
+ # === verbose_truth
260
+ # ========================================================================= #
261
+ def verbose_truth(i = '')
262
+ VerboseTruth[i]
263
+ end
264
+
265
+ # ========================================================================= #
266
+ # === esystem
267
+ # ========================================================================= #
268
+ def esystem(i)
269
+ e i
270
+ system i
271
+ end
272
+
273
+ # ========================================================================= #
274
+ # === return_pwd
275
+ # ========================================================================= #
276
+ def return_pwd
277
+ ::FtpParadise.return_pwd.to_s
278
+ end; alias return_current_directory return_pwd # === return_current_directory
279
+
280
+ # ========================================================================= #
281
+ # === on_roebe?
282
+ # ========================================================================= #
283
+ def on_roebe?
284
+ ENV['IS_ROEBE'].to_s == '1'
285
+ end; alias are_we_on_roebe? on_roebe? # === are_we_on_roebe?
286
+ alias is_on_roebe? on_roebe? # === is_on_roebe?
287
+
288
+ # =========================================================================== #
289
+ # === cliner
290
+ # =========================================================================== #
291
+ def cliner(
292
+ use_this_colour = nil
293
+ )
294
+ if Object.const_defined? :Cliner
295
+ if use_this_colour
296
+ use_this_colour = use_this_colour.to_s.to_sym
297
+ Cliner.cliner(use_colour: use_this_colour)
298
+ else
299
+ Cliner.cliner
300
+ end
301
+ if block_given?
302
+ yield
303
+ if use_this_colour
304
+ Cliner.cliner(use_colour: use_this_colour)
305
+ else
306
+ Cliner.cliner
307
+ end
308
+ end
309
+ end
310
+ end
311
+
312
+ # =========================================================================== #
313
+ # === cliner_seagreen
314
+ # =========================================================================== #
315
+ def cliner_seagreen
316
+ cliner(:seagreen)
317
+ end
318
+
319
+ # =========================================================================== #
320
+ # === cliner_violet
321
+ # =========================================================================== #
322
+ def cliner_violet
323
+ cliner(:violet)
324
+ end
325
+
326
+ # ========================================================================= #
327
+ # === swarn
328
+ # ========================================================================= #
329
+ def swarn(i = '')
330
+ return ::FtpParadise.swarn(i) if use_colours?
331
+ return i
332
+ end
333
+
334
+ # ========================================================================= #
335
+ # === sfile
336
+ # ========================================================================= #
337
+ def sfile(
338
+ i = '',
339
+ use_colours = use_colours?
340
+ )
341
+ return ::FtpParadise.sfile(i, use_colours)
342
+ end
343
+
344
+ # ========================================================================= #
345
+ # === sfancy
346
+ # ========================================================================= #
347
+ def sfancy(
348
+ i = '',
349
+ use_colours = use_colours?
350
+ )
351
+ return ::FtpParadise.sfancy(i, use_colours)
352
+ end
353
+
354
+ # ========================================================================= #
355
+ # === use_colours?
356
+ # ========================================================================= #
357
+ def use_colours?
358
+ return @internal_hash[:use_colours]
359
+ end
360
+
361
+ # ========================================================================= #
362
+ # === datafile?
363
+ # ========================================================================= #
364
+ def datafile?
365
+ '/home/x/data/personal/yaml/ftp/roebe_ftp.yml'
366
+ end
367
+
368
+ # ========================================================================= #
369
+ # === be_verbose=
370
+ # ========================================================================= #
371
+ def be_verbose=(i)
372
+ @be_verbose = i
373
+ end
374
+
375
+ end; end
@@ -21,43 +21,19 @@ module FtpParadise
21
21
  # ========================================================================= #
22
22
  # === FtpParadise.sdir
23
23
  # ========================================================================= #
24
- def self.sdir(i)
24
+ def self.sdir(i = '')
25
25
  return Colours.sdir(i) if use_colours?
26
- i
26
+ return i
27
27
  end
28
28
 
29
29
  # ========================================================================= #
30
30
  # === FtpParadise.swarn
31
31
  # ========================================================================= #
32
- def self.swarn(i)
32
+ def self.swarn(i = '')
33
33
  return Colours.swarn(i) if use_colours?
34
34
  return i
35
35
  end
36
36
 
37
- # ========================================================================= #
38
- # === FtpParadise.sfile
39
- # ========================================================================= #
40
- def self.sfile(i)
41
- return Colours.sfile(i) if use_colours?
42
- return i
43
- end
44
-
45
- # ========================================================================= #
46
- # === FtpParadise.sfancy
47
- # ========================================================================= #
48
- def self.sfancy(i)
49
- return Colours.sfancy(i) if use_colours? # Else we won't modify this at all.
50
- return i
51
- end
52
-
53
- # ========================================================================= #
54
- # === FtpParadise.simp
55
- # ========================================================================= #
56
- def self.simp(i)
57
- return Colours.simp(i) if use_colours? # Else we won't modify this.
58
- return i
59
- end
60
-
61
37
  # ========================================================================= #
62
38
  # === sfancy
63
39
  # ========================================================================= #
@@ -134,6 +110,30 @@ module FtpParadise
134
110
  e 'Testing '+sfancy('sfancy')+' next.'
135
111
  end
136
112
 
113
+ # ========================================================================= #
114
+ # === FtpParadise.sfancy
115
+ # ========================================================================= #
116
+ def self.sfancy(i, use_colours = use_colours?)
117
+ return Colours.sfancy(i) if use_colours # Else we won't modify this at all.
118
+ return i
119
+ end
120
+
121
+ # ========================================================================= #
122
+ # === FtpParadise.simp
123
+ # ========================================================================= #
124
+ def self.simp(i, use_colours = use_colours?)
125
+ return Colours.simp(i) if use_colours # Else we won't modify this.
126
+ return i
127
+ end
128
+
129
+ # ========================================================================= #
130
+ # === FtpParadise.sfile
131
+ # ========================================================================= #
132
+ def self.sfile(i, use_colours = use_colours?)
133
+ return Colours.sfile(i,) if use_colours
134
+ return i
135
+ end
136
+
137
137
  end
138
138
 
139
139
  if __FILE__ == $PROGRAM_NAME
@@ -6,7 +6,12 @@
6
6
  # =========================================================================== #
7
7
  module FtpParadise
8
8
 
9
- require 'ftp_paradise/configuration/configuration.rb'
9
+ begin
10
+ require 'ftp_paradise/configuration/configuration.rb'
11
+ rescue LoadError => error
12
+ puts 'ftp_paradise/configuration/configuration.rb is not available.'
13
+ pp error
14
+ end
10
15
 
11
16
  begin
12
17
  require 'colours'
@@ -9,8 +9,10 @@ module FtpParadise
9
9
  require 'ftp_paradise/project/project.rb'
10
10
 
11
11
  begin # Try to make use of Roebe::Configuration next.
12
- require 'roebe/configuration/configuration.rb'
13
- rescue LoadError; end
12
+ require 'roebe/configuration/class/configuration.rb'
13
+ rescue LoadError => error
14
+ pp error
15
+ end
14
16
 
15
17
  # ========================================================================= #
16
18
  # === @configuration
@@ -28,7 +30,8 @@ module FtpParadise
28
30
  # ===================================================================== #
29
31
  # Load up all .yml files from the path to the yaml directory:
30
32
  # ===================================================================== #
31
- @configuration = ::Roebe::Configuration::Configuration.new(FtpParadise.yaml_directory?)
33
+ use_this_directory = FtpParadise.yaml_directory?
34
+ @configuration = ::Roebe::Configuration.new(use_this_directory)
32
35
  end
33
36
  end; self.instance_eval { alias initialize_configuration initialize } # === FtpParadise.initialize_configuration
34
37
 
@@ -44,6 +47,6 @@ module FtpParadise
44
47
  # ========================================================================= #
45
48
  def self.config?
46
49
  @configuration
47
- end; self.class { alias configuration? config? } # === FtpParadise.configuration?
50
+ end; self.instance_eval { alias configuration? config? } # === FtpParadise.configuration?
48
51
 
49
52
  end
File without changes