@hapticjs/core 0.2.0 → 0.2.1

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.
package/dist/index.cjs CHANGED
@@ -34,29 +34,16 @@ var NoopAdapter = class {
34
34
  }
35
35
  };
36
36
 
37
- // src/utils/scheduling.ts
38
- function delay(ms) {
39
- return new Promise((resolve) => setTimeout(resolve, ms));
40
- }
41
- function clamp(value, min, max) {
42
- return Math.min(Math.max(value, min), max);
43
- }
44
- function normalizeIntensity(intensity) {
45
- return clamp(intensity, 0, 1);
46
- }
47
-
48
37
  // src/adapters/web-vibration.adapter.ts
49
38
  var WebVibrationAdapter = class {
50
39
  constructor() {
51
40
  this.name = "web-vibration";
52
- this._cancelled = false;
53
41
  this.supported = typeof navigator !== "undefined" && "vibrate" in navigator;
54
42
  }
55
43
  capabilities() {
56
44
  return {
57
45
  maxIntensityLevels: 1,
58
- // on/off only
59
- minDuration: 10,
46
+ minDuration: 20,
60
47
  maxDuration: 1e4,
61
48
  supportsPattern: true,
62
49
  supportsIntensity: false,
@@ -65,36 +52,39 @@ var WebVibrationAdapter = class {
65
52
  }
66
53
  async pulse(_intensity, duration) {
67
54
  if (!this.supported) return;
68
- navigator.vibrate(duration);
55
+ navigator.vibrate(Math.max(duration, 20));
69
56
  }
70
57
  async playSequence(steps) {
71
58
  if (!this.supported || steps.length === 0) return;
72
- this._cancelled = false;
73
- const pattern = this._toVibrationPattern(steps);
74
- if (this._canUseNativePattern(steps)) {
75
- navigator.vibrate(pattern);
76
- return;
77
- }
59
+ const pattern = [];
60
+ let lastType = null;
78
61
  for (const step of steps) {
79
- if (this._cancelled) break;
80
- if (step.type === "vibrate") {
81
- if (step.intensity > 0.1) {
82
- if (step.intensity < 0.5) {
83
- await this._pwmVibrate(step.duration, step.intensity);
84
- } else {
85
- navigator.vibrate(step.duration);
86
- await delay(step.duration);
87
- }
62
+ if (step.type === "vibrate" && step.intensity > 0.05) {
63
+ const dur = Math.max(step.duration, 20);
64
+ if (lastType === "vibrate") {
65
+ pattern[pattern.length - 1] += dur;
88
66
  } else {
89
- await delay(step.duration);
67
+ pattern.push(dur);
90
68
  }
69
+ lastType = "vibrate";
91
70
  } else {
92
- await delay(step.duration);
71
+ const dur = Math.max(step.duration, 10);
72
+ if (lastType === "pause") {
73
+ pattern[pattern.length - 1] += dur;
74
+ } else {
75
+ pattern.push(dur);
76
+ }
77
+ lastType = "pause";
78
+ }
79
+ }
80
+ if (pattern.length > 0) {
81
+ if (steps[0]?.type === "pause" || steps[0]?.type === "vibrate" && steps[0]?.intensity <= 0.05) {
82
+ pattern.unshift(0);
93
83
  }
84
+ navigator.vibrate(pattern);
94
85
  }
95
86
  }
96
87
  cancel() {
97
- this._cancelled = true;
98
88
  if (this.supported) {
99
89
  navigator.vibrate(0);
100
90
  }
@@ -102,37 +92,19 @@ var WebVibrationAdapter = class {
102
92
  dispose() {
103
93
  this.cancel();
104
94
  }
105
- /** Convert steps to Vibration API pattern array */
106
- _toVibrationPattern(steps) {
107
- const pattern = [];
108
- for (const step of steps) {
109
- pattern.push(step.duration);
110
- }
111
- return pattern;
112
- }
113
- /** Check if all steps can be played with native pattern (no intensity variation) */
114
- _canUseNativePattern(steps) {
115
- return steps.every(
116
- (s) => s.type === "pause" || s.type === "vibrate" && s.intensity >= 0.5
117
- );
118
- }
119
- /** Simulate lower intensity via pulse-width modulation */
120
- async _pwmVibrate(duration, intensity) {
121
- const cycleTime = 20;
122
- const onTime = Math.round(cycleTime * intensity);
123
- const offTime = cycleTime - onTime;
124
- const cycles = Math.floor(duration / cycleTime);
125
- const pattern = [];
126
- for (let i = 0; i < cycles; i++) {
127
- pattern.push(onTime, offTime);
128
- }
129
- if (pattern.length > 0) {
130
- navigator.vibrate(pattern);
131
- await delay(duration);
132
- }
133
- }
134
95
  };
135
96
 
97
+ // src/utils/scheduling.ts
98
+ function delay(ms) {
99
+ return new Promise((resolve) => setTimeout(resolve, ms));
100
+ }
101
+ function clamp(value, min, max) {
102
+ return Math.min(Math.max(value, min), max);
103
+ }
104
+ function normalizeIntensity(intensity) {
105
+ return clamp(intensity, 0, 1);
106
+ }
107
+
136
108
  // src/adapters/ios-audio.adapter.ts
137
109
  var IoSAudioAdapter = class {
138
110
  constructor() {
@@ -736,9 +708,9 @@ var HapticEngine = class _HapticEngine {
736
708
  /** Double tap */
737
709
  async doubleTap(intensity = 0.6) {
738
710
  await this._playSteps([
739
- { type: "vibrate", duration: 10, intensity },
711
+ { type: "vibrate", duration: 25, intensity },
740
712
  { type: "pause", duration: 80, intensity: 0 },
741
- { type: "vibrate", duration: 10, intensity }
713
+ { type: "vibrate", duration: 25, intensity }
742
714
  ]);
743
715
  }
744
716
  /** Long press feedback */
@@ -773,24 +745,24 @@ var HapticEngine = class _HapticEngine {
773
745
  }
774
746
  /** Selection change feedback */
775
747
  async selection() {
776
- await this._playSteps([{ type: "vibrate", duration: 8, intensity: 0.4 }]);
748
+ await this._playSteps([{ type: "vibrate", duration: 25, intensity: 0.5 }]);
777
749
  }
778
750
  /** Toggle feedback */
779
751
  async toggle(on) {
780
752
  if (on) {
781
- await this._playSteps([{ type: "vibrate", duration: 15, intensity: 0.6 }]);
753
+ await this._playSteps([{ type: "vibrate", duration: 30, intensity: 0.6 }]);
782
754
  } else {
783
- await this._playSteps([{ type: "vibrate", duration: 10, intensity: 0.3 }]);
755
+ await this._playSteps([{ type: "vibrate", duration: 25, intensity: 0.4 }]);
784
756
  }
785
757
  }
786
758
  /** Impact with style (matches iOS UIImpactFeedbackGenerator) */
787
759
  async impact(style = "medium") {
788
760
  const presets2 = {
789
- light: [{ type: "vibrate", duration: 10, intensity: 0.3 }],
790
- medium: [{ type: "vibrate", duration: 15, intensity: 0.6 }],
791
- heavy: [{ type: "vibrate", duration: 25, intensity: 1 }],
792
- rigid: [{ type: "vibrate", duration: 8, intensity: 0.9 }],
793
- soft: [{ type: "vibrate", duration: 30, intensity: 0.4 }]
761
+ light: [{ type: "vibrate", duration: 25, intensity: 0.4 }],
762
+ medium: [{ type: "vibrate", duration: 35, intensity: 0.7 }],
763
+ heavy: [{ type: "vibrate", duration: 50, intensity: 1 }],
764
+ rigid: [{ type: "vibrate", duration: 30, intensity: 0.9 }],
765
+ soft: [{ type: "vibrate", duration: 35, intensity: 0.5 }]
794
766
  };
795
767
  await this._playSteps(presets2[style]);
796
768
  }
@@ -1031,15 +1003,15 @@ var ui = {
1031
1003
  /** Light button tap */
1032
1004
  tap: {
1033
1005
  name: "ui.tap",
1034
- steps: [{ type: "vibrate", duration: 10, intensity: 0.6 }]
1006
+ steps: [{ type: "vibrate", duration: 30, intensity: 0.6 }]
1035
1007
  },
1036
1008
  /** Double tap */
1037
1009
  doubleTap: {
1038
1010
  name: "ui.doubleTap",
1039
1011
  steps: [
1040
- { type: "vibrate", duration: 10, intensity: 0.6 },
1012
+ { type: "vibrate", duration: 25, intensity: 0.6 },
1041
1013
  { type: "pause", duration: 80, intensity: 0 },
1042
- { type: "vibrate", duration: 10, intensity: 0.6 }
1014
+ { type: "vibrate", duration: 25, intensity: 0.6 }
1043
1015
  ]
1044
1016
  },
1045
1017
  /** Long press acknowledgment */
@@ -1050,58 +1022,58 @@ var ui = {
1050
1022
  /** Toggle switch on */
1051
1023
  toggleOn: {
1052
1024
  name: "ui.toggleOn",
1053
- steps: [{ type: "vibrate", duration: 15, intensity: 0.6 }]
1025
+ steps: [{ type: "vibrate", duration: 30, intensity: 0.6 }]
1054
1026
  },
1055
1027
  /** Toggle switch off */
1056
1028
  toggleOff: {
1057
1029
  name: "ui.toggleOff",
1058
- steps: [{ type: "vibrate", duration: 10, intensity: 0.3 }]
1030
+ steps: [{ type: "vibrate", duration: 25, intensity: 0.4 }]
1059
1031
  },
1060
1032
  /** Slider snap to value */
1061
1033
  sliderSnap: {
1062
1034
  name: "ui.sliderSnap",
1063
- steps: [{ type: "vibrate", duration: 5, intensity: 0.4 }]
1035
+ steps: [{ type: "vibrate", duration: 25, intensity: 0.5 }]
1064
1036
  },
1065
1037
  /** Selection changed */
1066
1038
  selection: {
1067
1039
  name: "ui.selection",
1068
- steps: [{ type: "vibrate", duration: 8, intensity: 0.4 }]
1040
+ steps: [{ type: "vibrate", duration: 25, intensity: 0.5 }]
1069
1041
  },
1070
1042
  /** Pull to refresh threshold reached */
1071
1043
  pullToRefresh: {
1072
1044
  name: "ui.pullToRefresh",
1073
1045
  steps: [
1074
- { type: "vibrate", duration: 20, intensity: 0.5 },
1046
+ { type: "vibrate", duration: 30, intensity: 0.5 },
1075
1047
  { type: "pause", duration: 40, intensity: 0 },
1076
- { type: "vibrate", duration: 30, intensity: 0.7 }
1048
+ { type: "vibrate", duration: 40, intensity: 0.7 }
1077
1049
  ]
1078
1050
  },
1079
1051
  /** Swipe action triggered */
1080
1052
  swipe: {
1081
1053
  name: "ui.swipe",
1082
1054
  steps: [
1083
- { type: "vibrate", duration: 12, intensity: 0.4 },
1055
+ { type: "vibrate", duration: 30, intensity: 0.5 },
1084
1056
  { type: "pause", duration: 30, intensity: 0 },
1085
- { type: "vibrate", duration: 8, intensity: 0.3 }
1057
+ { type: "vibrate", duration: 25, intensity: 0.4 }
1086
1058
  ]
1087
1059
  },
1088
1060
  /** Context menu appearance */
1089
1061
  contextMenu: {
1090
1062
  name: "ui.contextMenu",
1091
- steps: [{ type: "vibrate", duration: 20, intensity: 0.7 }]
1063
+ steps: [{ type: "vibrate", duration: 35, intensity: 0.7 }]
1092
1064
  },
1093
1065
  /** Drag start */
1094
1066
  dragStart: {
1095
1067
  name: "ui.dragStart",
1096
- steps: [{ type: "vibrate", duration: 12, intensity: 0.5 }]
1068
+ steps: [{ type: "vibrate", duration: 30, intensity: 0.5 }]
1097
1069
  },
1098
1070
  /** Drag drop */
1099
1071
  drop: {
1100
1072
  name: "ui.drop",
1101
1073
  steps: [
1102
- { type: "vibrate", duration: 20, intensity: 0.8 },
1074
+ { type: "vibrate", duration: 30, intensity: 0.8 },
1103
1075
  { type: "pause", duration: 30, intensity: 0 },
1104
- { type: "vibrate", duration: 10, intensity: 0.4 }
1076
+ { type: "vibrate", duration: 25, intensity: 0.5 }
1105
1077
  ]
1106
1078
  }
1107
1079
  };
@@ -1112,9 +1084,9 @@ var notifications = {
1112
1084
  success: {
1113
1085
  name: "notifications.success",
1114
1086
  steps: [
1115
- { type: "vibrate", duration: 30, intensity: 0.5 },
1087
+ { type: "vibrate", duration: 35, intensity: 0.5 },
1116
1088
  { type: "pause", duration: 60, intensity: 0 },
1117
- { type: "vibrate", duration: 40, intensity: 0.8 }
1089
+ { type: "vibrate", duration: 45, intensity: 0.8 }
1118
1090
  ]
1119
1091
  },
1120
1092
  /** Warning — three even pulses */
@@ -1141,16 +1113,16 @@ var notifications = {
1141
1113
  info: {
1142
1114
  name: "notifications.info",
1143
1115
  steps: [
1144
- { type: "vibrate", duration: 20, intensity: 0.4 }
1116
+ { type: "vibrate", duration: 35, intensity: 0.5 }
1145
1117
  ]
1146
1118
  },
1147
1119
  /** Message received */
1148
1120
  messageReceived: {
1149
1121
  name: "notifications.messageReceived",
1150
1122
  steps: [
1151
- { type: "vibrate", duration: 15, intensity: 0.5 },
1123
+ { type: "vibrate", duration: 30, intensity: 0.5 },
1152
1124
  { type: "pause", duration: 100, intensity: 0 },
1153
- { type: "vibrate", duration: 15, intensity: 0.5 }
1125
+ { type: "vibrate", duration: 30, intensity: 0.5 }
1154
1126
  ]
1155
1127
  },
1156
1128
  /** Alarm — urgent repeating pattern */
@@ -1174,9 +1146,9 @@ var notifications = {
1174
1146
  reminder: {
1175
1147
  name: "notifications.reminder",
1176
1148
  steps: [
1177
- { type: "vibrate", duration: 25, intensity: 0.5 },
1149
+ { type: "vibrate", duration: 30, intensity: 0.5 },
1178
1150
  { type: "pause", duration: 150, intensity: 0 },
1179
- { type: "vibrate", duration: 25, intensity: 0.5 }
1151
+ { type: "vibrate", duration: 30, intensity: 0.5 }
1180
1152
  ]
1181
1153
  }
1182
1154
  };
@@ -1190,26 +1162,25 @@ var gaming = {
1190
1162
  { type: "vibrate", duration: 100, intensity: 1 },
1191
1163
  { type: "vibrate", duration: 80, intensity: 0.8 },
1192
1164
  { type: "vibrate", duration: 60, intensity: 0.5 },
1193
- { type: "vibrate", duration: 40, intensity: 0.3 },
1194
- { type: "vibrate", duration: 30, intensity: 0.1 }
1165
+ { type: "vibrate", duration: 40, intensity: 0.3 }
1195
1166
  ]
1196
1167
  },
1197
1168
  /** Collision — sharp impact */
1198
1169
  collision: {
1199
1170
  name: "gaming.collision",
1200
1171
  steps: [
1201
- { type: "vibrate", duration: 30, intensity: 1 },
1202
- { type: "pause", duration: 20, intensity: 0 },
1203
- { type: "vibrate", duration: 15, intensity: 0.5 }
1172
+ { type: "vibrate", duration: 40, intensity: 1 },
1173
+ { type: "pause", duration: 30, intensity: 0 },
1174
+ { type: "vibrate", duration: 25, intensity: 0.5 }
1204
1175
  ]
1205
1176
  },
1206
1177
  /** Heartbeat — rhythmic pulse */
1207
1178
  heartbeat: {
1208
1179
  name: "gaming.heartbeat",
1209
1180
  steps: [
1210
- { type: "vibrate", duration: 20, intensity: 0.8 },
1181
+ { type: "vibrate", duration: 30, intensity: 0.8 },
1211
1182
  { type: "pause", duration: 80, intensity: 0 },
1212
- { type: "vibrate", duration: 30, intensity: 1 },
1183
+ { type: "vibrate", duration: 40, intensity: 1 },
1213
1184
  { type: "pause", duration: 400, intensity: 0 }
1214
1185
  ]
1215
1186
  },
@@ -1217,17 +1188,17 @@ var gaming = {
1217
1188
  gunshot: {
1218
1189
  name: "gaming.gunshot",
1219
1190
  steps: [
1220
- { type: "vibrate", duration: 15, intensity: 1 },
1221
- { type: "vibrate", duration: 30, intensity: 0.4 }
1191
+ { type: "vibrate", duration: 30, intensity: 1 },
1192
+ { type: "vibrate", duration: 40, intensity: 0.4 }
1222
1193
  ]
1223
1194
  },
1224
1195
  /** Sword clash — metallic ring */
1225
1196
  swordClash: {
1226
1197
  name: "gaming.swordClash",
1227
1198
  steps: [
1228
- { type: "vibrate", duration: 10, intensity: 1 },
1229
- { type: "pause", duration: 10, intensity: 0 },
1230
- { type: "vibrate", duration: 30, intensity: 0.6 },
1199
+ { type: "vibrate", duration: 25, intensity: 1 },
1200
+ { type: "pause", duration: 20, intensity: 0 },
1201
+ { type: "vibrate", duration: 40, intensity: 0.6 },
1231
1202
  { type: "vibrate", duration: 50, intensity: 0.3 }
1232
1203
  ]
1233
1204
  },
@@ -1235,10 +1206,10 @@ var gaming = {
1235
1206
  powerUp: {
1236
1207
  name: "gaming.powerUp",
1237
1208
  steps: [
1238
- { type: "vibrate", duration: 40, intensity: 0.2 },
1239
- { type: "vibrate", duration: 40, intensity: 0.4 },
1240
- { type: "vibrate", duration: 40, intensity: 0.6 },
1241
- { type: "vibrate", duration: 40, intensity: 0.8 },
1209
+ { type: "vibrate", duration: 40, intensity: 0.3 },
1210
+ { type: "vibrate", duration: 40, intensity: 0.5 },
1211
+ { type: "vibrate", duration: 40, intensity: 0.7 },
1212
+ { type: "vibrate", duration: 40, intensity: 0.9 },
1242
1213
  { type: "vibrate", duration: 60, intensity: 1 }
1243
1214
  ]
1244
1215
  },
@@ -1246,46 +1217,46 @@ var gaming = {
1246
1217
  damage: {
1247
1218
  name: "gaming.damage",
1248
1219
  steps: [
1249
- { type: "vibrate", duration: 40, intensity: 0.9 },
1250
- { type: "pause", duration: 20, intensity: 0 },
1251
- { type: "vibrate", duration: 30, intensity: 0.6 },
1252
- { type: "pause", duration: 20, intensity: 0 },
1253
- { type: "vibrate", duration: 20, intensity: 0.3 }
1220
+ { type: "vibrate", duration: 50, intensity: 0.9 },
1221
+ { type: "pause", duration: 25, intensity: 0 },
1222
+ { type: "vibrate", duration: 40, intensity: 0.6 },
1223
+ { type: "pause", duration: 25, intensity: 0 },
1224
+ { type: "vibrate", duration: 30, intensity: 0.4 }
1254
1225
  ]
1255
1226
  },
1256
1227
  /** Item pickup — light cheerful */
1257
1228
  pickup: {
1258
1229
  name: "gaming.pickup",
1259
1230
  steps: [
1260
- { type: "vibrate", duration: 10, intensity: 0.3 },
1231
+ { type: "vibrate", duration: 25, intensity: 0.4 },
1261
1232
  { type: "pause", duration: 40, intensity: 0 },
1262
- { type: "vibrate", duration: 15, intensity: 0.6 }
1233
+ { type: "vibrate", duration: 30, intensity: 0.7 }
1263
1234
  ]
1264
1235
  },
1265
1236
  /** Level complete — celebratory */
1266
1237
  levelComplete: {
1267
1238
  name: "gaming.levelComplete",
1268
1239
  steps: [
1269
- { type: "vibrate", duration: 20, intensity: 0.5 },
1240
+ { type: "vibrate", duration: 30, intensity: 0.5 },
1270
1241
  { type: "pause", duration: 60, intensity: 0 },
1271
- { type: "vibrate", duration: 20, intensity: 0.5 },
1242
+ { type: "vibrate", duration: 30, intensity: 0.5 },
1272
1243
  { type: "pause", duration: 60, intensity: 0 },
1273
- { type: "vibrate", duration: 30, intensity: 0.7 },
1244
+ { type: "vibrate", duration: 40, intensity: 0.7 },
1274
1245
  { type: "pause", duration: 60, intensity: 0 },
1275
- { type: "vibrate", duration: 50, intensity: 1 }
1246
+ { type: "vibrate", duration: 60, intensity: 1 }
1276
1247
  ]
1277
1248
  },
1278
1249
  /** Engine rumble — continuous vibration */
1279
1250
  engineRumble: {
1280
1251
  name: "gaming.engineRumble",
1281
1252
  steps: [
1282
- { type: "vibrate", duration: 30, intensity: 0.4 },
1283
- { type: "pause", duration: 10, intensity: 0 },
1284
- { type: "vibrate", duration: 30, intensity: 0.5 },
1285
- { type: "pause", duration: 10, intensity: 0 },
1286
- { type: "vibrate", duration: 30, intensity: 0.4 },
1287
- { type: "pause", duration: 10, intensity: 0 },
1288
- { type: "vibrate", duration: 30, intensity: 0.5 }
1253
+ { type: "vibrate", duration: 40, intensity: 0.5 },
1254
+ { type: "pause", duration: 15, intensity: 0 },
1255
+ { type: "vibrate", duration: 40, intensity: 0.6 },
1256
+ { type: "pause", duration: 15, intensity: 0 },
1257
+ { type: "vibrate", duration: 40, intensity: 0.5 },
1258
+ { type: "pause", duration: 15, intensity: 0 },
1259
+ { type: "vibrate", duration: 40, intensity: 0.6 }
1289
1260
  ]
1290
1261
  }
1291
1262
  };
@@ -1296,9 +1267,9 @@ var accessibility = {
1296
1267
  confirm: {
1297
1268
  name: "accessibility.confirm",
1298
1269
  steps: [
1299
- { type: "vibrate", duration: 30, intensity: 0.7 },
1270
+ { type: "vibrate", duration: 35, intensity: 0.7 },
1300
1271
  { type: "pause", duration: 100, intensity: 0 },
1301
- { type: "vibrate", duration: 30, intensity: 0.7 }
1272
+ { type: "vibrate", duration: 35, intensity: 0.7 }
1302
1273
  ]
1303
1274
  },
1304
1275
  /** Deny/reject — long single buzz */
@@ -1312,41 +1283,41 @@ var accessibility = {
1312
1283
  boundary: {
1313
1284
  name: "accessibility.boundary",
1314
1285
  steps: [
1315
- { type: "vibrate", duration: 15, intensity: 1 }
1286
+ { type: "vibrate", duration: 30, intensity: 1 }
1316
1287
  ]
1317
1288
  },
1318
1289
  /** Focus change — subtle tick */
1319
1290
  focusChange: {
1320
1291
  name: "accessibility.focusChange",
1321
1292
  steps: [
1322
- { type: "vibrate", duration: 5, intensity: 0.3 }
1293
+ { type: "vibrate", duration: 25, intensity: 0.5 }
1323
1294
  ]
1324
1295
  },
1325
1296
  /** Counting rhythm — one tick per count */
1326
1297
  countTick: {
1327
1298
  name: "accessibility.countTick",
1328
1299
  steps: [
1329
- { type: "vibrate", duration: 8, intensity: 0.5 }
1300
+ { type: "vibrate", duration: 25, intensity: 0.5 }
1330
1301
  ]
1331
1302
  },
1332
1303
  /** Navigation landmark reached */
1333
1304
  landmark: {
1334
1305
  name: "accessibility.landmark",
1335
1306
  steps: [
1336
- { type: "vibrate", duration: 15, intensity: 0.6 },
1307
+ { type: "vibrate", duration: 25, intensity: 0.6 },
1337
1308
  { type: "pause", duration: 40, intensity: 0 },
1338
- { type: "vibrate", duration: 15, intensity: 0.6 },
1309
+ { type: "vibrate", duration: 25, intensity: 0.6 },
1339
1310
  { type: "pause", duration: 40, intensity: 0 },
1340
- { type: "vibrate", duration: 15, intensity: 0.6 }
1311
+ { type: "vibrate", duration: 25, intensity: 0.6 }
1341
1312
  ]
1342
1313
  },
1343
1314
  /** Progress checkpoint — escalating feedback */
1344
1315
  progressCheckpoint: {
1345
1316
  name: "accessibility.progressCheckpoint",
1346
1317
  steps: [
1347
- { type: "vibrate", duration: 20, intensity: 0.4 },
1318
+ { type: "vibrate", duration: 30, intensity: 0.5 },
1348
1319
  { type: "pause", duration: 60, intensity: 0 },
1349
- { type: "vibrate", duration: 25, intensity: 0.7 }
1320
+ { type: "vibrate", duration: 35, intensity: 0.7 }
1350
1321
  ]
1351
1322
  }
1352
1323
  };
@@ -1356,51 +1327,51 @@ var system = {
1356
1327
  /** Keyboard key press */
1357
1328
  keyPress: {
1358
1329
  name: "system.keyPress",
1359
- steps: [{ type: "vibrate", duration: 5, intensity: 0.3 }]
1330
+ steps: [{ type: "vibrate", duration: 25, intensity: 0.5 }]
1360
1331
  },
1361
1332
  /** Scroll tick (detent-like) */
1362
1333
  scrollTick: {
1363
1334
  name: "system.scrollTick",
1364
- steps: [{ type: "vibrate", duration: 3, intensity: 0.2 }]
1335
+ steps: [{ type: "vibrate", duration: 20, intensity: 0.4 }]
1365
1336
  },
1366
1337
  /** Scroll boundary reached */
1367
1338
  scrollBounce: {
1368
1339
  name: "system.scrollBounce",
1369
1340
  steps: [
1370
- { type: "vibrate", duration: 10, intensity: 0.5 },
1371
- { type: "vibrate", duration: 20, intensity: 0.3 }
1341
+ { type: "vibrate", duration: 25, intensity: 0.6 },
1342
+ { type: "vibrate", duration: 30, intensity: 0.4 }
1372
1343
  ]
1373
1344
  },
1374
1345
  /** Delete action */
1375
1346
  delete: {
1376
1347
  name: "system.delete",
1377
1348
  steps: [
1378
- { type: "vibrate", duration: 15, intensity: 0.5 },
1349
+ { type: "vibrate", duration: 30, intensity: 0.5 },
1379
1350
  { type: "pause", duration: 50, intensity: 0 },
1380
- { type: "vibrate", duration: 25, intensity: 0.8 }
1351
+ { type: "vibrate", duration: 40, intensity: 0.8 }
1381
1352
  ]
1382
1353
  },
1383
1354
  /** Undo action */
1384
1355
  undo: {
1385
1356
  name: "system.undo",
1386
1357
  steps: [
1387
- { type: "vibrate", duration: 20, intensity: 0.5 },
1358
+ { type: "vibrate", duration: 30, intensity: 0.5 },
1388
1359
  { type: "pause", duration: 80, intensity: 0 },
1389
- { type: "vibrate", duration: 10, intensity: 0.3 }
1360
+ { type: "vibrate", duration: 25, intensity: 0.4 }
1390
1361
  ]
1391
1362
  },
1392
1363
  /** Copy to clipboard */
1393
1364
  copy: {
1394
1365
  name: "system.copy",
1395
- steps: [{ type: "vibrate", duration: 12, intensity: 0.4 }]
1366
+ steps: [{ type: "vibrate", duration: 30, intensity: 0.5 }]
1396
1367
  },
1397
1368
  /** Paste from clipboard */
1398
1369
  paste: {
1399
1370
  name: "system.paste",
1400
1371
  steps: [
1401
- { type: "vibrate", duration: 8, intensity: 0.3 },
1372
+ { type: "vibrate", duration: 25, intensity: 0.4 },
1402
1373
  { type: "pause", duration: 30, intensity: 0 },
1403
- { type: "vibrate", duration: 12, intensity: 0.5 }
1374
+ { type: "vibrate", duration: 30, intensity: 0.6 }
1404
1375
  ]
1405
1376
  }
1406
1377
  };