1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | import theTranslator from './Translator.js'; |
24 | import { LAT_LNG, ZERO, ONE, TWO, THREE, HEXADECIMAL, DISTANCE } from '../../main/Constants.js'; |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | class Utilities { |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | constructor ( ) { |
40 | Object.freeze ( this ); |
41 | } |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | get UUID ( ) { |
49 | const UUID_LENGHT = 16; |
50 | const UUID_STRLENGHT = 2; |
51 | const UUID_SEPARATORS = [ '', '', '', '-', '', '-', '', '-', '', '-', '', '', '', '', '', '' ]; |
52 | const randomValues = new Uint8Array ( UUID_LENGHT ); |
53 | |
54 | window.crypto.getRandomValues ( randomValues ); |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | randomValues [ 6 ] = ( randomValues [ 6 ] & 0x0f ) | 0x40; |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | randomValues [ 8 ] = ( randomValues [ 8 ] & 0x3f ) | 0x80; |
71 | |
72 | |
73 | |
74 | let UUID = ''; |
75 | for ( let counter = ZERO; counter < UUID_LENGHT; counter ++ ) { |
76 | UUID += randomValues [ counter ].toString ( HEXADECIMAL ).padStart ( UUID_STRLENGHT, '0' ) + |
77 | UUID_SEPARATORS [ counter ]; |
78 | } |
79 | |
80 | return UUID; |
81 | } |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | storageAvailable ( type ) { |
89 | try { |
90 | const storage = window [ type ]; |
91 | const testString = '__storage_test__'; |
92 | storage.setItem ( testString, testString ); |
93 | storage.removeItem ( testString ); |
94 | return true; |
95 | } |
96 | catch { |
97 | return false; |
98 | } |
99 | } |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | |
106 | |
107 | openFile ( eventListener, acceptFileType ) { |
108 | const openFileInput = document.createElement ( 'input' ); |
109 | openFileInput.type = 'file'; |
110 | if ( acceptFileType ) { |
111 | openFileInput.accept = acceptFileType; |
112 | } |
113 | openFileInput.addEventListener ( |
114 | 'change', |
115 | eventListener, |
116 | false |
117 | ); |
118 | openFileInput.click ( ); |
119 | } |
120 | |
121 | |
122 | |
123 | |
124 | |
125 | |
126 | |
127 | |
128 | saveFile ( fileName, fileContent, fileMimeType ) { |
129 | try { |
130 | const objURL = |
131 | fileMimeType |
132 | ? |
133 | window.URL.createObjectURL ( new File ( [ fileContent ], fileName, { type : fileMimeType } ) ) |
134 | : |
135 | URL.createObjectURL ( fileContent ); |
136 | const element = document.createElement ( 'a' ); |
137 | element.setAttribute ( 'href', objURL ); |
138 | element.setAttribute ( 'download', fileName ); |
139 | element.click ( ); |
140 | window.URL.revokeObjectURL ( objURL ); |
141 | } |
142 | catch ( err ) { |
143 | if ( err instanceof Error ) { |
144 | console.error ( err ); |
145 | } |
146 | } |
147 | } |
148 | |
149 | |
150 | |
151 | |
152 | |
153 | |
154 | formatTime ( time ) { |
155 | const SECOND_IN_DAY = 86400; |
156 | const SECOND_IN_HOUR = 3600; |
157 | const SECOND_IN_MINUT = 60; |
158 | const iTtime = Math.floor ( time ); |
159 | if ( ZERO === iTtime ) { |
160 | return ''; |
161 | } |
162 | const days = Math.floor ( iTtime / SECOND_IN_DAY ); |
163 | const hours = Math.floor ( iTtime % SECOND_IN_DAY / SECOND_IN_HOUR ); |
164 | const minutes = Math.floor ( iTtime % SECOND_IN_HOUR / SECOND_IN_MINUT ); |
165 | const seconds = Math.floor ( iTtime % SECOND_IN_MINUT ); |
166 | if ( ZERO < days ) { |
167 | return days + |
168 | '\u00A0' |
169 | + theTranslator.getText ( 'Utilities - Day' ) + |
170 | '\u00A0' + |
171 | hours + |
172 | '\u00A0' + |
173 | theTranslator.getText ( 'Utilities - Hour' ); |
174 | } |
175 | else if ( ZERO < hours ) { |
176 | return hours + |
177 | '\u00A0' |
178 | + theTranslator.getText ( 'Utilities - Hour' ) |
179 | + '\u00A0' + |
180 | minutes + |
181 | '\u00A0' |
182 | + theTranslator.getText ( 'Utilities - Minute' ); |
183 | } |
184 | else if ( ZERO < minutes ) { |
185 | return minutes + |
186 | '\u00A0' + |
187 | theTranslator.getText ( 'Utilities - Minute' ); |
188 | } |
189 | return seconds + '\u00A0' + theTranslator.getText ( 'Utilities - Second' ); |
190 | } |
191 | |
192 | |
193 | |
194 | |
195 | |
196 | |
197 | formatDistance ( distance ) { |
198 | const DISTANCE_ROUND = 10; |
199 | |
200 | const iDistance = Math.floor ( distance ); |
201 | if ( ZERO >= iDistance ) { |
202 | return '0\u00A0km'; |
203 | } |
204 | return Math.floor ( iDistance / DISTANCE.metersInKm ) + |
205 | ',' + |
206 | Math.floor ( ( iDistance % DISTANCE.metersInKm ) / DISTANCE_ROUND ).toFixed ( ZERO ) |
207 | .padStart ( TWO, '0' ) |
208 | .padEnd ( THREE, '0' ) + |
209 | '\u00A0km'; |
210 | } |
211 | |
212 | |
213 | |
214 | |
215 | |
216 | |
217 | numberToDMS ( number ) { |
218 | const MINUTES_IN_DEGREE = 60.0; |
219 | const SECONDS_IN_DEGREE = 3600.0; |
220 | const SECONDS_DECIMALS = 100.0; |
221 | let remind = number; |
222 | let degrees = Math.floor ( number ); |
223 | remind -= degrees; |
224 | let minutes = Math.floor ( remind * MINUTES_IN_DEGREE ); |
225 | remind -= minutes / MINUTES_IN_DEGREE; |
226 | remind *= SECONDS_IN_DEGREE; |
227 | let seconds = Math.floor ( remind ); |
228 | remind -= seconds; |
229 | remind = Math.floor ( remind * SECONDS_DECIMALS ); |
230 | return degrees.toString ( ) + '° ' + minutes.toString ( ) + '\' ' + seconds + '" ' + remind; |
231 | } |
232 | |
233 | |
234 | |
235 | |
236 | |
237 | |
238 | formatLatDMS ( lat ) { |
239 | return ( |
240 | lat > ZERO |
241 | ? |
242 | this.numberToDMS ( lat ) + '\u00A0N' |
243 | : |
244 | this.numberToDMS ( -lat ) + '\u00A0S' |
245 | ); |
246 | } |
247 | |
248 | |
249 | |
250 | |
251 | |
252 | |
253 | formatLngDMS ( lng ) { |
254 | return ( |
255 | lng > ZERO |
256 | ? |
257 | this.numberToDMS ( lng ) + '\u00A0E' |
258 | : |
259 | this.numberToDMS ( -lng ) + '\u00A0W' |
260 | ); |
261 | } |
262 | |
263 | |
264 | |
265 | |
266 | |
267 | |
268 | formatLatLngDMS ( latLng ) { |
269 | if ( ZERO === latLng [ ZERO ] && ZERO === latLng [ ONE ] ) { |
270 | return ''; |
271 | } |
272 | return this.formatLatDMS ( latLng [ ZERO ] ) + '\u00A0-\u00A0' + this.formatLngDMS ( latLng [ ONE ] ); |
273 | } |
274 | |
275 | |
276 | |
277 | |
278 | |
279 | |
280 | formatLat ( lat ) { |
281 | return ( |
282 | lat > ZERO |
283 | ? |
284 | lat.toFixed ( LAT_LNG.fixed ) + '\u00A0N' |
285 | : |
286 | ( -lat ).toFixed ( LAT_LNG.fixed ) + '\u00A0S' |
287 | ); |
288 | } |
289 | |
290 | |
291 | |
292 | |
293 | |
294 | |
295 | formatLng ( lng ) { |
296 | return ( |
297 | lng > ZERO |
298 | ? |
299 | lng.toFixed ( LAT_LNG.fixed ) + '\u00A0E' |
300 | : |
301 | ( -lng ).toFixed ( LAT_LNG.fixed ) + '\u00A0W' |
302 | ); |
303 | } |
304 | |
305 | |
306 | |
307 | |
308 | |
309 | |
310 | formatLatLng ( latLng ) { |
311 | if ( ZERO === latLng [ ZERO ] && ZERO === latLng [ ONE ] ) { |
312 | return ''; |
313 | } |
314 | return this.formatLat ( latLng [ ZERO ] ) + '\u00A0-\u00A0' + this.formatLng ( latLng [ ONE ] ); |
315 | } |
316 | } |
317 | |
318 | |
319 | |
320 | |
321 | |
322 | |
323 | |
324 | |
325 | const theUtilities = new Utilities ( ); |
326 | |
327 | export default theUtilities; |
328 | |
329 | |
330 | |