remote-calibrator 0.3.0-rc.3 → 0.5.0-beta.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. package/CHANGELOG.md +35 -3
  2. package/README.md +34 -49
  3. package/homepage/example.css +4 -3
  4. package/homepage/example.js +42 -22
  5. package/homepage/index.html +19 -4
  6. package/i18n/fetch-languages-sheets.js +11 -1
  7. package/lib/RemoteCalibrator.min.js +1 -1
  8. package/lib/RemoteCalibrator.min.js.LICENSE.txt +19 -2
  9. package/lib/RemoteCalibrator.min.js.map +1 -1
  10. package/netlify.toml +1 -1
  11. package/package.json +25 -24
  12. package/src/WebGazer4RC/package-lock.json +198 -143
  13. package/src/WebGazer4RC/package.json +2 -2
  14. package/src/WebGazer4RC/src/index.mjs +161 -52
  15. package/src/WebGazer4RC/test/webgazer_test.js +1 -1
  16. package/src/check/checkScreenSize.js +84 -0
  17. package/src/components/buttons.js +21 -4
  18. package/src/components/input.js +82 -0
  19. package/src/components/keyBinder.js +5 -6
  20. package/src/components/language.js +5 -0
  21. package/src/components/mediaPermission.js +21 -0
  22. package/src/components/onCanvas.js +2 -2
  23. package/src/components/sound.js +30 -2
  24. package/src/components/swalOptions.js +6 -3
  25. package/src/components/utils.js +27 -1
  26. package/src/components/video.js +9 -6
  27. package/src/const.js +15 -0
  28. package/src/core.js +103 -48
  29. package/src/css/buttons.scss +34 -7
  30. package/src/css/components.scss +57 -0
  31. package/src/css/distance.scss +71 -1
  32. package/src/css/gaze.css +9 -5
  33. package/src/css/main.css +22 -6
  34. package/src/css/panel.scss +33 -3
  35. package/src/css/screenSize.css +6 -5
  36. package/src/css/swal.css +1 -1
  37. package/src/css/video.scss +19 -0
  38. package/src/distance/distance.js +194 -41
  39. package/src/distance/distanceCheck.js +241 -0
  40. package/src/distance/distanceTrack.js +165 -68
  41. package/src/{interpupillaryDistance.js → distance/interPupillaryDistance.js} +27 -19
  42. package/src/gaze/gaze.js +4 -7
  43. package/src/gaze/gazeAccuracy.js +9 -4
  44. package/src/gaze/gazeCalibration.js +14 -4
  45. package/src/gaze/gazeTracker.js +40 -9
  46. package/src/i18n.js +1 -1
  47. package/src/index.js +7 -2
  48. package/src/media/two-side-arrow.svg +1 -0
  49. package/src/media/two-sided-horizontal.svg +1 -0
  50. package/src/media/two-sided-vertical.svg +3 -0
  51. package/src/panel.js +130 -65
  52. package/src/screenSize.js +38 -5
  53. package/webpack.config.js +7 -4
  54. package/media/measureDistance.png +0 -0
  55. package/media/panel.png +0 -0
  56. package/media/screenSize.png +0 -0
  57. package/media/trackGaze.png +0 -0
  58. package/src/displaySize.js +0 -28
@@ -7,6 +7,34 @@ const feedbackSynth = new Synth({
7
7
  envelope: { attack: 0.001, decay: 0.001, sustain: 1, release: 0.001 },
8
8
  }).connect(new Volume(-17).toDestination())
9
9
 
10
- export const soundFeedback = () => {
11
- feedbackSynth.triggerAttackRelease(2000, 0.05)
10
+ const softFeedbackSynth = new Synth({
11
+ oscillator: {
12
+ type: 'sine',
13
+ },
14
+ }).connect(new Volume(-5).toDestination())
15
+
16
+ export const soundFeedback = (style = 0) => {
17
+ switch (style) {
18
+ case 0:
19
+ feedbackSynth.triggerAttackRelease(2000, 0.05)
20
+ return
21
+
22
+ case 1:
23
+ // Negative feedback
24
+ feedbackSynth.triggerAttackRelease(500, 0.5)
25
+ return
26
+
27
+ case 2:
28
+ // Purr
29
+ feedbackSynth.triggerAttackRelease(200, 0.6)
30
+ return
31
+
32
+ case 3:
33
+ softFeedbackSynth.triggerAttackRelease(200, 0.2)
34
+ return
35
+
36
+ default:
37
+ feedbackSynth.triggerAttackRelease(2000, 0.05)
38
+ return
39
+ }
12
40
  }
@@ -1,8 +1,8 @@
1
1
  import { phrases } from '../i18n'
2
2
 
3
- export const swalInfoOptions = RC => {
3
+ export const swalInfoOptions = (RC, { showIcon }) => {
4
4
  return {
5
- icon: 'info',
5
+ icon: showIcon ? 'info' : undefined,
6
6
  allowEscapeKey: false,
7
7
  allowEnterKey: false,
8
8
  allowOutsideClick: false,
@@ -10,6 +10,7 @@ export const swalInfoOptions = RC => {
10
10
  confirmButtonText: phrases.RC_ok[RC.L],
11
11
  showClass: {
12
12
  popup: 'animate__animated animate__fadeInUp',
13
+ icon: '',
13
14
  // backdrop: 'animate__animated animate__fadeIn',
14
15
  },
15
16
  hideClass: {
@@ -19,9 +20,11 @@ export const swalInfoOptions = RC => {
19
20
  iconColor: RC._CONST.COLOR.ORANGE,
20
21
  confirmButtonColor: '#aaa',
21
22
  customClass: {
23
+ popup: 'my__swal2__container',
22
24
  icon: 'my__swal2__icon',
23
25
  title: 'my__swal2__title',
24
- htmlContainer: 'my__swal2__html',
26
+ htmlContainer: 'my__swal2__html' + ` rc-lang-${RC.LD.toLowerCase()}`,
27
+ confirmButton: 'rc-button rc-go-button',
25
28
  },
26
29
  }
27
30
  }
@@ -68,6 +68,12 @@
68
68
  }
69
69
  })()
70
70
 
71
+ export function safeExecuteFunc(f, ...a) {
72
+ if (f && typeof f === 'function')
73
+ if (a.length) f(...a)
74
+ else f()
75
+ }
76
+
71
77
  // http://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep
72
78
  export function sleep(time) {
73
79
  return new Promise(resolve => setTimeout(resolve, time))
@@ -86,16 +92,33 @@ export function getFullscreen() {
86
92
  const element = document.documentElement
87
93
  if (element.requestFullscreen) {
88
94
  element.requestFullscreen()
95
+ return true
89
96
  } else if (element.mozRequestFullScreen) {
90
97
  element.mozRequestFullScreen()
98
+ return true
91
99
  } else if (element.webkitRequestFullscreen) {
92
100
  element.webkitRequestFullscreen()
101
+ return true
93
102
  } else if (element.msRequestFullscreen) {
94
103
  element.msRequestFullscreen()
104
+ return true
105
+ } else {
106
+ return false
95
107
  }
108
+ } else {
109
+ return false
96
110
  }
97
111
  }
98
112
 
113
+ export function isFullscreen() {
114
+ return (
115
+ Math.abs(window.innerHeight - screen.height) < 5 &&
116
+ Math.abs(window.innerWidth - screen.width) < 5 &&
117
+ window.screenX < 5 &&
118
+ window.screenY < 5
119
+ )
120
+ }
121
+
99
122
  /* -------------------------------------------------------------------------- */
100
123
 
101
124
  export function constructInstructions(
@@ -127,7 +150,7 @@ export function dist2d(aX, aY, bX, bY) {
127
150
  return Math.sqrt(Math.pow(aX - bX, 2) + Math.pow(aY - bY, 2))
128
151
  }
129
152
 
130
- // https://stackoverflow.com/a/12646864/11069914
153
+ // https://stackoverflow.com/a/12646864
131
154
  export function shuffle(array) {
132
155
  for (let i = array.length - 1; i > 0; i--) {
133
156
  const j = Math.floor(Math.random() * (i + 1))
@@ -148,6 +171,9 @@ export const median = arr => {
148
171
  return arr.length % 2 !== 0 ? num[mid] : (num[mid - 1] + num[mid]) / 2
149
172
  }
150
173
 
174
+ // https://stackoverflow.com/a/41452260
175
+ export const average = array => array.reduce((a, b) => a + b) / array.length
176
+
151
177
  /**
152
178
  *
153
179
  * BLUR ALL
@@ -1,4 +1,6 @@
1
- // Only one video for all functions
1
+ /* Only one video for all functions */
2
+
3
+ import { safeExecuteFunc } from './utils'
2
4
 
3
5
  export function addVideoElementsToBody() {
4
6
  let v = document.querySelector('video')
@@ -33,7 +35,7 @@ export function startVideo(videoElement, callback) {
33
35
  videoElement.play()
34
36
 
35
37
  // ! CALLBACK
36
- if (callback) callback(stream)
38
+ safeExecuteFunc(callback, stream)
37
39
  },
38
40
  err => console.error(err)
39
41
  )
@@ -82,17 +84,18 @@ export function checkWebgazerReady(RC, pipWidthPx, opacity, WG, callback) {
82
84
  // Set position
83
85
  setDefaultVideoPosition(RC, v)
84
86
 
85
- // Give callback after 2 sec
87
+ // Give callback after 0.5 sec
86
88
  setTimeout(() => {
89
+ RC.videoOpacity()
87
90
  if (RC.isMobile.value)
88
91
  v.style.transition = `right 0.5s, top 0.5s, width 0.5s, height 0.5s, border-radius 0.5s`
89
92
  else
90
93
  v.style.transition = `left 0.5s, bottom 0.5s, width 0.5s, height 0.5s, border-radius 0.5s`
91
- callback()
92
- }, 1000)
94
+ safeExecuteFunc(callback)
95
+ }, 700)
93
96
  clearInterval(c)
94
97
  }
95
- }, 200)
98
+ }, 50)
96
99
  }
97
100
 
98
101
  export function setDefaultVideoPosition(RC, v) {
package/src/const.js CHANGED
@@ -12,6 +12,8 @@ RemoteCalibrator.prototype._CONST = Object.freeze({
12
12
  MARGIN: 10,
13
13
  BORDER: 8,
14
14
  },
15
+ PPI_DONT_USE: 127.7,
16
+ PD_DONT_USE: 6.4,
15
17
  },
16
18
  S: {
17
19
  AUTO: 'AUTO',
@@ -24,5 +26,18 @@ RemoteCalibrator.prototype._CONST = Object.freeze({
24
26
  LIGHT_GREY: '#cccccc',
25
27
  ORANGE: '#ff9a00',
26
28
  DARK_RED: '#ac0d0d',
29
+ RED: '#ee0000',
30
+ },
31
+ LTR: 'LTR',
32
+ RTL: 'RTL',
33
+ VIEW_METHOD: {
34
+ B: 'BlindSpot',
35
+ F: 'FaceMesh',
36
+ },
37
+ IN_TO_CM: 2.54,
38
+ UNITS: {
39
+ CM: 'cm',
40
+ IN_D: 'inDecimal',
41
+ IN_F: 'inFractional',
27
42
  },
28
43
  })
package/src/core.js CHANGED
@@ -13,16 +13,27 @@ import {
13
13
  getFullscreen,
14
14
  blurAll,
15
15
  constructInstructions,
16
+ isFullscreen,
17
+ safeExecuteFunc,
16
18
  } from './components/utils'
17
19
  import { looseSetLanguage } from './components/language'
18
20
  import { phrases } from './i18n'
21
+ import isEqual from 'react-fast-compare'
19
22
 
20
23
  class RemoteCalibrator {
21
24
  constructor() {
22
25
  this._initialized = false
23
26
 
24
- this._hasPanel = false
25
- this._panelFinished = false
27
+ this._id = null
28
+
29
+ this._lang = null // A single string, e.g., 'en-US'
30
+ this._langData = []
31
+
32
+ this._panelStatus = {
33
+ hasPanel: false,
34
+ panelFinished: false,
35
+ panelResolveIntervals: [],
36
+ }
26
37
  this._panel = {
27
38
  panel: null,
28
39
  panelObserver: null,
@@ -33,10 +44,30 @@ class RemoteCalibrator {
33
44
  panelResolve: null,
34
45
  }
35
46
 
36
- this._id = null
47
+ // Calibration check
48
+ this._participantCheckEquipment = {
49
+ has: null,
50
+ equipment: null,
51
+ unit: null,
52
+ }
37
53
 
38
- this._lang = null // A single string, e.g., 'en-US'
39
- this._langData = []
54
+ // Are we calibrating for setting up gaze or distance tracking?
55
+ this._trackingSetupFinishedStatus = {
56
+ gaze: true,
57
+ distance: true,
58
+ }
59
+ this._distanceTrackNudging = {
60
+ distanceCorrecting: null, // setInterval
61
+ distanceCorrectEnabled: false, // Whether to correct or not, used for endNudger
62
+ distanceDesired: null,
63
+ distanceAllowedRatio: null,
64
+ }
65
+ this._tackingVideoFrameTimestamps = {
66
+ gaze: 0,
67
+ distance: 0,
68
+ }
69
+
70
+ // ! DATA
40
71
 
41
72
  this._environmentData = []
42
73
 
@@ -52,11 +83,20 @@ class RemoteCalibrator {
52
83
  // Status
53
84
  this._fullscreenData = []
54
85
 
86
+ // Check
87
+ this._equipmentData = []
88
+
89
+ ////
90
+
55
91
  this._background = {
56
92
  element: null,
57
93
  instructionElement: null,
58
94
  }
59
95
 
96
+ this._nudger = {
97
+ element: null,
98
+ }
99
+
60
100
  this._params = {
61
101
  backgroundColor: '#eee',
62
102
  videoOpacity: 0.8,
@@ -64,6 +104,11 @@ class RemoteCalibrator {
64
104
  }
65
105
 
66
106
  this.deviceDetector = new DeviceDetector()
107
+
108
+ window.console.log(
109
+ `%c\nEasyEyes Remote Calibrator ${this.version.value}\n`,
110
+ `color: ${this._CONST.COLOR.ORANGE}`
111
+ )
67
112
  }
68
113
 
69
114
  /* --------------------------------- GETTERS -------------------------------- */
@@ -76,6 +121,10 @@ class RemoteCalibrator {
76
121
  return this._background.instructionElement
77
122
  }
78
123
 
124
+ get nudger() {
125
+ return this._nudger.element
126
+ }
127
+
79
128
  // PARAMS
80
129
 
81
130
  get params() {
@@ -127,6 +176,10 @@ class RemoteCalibrator {
127
176
  return this._lang
128
177
  }
129
178
 
179
+ get LD() {
180
+ return this.languageDirection.value
181
+ }
182
+
130
183
  get language() {
131
184
  return this._helper_get(this._langData, 'language')
132
185
  }
@@ -150,40 +203,36 @@ class RemoteCalibrator {
150
203
  // Status
151
204
 
152
205
  get isFullscreen() {
153
- return {
154
- value:
155
- Math.abs(window.innerHeight - screen.height) < 5 &&
156
- Math.abs(window.innerWidth - screen.width) < 5 &&
157
- window.screenX < 5 &&
158
- window.screenY < 5,
159
- timestamp: new Date(),
160
- }
206
+ if (
207
+ !this.fullscreenData.length ||
208
+ !isEqual(isFullscreen(), this._helper_get(this._fullscreenData).value)
209
+ )
210
+ this.newFullscreenData = {
211
+ value: isFullscreen(),
212
+ timestamp: new Date(),
213
+ }
214
+ return this._helper_get(this._fullscreenData)
161
215
  }
162
216
 
163
217
  // Environment
164
218
 
165
219
  get bot() {
166
- if (!this._environmentData.length) this.environment()
167
220
  return this._helper_get(this._environmentData, 'bot')
168
221
  }
169
222
 
170
223
  get browser() {
171
- if (!this._environmentData.length) this.environment()
172
224
  return this._helper_get(this._environmentData, 'browser')
173
225
  }
174
226
 
175
227
  get browserVersion() {
176
- if (!this._environmentData.length) this.environment()
177
228
  return this._helper_get(this._environmentData, 'browserVersion')
178
229
  }
179
230
 
180
231
  get deviceType() {
181
- if (!this._environmentData.length) this.environment()
182
232
  return this._helper_get(this._environmentData, 'deviceType')
183
233
  }
184
234
 
185
235
  get isMobile() {
186
- if (!this._environmentData.length) this.environment()
187
236
  const d = this._helper_get(this._environmentData, 'deviceType')
188
237
  return {
189
238
  value: d.value !== 'desktop',
@@ -192,64 +241,60 @@ class RemoteCalibrator {
192
241
  }
193
242
 
194
243
  get model() {
195
- if (!this._environmentData.length) this.environment()
196
244
  return this._helper_get(this._environmentData, 'model')
197
245
  }
198
246
 
199
247
  get manufacturer() {
200
- if (!this._environmentData.length) this.environment()
201
248
  return this._helper_get(this._environmentData, 'manufacturer')
202
249
  }
203
250
 
204
251
  get engine() {
205
- if (!this._environmentData.length) this.environment()
206
252
  return this._helper_get(this._environmentData, 'engine')
207
253
  }
208
254
 
209
255
  get system() {
210
- if (!this._environmentData.length) this.environment()
211
256
  return this._helper_get(this._environmentData, 'system')
212
257
  }
213
258
 
214
259
  get systemFamily() {
215
- if (!this._environmentData.length) this.environment()
216
260
  return this._helper_get(this._environmentData, 'systemFamily')
217
261
  }
218
262
 
219
263
  get description() {
220
- if (!this._environmentData.length) this.environment()
221
264
  return this._helper_get(this._environmentData, 'description')
222
265
  }
223
266
 
224
267
  get fullDescription() {
225
- if (!this._environmentData.length) this.environment()
226
268
  return this._helper_get(this._environmentData, 'fullDescription')
227
269
  }
228
270
 
229
271
  get userLanguage() {
230
- if (!this._environmentData.length) this.environment()
231
272
  return this._helper_get(this._environmentData, 'userLanguage')
232
273
  }
233
274
 
275
+ get equipment() {
276
+ return this._helper_get(this._equipmentData)
277
+ }
278
+
234
279
  // Screen
235
280
 
236
281
  get displayWidthPx() {
237
- if (!this._displayData.length) this.displaySize()
282
+ this._displaySize()
238
283
  return this._helper_get(this._displayData, 'displayWidthPx')
239
284
  }
240
285
 
241
286
  get displayHeightPx() {
242
- if (!this._displayData.length) this.displaySize()
287
+ this._displaySize()
243
288
  return this._helper_get(this._displayData, 'displayHeightPx')
244
289
  }
245
290
 
246
291
  get windowWidthPx() {
247
- if (!this._displayData.length) this.displaySize()
292
+ this._displaySize()
248
293
  return this._helper_get(this._displayData, 'windowWidthPx')
249
294
  }
250
295
 
251
296
  get windowHeightPx() {
252
- if (!this._displayData.length) this.displaySize()
297
+ this._displaySize()
253
298
  return this._helper_get(this._displayData, 'windowHeightPx')
254
299
  }
255
300
 
@@ -327,7 +372,7 @@ class RemoteCalibrator {
327
372
  return this._gazePositionData
328
373
  }
329
374
 
330
- get fullScreenData() {
375
+ get fullscreenData() {
331
376
  return this._fullscreenData
332
377
  }
333
378
 
@@ -410,6 +455,13 @@ class RemoteCalibrator {
410
455
  set newLanguageData(data) {
411
456
  this._langData.push(data)
412
457
  }
458
+
459
+ /**
460
+ * @param {{ value: { has: boolean; unit: string; equipment: string; }; timestamp: Date; }} data
461
+ */
462
+ set newEquipmentData(data) {
463
+ this._equipmentData.push(data)
464
+ }
413
465
  }
414
466
 
415
467
  /**
@@ -436,7 +488,8 @@ RemoteCalibrator.prototype.init = function (options = {}, callback) {
436
488
  timestamp: new Date(),
437
489
  }
438
490
 
439
- this.environment()
491
+ this._environment()
492
+ this._displaySize()
440
493
 
441
494
  if (this._CONST.S.AUTO === options.language)
442
495
  // AUTO
@@ -444,7 +497,7 @@ RemoteCalibrator.prototype.init = function (options = {}, callback) {
444
497
  else this.newLanguageData = looseSetLanguage(options.language)
445
498
  this._lang = this.language.value
446
499
 
447
- if (callback && typeof callback === 'function') callback(this._id)
500
+ safeExecuteFunc(callback, this._id)
448
501
  }
449
502
  }
450
503
 
@@ -453,13 +506,20 @@ RemoteCalibrator.prototype.init = function (options = {}, callback) {
453
506
  * Get the environment data, e.g. browser type
454
507
  *
455
508
  */
456
- RemoteCalibrator.prototype.environment = function (callback) {
509
+ RemoteCalibrator.prototype._environment = function () {
457
510
  if (this.checkInitialized()) {
458
511
  blurAll()
459
512
 
460
513
  const device = this.deviceDetector.parse(platform.ua)
461
514
  const bot = device.bot
462
515
 
516
+ if (!device.device)
517
+ device.device = {
518
+ type: null,
519
+ model: null,
520
+ brand: null,
521
+ }
522
+
463
523
  const data = {
464
524
  value: {
465
525
  bot: bot
@@ -482,8 +542,6 @@ RemoteCalibrator.prototype.environment = function (callback) {
482
542
  }
483
543
 
484
544
  this.newEnvironmentData = data
485
-
486
- if (callback) callback(data)
487
545
  }
488
546
  }
489
547
 
@@ -503,25 +561,20 @@ RemoteCalibrator.prototype.checkInitialized = function () {
503
561
  * @param {Boolean} f Get fullscreen or not from options
504
562
  */
505
563
  RemoteCalibrator.prototype.getFullscreen = function (f = true) {
506
- if (
507
- window.fullScreen ||
508
- (window.innerWidth === screen.width && window.innerHeight === screen.height)
509
- ) {
564
+ if (isFullscreen()) {
510
565
  return true
511
566
  }
512
567
 
513
- if (f && !debug) getFullscreen()
568
+ this.newFullscreenData = {
569
+ value: f && !debug ? getFullscreen() : false,
570
+ timestamp: new Date(),
571
+ }
514
572
 
515
573
  // Minimize address bar on mobile devices
516
574
  // ! Experimental
517
575
  if (this.isMobile.value) window.scrollBy(0, 1)
518
576
 
519
- this.newFullscreenData = {
520
- value: f && !debug,
521
- timestamp: new Date(),
522
- }
523
-
524
- return f && !debug
577
+ return this.isFullscreen
525
578
  }
526
579
 
527
580
  /**
@@ -548,6 +601,7 @@ RemoteCalibrator.prototype._addBackground = function (inner) {
548
601
  if (!b) {
549
602
  b = document.createElement('div')
550
603
  b.id = 'calibration-background'
604
+ b.className = 'calibration-background' + ` rc-lang-${this.LD.toLowerCase()}`
551
605
 
552
606
  document.body.classList.add('lock-view')
553
607
  document.body.appendChild(b)
@@ -556,8 +610,9 @@ RemoteCalibrator.prototype._addBackground = function (inner) {
556
610
  }
557
611
 
558
612
  if (inner) b.innerHTML = inner
559
-
560
613
  this._background.element = b
614
+
615
+ return this.background
561
616
  }
562
617
 
563
618
  /**
@@ -1,29 +1,56 @@
1
1
  .rc-buttons {
2
+ z-index: 10;
3
+ }
4
+
5
+ .rc-absolute-buttons {
2
6
  position: fixed;
7
+ text-align: right;
3
8
  bottom: 1.25rem;
4
9
  right: 1.25rem;
5
- z-index: 900000;
6
10
  }
7
11
 
8
12
  .rc-button {
9
- text-align: center;
13
+ text-align: center !important;
10
14
  border: none !important;
11
- background: #ffffffee;
12
15
  line-height: 150% !important;
13
16
  font-size: 1rem !important;
14
17
  font-weight: 700 !important;
15
- color: #333;
16
18
  padding: 1rem 1.5rem !important;
17
19
  margin: 0.25rem !important;
18
20
  border-radius: 7px !important;
19
21
  cursor: pointer;
22
+ }
23
+
24
+ .rc-go-button {
25
+ background: #ff9a00aa !important;
26
+ color: #fff !important;
27
+
28
+ &:hover {
29
+ background: #ff9a00 !important;
30
+ }
31
+
32
+ &:active {
33
+ background: #d68200 !important;
34
+ }
35
+ }
36
+
37
+ .rc-cancel-button,
38
+ .rc-custom-button {
39
+ background: #ffffffee !important;
40
+ color: #333 !important;
20
41
 
21
42
  &:hover {
22
- background: #ddd;
43
+ background: #ddd !important;
23
44
  }
24
45
 
25
46
  &:active {
26
- background: #aaa;
27
- color: #000;
47
+ background: #aaa !important;
48
+ color: #000 !important;
28
49
  }
29
50
  }
51
+
52
+ .rc-button:disabled {
53
+ background: #ddd !important;
54
+ color: #999 !important;
55
+ cursor: default !important;
56
+ }
@@ -0,0 +1,57 @@
1
+ .my__swal2__container .swal2-select {
2
+ font-family: inherit !important;
3
+ border-radius: 5px !important;
4
+ border: 2px solid #aaa !important;
5
+ outline: none !important;
6
+ }
7
+
8
+ /* -------------------------------------------------------------------------- */
9
+ /* Measure Input */
10
+ /* -------------------------------------------------------------------------- */
11
+
12
+ .rc-form {
13
+ font-size: 2rem;
14
+ font-family: inherit;
15
+
16
+ .rc-form-inputs {
17
+ display: flex;
18
+ justify-content: space-between !important;
19
+ margin: 1rem 0;
20
+
21
+ .rc-form-input,
22
+ span {
23
+ flex-grow: 1;
24
+ padding: 0.5rem;
25
+ font-family: inherit;
26
+ font-size: inherit;
27
+ }
28
+
29
+ span {
30
+ font-weight: 700;
31
+ }
32
+ }
33
+
34
+ .rc-form-input {
35
+ border: 2px solid #aaa;
36
+ outline: none;
37
+ border-radius: 5px;
38
+ width: min(100%, 10rem);
39
+
40
+ &.rc-input-error {
41
+ border-color: #ac0d0d !important;
42
+ color: #ac0d0d !important;
43
+ }
44
+ }
45
+ }
46
+
47
+ .arrow-two-sided-svg {
48
+ position: fixed;
49
+ width: 100%;
50
+ bottom: 10%;
51
+ left: 0;
52
+ right: 0;
53
+
54
+ .arrow-two-sided {
55
+ fill: #ff9a00;
56
+ }
57
+ }