p5-phone 1.6.1 → 1.6.3

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.
Files changed (67) hide show
  1. package/README.md +3 -3
  2. package/dist/p5-phone.js +33 -32
  3. package/dist/p5-phone.min.js +1 -1
  4. package/examples/Phone Sensor Examples/microphone/01_mic_level/index.html +1 -1
  5. package/examples/Phone Sensor Examples/movement/01_orientation_basic/index.html +1 -1
  6. package/examples/Phone Sensor Examples/movement/02_rotational_velocity/index.html +1 -1
  7. package/examples/Phone Sensor Examples/movement/03_acceleration/index.html +1 -1
  8. package/examples/Phone Sensor Examples/sound/01_dual_audio/index.html +1 -1
  9. package/examples/Phone Sensor Examples/sound/02_volume_touches/index.html +1 -1
  10. package/examples/Phone Sensor Examples/touch/01_touch_basic/index.html +1 -1
  11. package/examples/Phone Sensor Examples/touch/02_touch_zones/index.html +1 -1
  12. package/examples/Phone Sensor Examples/touch/03_touch_count/index.html +1 -1
  13. package/examples/Phone Sensor Examples/touch/04_touch_distance/index.html +1 -1
  14. package/examples/Phone Sensor Examples/touch/05_touch_angle/index.html +1 -1
  15. package/examples/Phone Sensor Examples/vibration/01_haptic_feedback/index.html +1 -1
  16. package/examples/Phone Sensor Examples - Minimal/microphone/01_mic_level/index.html +1 -1
  17. package/examples/Phone Sensor Examples - Minimal/movement/01_orientation_basic/index.html +1 -1
  18. package/examples/Phone Sensor Examples - Minimal/movement/02_rotational_velocity/index.html +1 -1
  19. package/examples/Phone Sensor Examples - Minimal/movement/03_acceleration/index.html +1 -1
  20. package/examples/Phone Sensor Examples - Minimal/sound/01_sound_basic/index.html +1 -1
  21. package/examples/Phone Sensor Examples - Minimal/sound/02_sound_amplitude/index.html +1 -1
  22. package/examples/Phone Sensor Examples - Minimal/touch/01_touch_basic/index.html +1 -1
  23. package/examples/Phone Sensor Examples - Minimal/touch/02_touch_zones/index.html +1 -1
  24. package/examples/Phone Sensor Examples - Minimal/touch/03_touch_count/index.html +1 -1
  25. package/examples/Phone Sensor Examples - Minimal/touch/04_touch_distance/index.html +1 -1
  26. package/examples/Phone Sensor Examples - Minimal/touch/05_touch_angle/index.html +1 -1
  27. package/examples/Phone Sensor Examples - Minimal/vibration/01_haptic_feedback/index.html +1 -1
  28. package/examples/Phone and Gif/collision/index.html +1 -1
  29. package/examples/Phone and Gif/fetch/index.html +1 -1
  30. package/examples/Phone and Gif/fly/index.html +1 -1
  31. package/examples/Phone and Gif/roll/index.html +1 -1
  32. package/examples/UXcompare/button-vs-movement/index.html +1 -1
  33. package/examples/UXcompare/button-vs-orientation/index.html +1 -1
  34. package/examples/UXcompare/button-vs-shake/index.html +1 -1
  35. package/examples/UXcompare/gyroscope-demo/index.html +1 -1
  36. package/examples/UXcompare/microphone-demo/index.html +1 -1
  37. package/examples/UXcompare/slider-vs-angle/index.html +1 -1
  38. package/examples/UXcompare/slider-vs-distance/index.html +1 -1
  39. package/examples/UXcompare/slider-vs-microphone/index.html +1 -1
  40. package/examples/UXcompare/slider-vs-touches/index.html +1 -1
  41. package/examples/UXcompare/sliders-vs-acceleration/index.html +1 -1
  42. package/examples/UXcompare/sliders-vs-rotation/index.html +1 -1
  43. package/examples/blankTemplate/index.html +1 -1
  44. package/examples/homepage/index.html +5 -5
  45. package/examples/{workArea/04_facemesh-FINAL → ml5/PHONE_FaceMesh_two_points}/index.html +5 -1
  46. package/examples/ml5/PHONE_FaceMesh_two_points/sketch.js +380 -0
  47. package/package.json +1 -1
  48. package/src/p5-phone.js +33 -32
  49. package/examples/workArea/01_camera-selector/README.md +0 -119
  50. package/examples/workArea/01_camera-selector/index.html +0 -28
  51. package/examples/workArea/01_camera-selector/sketch.js +0 -239
  52. package/examples/workArea/03_facemesh-nose/index.html +0 -34
  53. package/examples/workArea/03_facemesh-nose/sketch.js +0 -247
  54. package/examples/workArea/03_facemesh-nose-preload/index.html +0 -34
  55. package/examples/workArea/03_facemesh-nose-preload/sketch.js +0 -173
  56. package/examples/workArea/04_facemesh-FINAL/README.md +0 -85
  57. package/examples/workArea/04_facemesh-FINAL/sketch.js +0 -240
  58. package/examples/workArea/04_facemesh-simplified_temp/README.md +0 -93
  59. package/examples/workArea/04_facemesh-simplified_temp/index.html +0 -31
  60. package/examples/workArea/04_facemesh-simplified_temp/sketch.js +0 -259
  61. package/examples/workArea/05_handpose/extra.js +0 -0
  62. package/examples/workArea/05_handpose/index.html +0 -31
  63. package/examples/workArea/05_handpose/sketch.js +0 -362
  64. package/examples/workArea/05_handpose-preload/index.html +0 -31
  65. package/examples/workArea/05_handpose-preload/sketch.js +0 -362
  66. package/examples/workArea/06_bodypose-FINAL/index.html +0 -31
  67. package/examples/workArea/06_bodypose-FINAL/sketch.js +0 -360
package/README.md CHANGED
@@ -67,10 +67,10 @@ This library simplifies access to the following p5.js mobile sensor and audio co
67
67
 
68
68
  ```html
69
69
  <!-- Minified version (recommended) -->
70
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
70
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
71
71
 
72
72
  <!-- Development version (larger, with comments) -->
73
- <!-- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.js"></script> -->
73
+ <!-- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.js"></script> -->
74
74
  ```
75
75
 
76
76
  ### Basic Setup
@@ -98,7 +98,7 @@ This library simplifies access to the following p5.js mobile sensor and audio co
98
98
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.10/p5.min.js"></script>
99
99
 
100
100
  <!-- Load p5-phone library -->
101
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
101
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
102
102
 
103
103
  </head>
104
104
  <body>
package/dist/p5-phone.js CHANGED
@@ -1367,8 +1367,12 @@ class PhoneCamera {
1367
1367
 
1368
1368
  const videoWidth = this._video.width;
1369
1369
  const videoHeight = this._video.height;
1370
- const canvasWidth = window.width || window.innerWidth;
1371
- const canvasHeight = window.height || window.innerHeight;
1370
+
1371
+ // Get actual canvas DISPLAY dimensions (not drawing buffer dimensions)
1372
+ // In p5.js, the width/height globals represent the logical canvas size
1373
+ // which already accounts for pixel density in recent versions
1374
+ const canvasWidth = (typeof width !== 'undefined') ? width : window.innerWidth;
1375
+ const canvasHeight = (typeof height !== 'undefined') ? height : window.innerHeight;
1372
1376
 
1373
1377
  let drawWidth, drawHeight, drawX, drawY;
1374
1378
 
@@ -1442,11 +1446,10 @@ class PhoneCamera {
1442
1446
  }
1443
1447
 
1444
1448
  // Add offset to position on canvas
1445
- // Note: dims.x can be negative in fitHeight mode when video is wider than canvas
1446
- // In that case, the video is drawn starting off-screen, but we want coordinates
1447
- // relative to the visible portion, so we use max(0, dims.x)
1448
- const mappedX = scaledX + Math.max(0, dims.x);
1449
- const mappedY = scaledY + Math.max(0, dims.y);
1449
+ // dims.x and dims.y represent where the video is drawn on the canvas
1450
+ // This can be negative when the video is larger than the canvas (fitHeight/fitWidth modes)
1451
+ const mappedX = scaledX + dims.x;
1452
+ const mappedY = scaledY + dims.y;
1450
1453
 
1451
1454
  return { x: mappedX, y: mappedY };
1452
1455
  }
@@ -1502,14 +1505,32 @@ class PhoneCamera {
1502
1505
 
1503
1506
  const dims = this.getDimensions();
1504
1507
 
1508
+ // Get canvas display dimensions for mirroring
1509
+ const canvasWidth = (typeof width !== 'undefined') ? width : window.innerWidth;
1510
+
1511
+ // Debug: log what we're drawing (once)
1512
+ if (!this._drawDebugLogged) {
1513
+ console.log('_draw() params:', {
1514
+ x: dims.x,
1515
+ y: dims.y,
1516
+ width: dims.width,
1517
+ height: dims.height,
1518
+ canvasWidth: canvasWidth,
1519
+ mirror: this._mirror
1520
+ });
1521
+ this._drawDebugLogged = true;
1522
+ }
1523
+
1505
1524
  // Save current drawing state
1506
1525
  push();
1507
1526
 
1508
1527
  // Apply mirroring if needed
1509
1528
  if (this._mirror) {
1510
- translate(dims.x + dims.width, dims.y);
1529
+ // Mirror by flipping around the center of the canvas
1530
+ translate(canvasWidth, 0);
1511
1531
  scale(-1, 1);
1512
- image(this._video, 0, 0, dims.width, dims.height);
1532
+ // Draw at the same logical position
1533
+ image(this._video, dims.x, dims.y, dims.width, dims.height);
1513
1534
  } else {
1514
1535
  image(this._video, dims.x, dims.y, dims.width, dims.height);
1515
1536
  }
@@ -1619,29 +1640,9 @@ if (typeof p5 !== 'undefined' && p5.prototype) {
1619
1640
  if (args[0] instanceof PhoneCamera) {
1620
1641
  const cam = args[0];
1621
1642
 
1622
- // If x and y are provided, use them, otherwise use camera's calculated position
1623
- if (args.length >= 3) {
1624
- // User provided position: image(cam, x, y, [w], [h])
1625
- if (!cam.ready || !cam.video) return;
1626
-
1627
- const x = args[1];
1628
- const y = args[2];
1629
- const w = args[3] || cam.width;
1630
- const h = args[4] || cam.height;
1631
-
1632
- this.push();
1633
- if (cam.mirror) {
1634
- this.translate(x + w, y);
1635
- this.scale(-1, 1);
1636
- originalImage.call(this, cam.video, 0, 0, w, h);
1637
- } else {
1638
- originalImage.call(this, cam.video, x, y, w, h);
1639
- }
1640
- this.pop();
1641
- } else {
1642
- // No position provided: image(cam) - use auto-positioning
1643
- cam._draw();
1644
- }
1643
+ // Always use auto-positioning for PhoneCamera
1644
+ // The camera calculates the correct position based on mode (fitHeight, fitWidth, etc)
1645
+ cam._draw();
1645
1646
  } else {
1646
1647
  // Not a PhoneCamera, use original image function
1647
1648
  originalImage.apply(this, args);
@@ -7,4 +7,4 @@
7
7
  * Released under the MIT License
8
8
  * https://opensource.org/licenses/MIT
9
9
  */
10
- window._originalConsoleError=console.error,window._originalConsoleWarn=console.warn,window._debugErrorHandlersSet||(window._debugErrorHandlersSet=!0,window._earlyErrors=window._earlyErrors||[],window.addEventListener("error",function(e){const n=`${e.error?.message||e.message||"Unknown error"} (${e.filename?e.filename.split("/").pop():"unknown file"}:${e.lineno||"unknown line"})`;console.error("🚨 Error caught:",n),e.error?.stack&&console.error("Stack:",e.error.stack),window._earlyErrors.push({type:"error",message:"JavaScript Error: "+n,stack:e.error?.stack}),!1===window.SHOW_DEBUG||window._debugVisible||"function"==typeof showDebug&&showDebug(),window._debugVisible&&"function"==typeof debugError&&(debugError("JavaScript Error:",n),e.error?.stack&&debugError("Stack trace:",e.error.stack))}),window.addEventListener("unhandledrejection",function(e){const n=e.reason?.message||e.reason||"Unknown promise rejection";console.error("🚨 Promise rejection caught:",n),window._earlyErrors.push({type:"error",message:"Unhandled Promise Rejection: "+n}),window._debugVisible&&"function"==typeof debugError&&debugError("Unhandled Promise Rejection:",n)})),window.sensorsEnabled=!1,window.micEnabled=!1,window.soundEnabled=!1,window.gesturesLocked=!1,window.vibrationEnabled=!1;let _permissionsInitialized=!1,_micInstance=null;function lockGestures(){window.gesturesLocked||(console.log("🔒 Locking mobile gestures..."),_initializeGestureBlocking(),_initializeP5TouchOverrides(),window.gesturesLocked=!0,console.log("✅ Mobile gestures locked"))}function enableGyroButton(e="ENABLE MOTION SENSORS",n="Requesting motion sensors..."){_createPermissionButton(e,n,async()=>{await _requestMotionPermissions(),console.log("✅ Gyroscope enabled via button")})}function enableGyroTap(e="Tap screen to enable motion sensors"){_createTapToEnable(e,async()=>{await _requestMotionPermissions(),console.log("✅ Gyroscope enabled via tap")})}function enableMicButton(e="ENABLE MICROPHONE",n="Requesting microphone access..."){_createPermissionButton(e,n,async()=>{await _requestMicrophonePermissions(),console.log("✅ Microphone enabled via button")})}function enableMicTap(e="Tap screen to enable microphone"){_createTapToEnable(e,async()=>{await _requestMicrophonePermissions(),console.log("✅ Microphone enabled via tap")})}function enableSoundButton(e="ENABLE SOUND",n="Enabling audio..."){_createPermissionButton(e,n,async()=>{await _requestSoundOutput(),console.log("✅ Sound output enabled via button")})}function enableSoundTap(e="Tap screen to enable sound"){_createTapToEnable(e,async()=>{await _requestSoundOutput(),console.log("✅ Sound output enabled via tap")})}function enableVibrationButton(e="ENABLE VIBRATION",n="Enabling vibration..."){_createPermissionButton(e,n,async()=>{await _requestVibrationPermission(),console.log("✅ Vibration enabled via button")})}function enableVibrationTap(e="Tap screen to enable vibration"){_createTapToEnable(e,async()=>{await _requestVibrationPermission(),console.log("✅ Vibration enabled via tap")})}function enableAllButton(e="ENABLE MOTION & MICROPHONE",n="Requesting permissions..."){_createPermissionButton(e,n,async()=>{await _requestMotionPermissions(),await _requestMicrophonePermissions(),console.log("✅ Motion sensors and microphone enabled via button")})}function enableAllTap(e="Tap screen to enable motion sensors & microphone"){_createTapToEnable(e,async()=>{await _requestMotionPermissions(),await _requestMicrophonePermissions(),console.log("✅ Motion sensors and microphone enabled via tap")})}function vibrate(e){return window.vibrationEnabled?navigator.vibrate?navigator.vibrate(e):(console.warn("⚠️ Vibration API not supported on this device"),!1):(console.warn("⚠️ Vibration not enabled. Call enableVibrationTap() or enableVibrationButton() first."),!1)}function stopVibration(){navigator.vibrate&&navigator.vibrate(0)}async function _requestMotionPermissions(){try{if("undefined"!=typeof DeviceOrientationEvent&&"function"==typeof DeviceOrientationEvent.requestPermission){const e=await DeviceOrientationEvent.requestPermission();if(console.log("Orientation permission:",e),"undefined"!=typeof DeviceMotionEvent&&"function"==typeof DeviceMotionEvent.requestPermission){const e=await DeviceMotionEvent.requestPermission();console.log("Motion permission:",e)}}window.sensorsEnabled=!0,_notifySketchReady()}catch(e){console.error("Motion sensor permission error:",e),_debugVisible&&debugError("Motion sensor permission error:",e),window.sensorsEnabled=!0,_notifySketchReady()}}async function _requestMicrophonePermissions(){try{"undefined"!=typeof userStartAudio&&await userStartAudio(),"undefined"!=typeof mic&&mic&&mic.start?(mic.start(),_micInstance=mic,window.micEnabled=!0):console.warn("No microphone object found. Create one with: mic = new p5.AudioIn();"),_notifySketchReady()}catch(e){console.error("Microphone permission error:",e),_debugVisible&&debugError("Microphone permission error:",e),_notifySketchReady()}}async function _requestSoundOutput(){try{"undefined"!=typeof userStartAudio&&await userStartAudio(),window.soundEnabled=!0,_notifySketchReady()}catch(e){console.error("Sound output error:",e),_debugVisible&&debugError("Sound output error:",e),window.soundEnabled=!0,_notifySketchReady()}}async function _requestVibrationPermission(){try{if(!navigator.vibrate)return console.warn("⚠️ Vibration API not supported on this device (likely iOS)"),_debugVisible&&debugWarn("Vibration API not supported on this device"),window.vibrationEnabled=!1,void _notifySketchReady();navigator.vibrate(1)?(window.vibrationEnabled=!0,console.log("✅ Vibration enabled")):(console.warn("⚠️ Vibration API available but vibration failed"),window.vibrationEnabled=!1),_notifySketchReady()}catch(e){console.error("Vibration permission error:",e),_debugVisible&&debugError("Vibration permission error:",e),window.vibrationEnabled=!1,_notifySketchReady()}}function _notifySketchReady(){"function"==typeof userSetupComplete&&userSetupComplete(),window.dispatchEvent(new CustomEvent("permissionsReady",{detail:{sensors:window.sensorsEnabled,microphone:window.micEnabled,sound:window.soundEnabled,vibration:window.vibrationEnabled,gestures:window.gesturesLocked}}))}function _createPermissionButton(e,n,t){_removeExistingUI();const o=document.createElement("button");o.id="permissionButton",o.textContent=e,o.style.cssText="\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n padding: 20px 40px;\n font-size: 18px;\n font-weight: bold;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n border: none;\n border-radius: 12px;\n cursor: pointer;\n z-index: 999999;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n box-shadow: 0 4px 15px rgba(0,0,0,0.2);\n transition: transform 0.2s ease;\n touch-action: manipulation;\n ";const i=document.createElement("div");i.id="permissionStatus",i.textContent=n,i.style.cssText="\n position: fixed;\n top: 60%;\n left: 50%;\n transform: translate(-50%, 0);\n color: white;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n text-align: center;\n z-index: 999998;\n display: none;\n ",o.addEventListener("mouseenter",()=>{o.style.transform="translate(-50%, -50%) scale(1.05)"}),o.addEventListener("mouseleave",()=>{o.style.transform="translate(-50%, -50%) scale(1)"});const r=async()=>{o.parentNode&&(o.style.display="none",i.style.display="block",await t(),i.style.display="none",_removeExistingUI())};o.addEventListener("click",r),o.addEventListener("touchend",function(e){e.preventDefault(),e.stopPropagation(),r()}),o.addEventListener("pointerup",function(e){e.preventDefault(),e.stopPropagation(),r()}),document.body.appendChild(o),document.body.appendChild(i)}function _createTapToEnable(e,n){_removeExistingUI();const t=document.createElement("div");t.id="tapOverlay",t.style.cssText="\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.8);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 999999;\n cursor: pointer;\n touch-action: manipulation;\n ";const o=document.createElement("div");o.textContent=e,o.style.cssText="\n color: white;\n font-size: 24px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n text-align: center;\n padding: 40px;\n border: 2px solid rgba(255, 255, 255, 0.3);\n border-radius: 12px;\n background: rgba(255, 255, 255, 0.1);\n backdrop-filter: blur(10px);\n ",t.appendChild(o);const i=async()=>{t.parentNode&&(o.textContent="Enabling...",await n(),t.parentNode&&document.body.removeChild(t))};t.addEventListener("click",i),t.addEventListener("touchend",function(e){e.preventDefault(),e.stopPropagation(),i()}),t.addEventListener("pointerup",function(e){e.preventDefault(),e.stopPropagation(),i()}),document.body.appendChild(t)}function _removeExistingUI(){const e=document.getElementById("permissionButton"),n=document.getElementById("permissionStatus"),t=document.getElementById("tapOverlay");e&&e.remove(),n&&n.remove(),t&&t.remove()}function _initializeGestureBlocking(){window.history.pushState(null,"",window.location.href),window.onpopstate=function(){window.history.pushState(null,"",window.location.href)},window.addEventListener("beforeunload",function(e){e.preventDefault(),e.returnValue=""}),_initializeEdgeSwipePrevention(),_initializeOtherGesturePrevention()}function _initializeEdgeSwipePrevention(){let e=0,n=0;document.addEventListener("touchstart",function(t){t.touches&&t.touches.length>0&&(e=t.touches[0].clientX,n=t.touches[0].clientY,(e<20||e>window.innerWidth-20)&&t.preventDefault())},{passive:!1,capture:!0}),document.addEventListener("touchmove",function(t){if(!t.touches||0===t.touches.length)return;let o=t.touches[0].clientX,i=t.touches[0].clientY,r=o-e,a=i-n;(e<20&&r>0||e>window.innerWidth-20&&r<0)&&(t.preventDefault(),t.stopPropagation()),0===window.pageYOffset&&a>0&&t.preventDefault(),!t.target||"CANVAS"!==t.target.tagName||document.getElementById("tapOverlay")||document.getElementById("permissionButton")||t.preventDefault()},{passive:!1,capture:!0})}function _initializeOtherGesturePrevention(){document.addEventListener("gesturestart",function(e){e.preventDefault()}),document.addEventListener("gesturechange",function(e){e.preventDefault()}),document.addEventListener("gestureend",function(e){e.preventDefault()});let e=0;document.addEventListener("touchend",function(n){if(n.target&&("tapOverlay"===n.target.id||n.target.closest("#tapOverlay")||"permissionButton"===n.target.id||"permissionStatus"===n.target.id||n.target.closest("#permissionButton")||n.target.closest("#permissionStatus")))return;const t=Date.now();t-e<=300&&n.preventDefault(),e=t},!1),window.oncontextmenu=function(e){return e.preventDefault(),e.stopPropagation(),!1}}function _initializeP5TouchOverrides(){setTimeout(()=>{if(window._setupDone)_overrideP5Touch();else{const e=setInterval(()=>{window._setupDone&&(_overrideP5Touch(),clearInterval(e))},100)}},100)}function _overrideP5Touch(){const e=window.touchStarted||function(){},n=window.touchMoved||function(){},t=window.touchEnded||function(){},o=window.mousePressed||function(){},i=window.mouseDragged||function(){},r=window.mouseReleased||function(){};window.touchStarted=function(n){return e(n),!1},window.touchMoved=function(e){return n(e),!1},window.touchEnded=function(e){return t(e),!1},window.mousePressed=function(e){return o(e),!1},window.mouseDragged=function(e){return i(e),!1},window.mouseReleased=function(e){return r(e),!1}}document.addEventListener("DOMContentLoaded",function(){const e=document.getElementById("startButton"),n=document.getElementById("statusText");e&&n&&(console.warn("⚠️ Legacy HTML elements detected. Consider using the new API functions instead."),e.addEventListener("click",async()=>{e.classList.add("hidden"),n.classList.remove("hidden"),n.textContent="Requesting permissions...",await _requestMotionPermissions(),await _requestMicrophonePermissions(),n.classList.add("hidden")}),lockGestures())});let _debugPanel=null,_debugVisible=!1,_debugMessages=[];const MAX_DEBUG_MESSAGES=20;function showDebug(){_createDebugPanel(),_debugPanel.style.display="block",_debugVisible=!0,window._debugVisible=!0,_setupConsoleOverrides(),_displayEarlyErrors()}function hideDebug(){_debugPanel&&(_debugPanel.style.display="none",_debugVisible=!1)}function toggleDebug(){_debugVisible?hideDebug():showDebug()}function debug(...e){console.log(...e);_addDebugMessage(e.map(e=>{if("object"==typeof e&&null!==e)try{return JSON.stringify(e,null,2)}catch(n){return String(e)}return String(e)}).join(" "),"log")}function debugError(...e){(window._originalConsoleError||console.error).apply(console,e);_addDebugMessage(`❌ ERROR: ${e.map(e=>{if("object"==typeof e&&null!==e)try{return JSON.stringify(e,null,2)}catch(n){return String(e)}return String(e)}).join(" ")}`,"error")}function debugWarn(...e){(window._originalConsoleWarn||console.warn).apply(console,e);_addDebugMessage(`⚠️ WARNING: ${e.map(e=>{if("object"==typeof e&&null!==e)try{return JSON.stringify(e,null,2)}catch(n){return String(e)}return String(e)}).join(" ")}`,"warning")}function _addDebugMessage(e,n="log"){const t={text:`[${(new Date).toLocaleTimeString("en-US",{hour12:!1,hour:"2-digit",minute:"2-digit",second:"2-digit",fractionalSecondDigits:3})}] ${e}`,type:n};_debugMessages.push(t),_debugMessages.length>20&&_debugMessages.shift(),_debugPanel&&_updateDebugDisplay()}function _setupConsoleOverrides(){window._consoleOverrideSet||(window._consoleOverrideSet=!0,window._originalConsoleError=console.error,window._originalConsoleWarn=console.warn,console.error=function(...e){window._originalConsoleError.apply(console,e),_debugVisible&&debugError(...e)},console.warn=function(...e){window._originalConsoleWarn.apply(console,e),_debugVisible&&debugWarn(...e)})}function _displayEarlyErrors(){window._earlyErrors&&window._earlyErrors.length>0&&(debugError(`🚨 Found ${window._earlyErrors.length} early error(s):`),window._earlyErrors.forEach(e=>{debugError(e.message),e.stack&&debugError("Stack trace:",e.stack)}),window._earlyErrors=[])}function _createDebugPanel(){if(_debugPanel)return;_debugPanel=document.createElement("div"),_debugPanel.id="mobile-debug-panel",_debugPanel.innerHTML='\n <div id="mobile-debug-header">\n <span>Debug</span>\n <button id="mobile-debug-close">×</button>\n </div>\n <div id="mobile-debug-content"></div>\n ';const e=document.createElement("style");e.textContent="\n #mobile-debug-panel {\n position: fixed;\n top: 20px;\n right: 20px;\n width: 350px;\n max-width: calc(100vw - 40px);\n max-height: 400px;\n background: rgba(0, 0, 0, 0.9);\n color: #ffffff;\n font-family: 'Courier New', monospace;\n font-size: 12px;\n border-radius: 8px;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);\n z-index: 10000;\n display: none;\n }\n \n #mobile-debug-header {\n background: rgba(255, 255, 255, 0.1);\n padding: 8px 12px;\n border-bottom: 1px solid rgba(255, 255, 255, 0.2);\n display: flex;\n justify-content: space-between;\n align-items: center;\n border-radius: 8px 8px 0 0;\n }\n \n #mobile-debug-header span {\n font-weight: bold;\n font-size: 13px;\n }\n \n #mobile-debug-close {\n background: none;\n border: none;\n color: #ffffff;\n font-size: 18px;\n cursor: pointer;\n padding: 0;\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n \n #mobile-debug-close:hover {\n background: rgba(255, 255, 255, 0.1);\n border-radius: 4px;\n }\n \n #mobile-debug-content {\n padding: 12px;\n max-height: 340px;\n overflow-y: auto;\n word-wrap: break-word;\n line-height: 1.4;\n }\n \n .debug-message {\n margin-bottom: 4px;\n white-space: pre-wrap;\n }\n \n .debug-message.error {\n color: #ff6b6b;\n background: rgba(255, 107, 107, 0.1);\n padding: 4px;\n border-radius: 3px;\n border-left: 3px solid #ff6b6b;\n }\n \n .debug-message.warning {\n color: #ffd93d;\n background: rgba(255, 217, 61, 0.1);\n padding: 4px;\n border-radius: 3px;\n border-left: 3px solid #ffd93d;\n }\n \n .debug-timestamp {\n color: #888;\n font-size: 10px;\n }\n \n @media (max-width: 480px) {\n #mobile-debug-panel {\n width: calc(100vw - 20px);\n right: 10px;\n top: 10px;\n }\n }\n ",document.head.appendChild(e),document.body.appendChild(_debugPanel),document.getElementById("mobile-debug-close").onclick=hideDebug,_updateDebugDisplay()}function _updateDebugDisplay(){if(!_debugPanel)return;const e=document.getElementById("mobile-debug-content");e&&(e.innerHTML=_debugMessages.map(e=>"string"==typeof e?`<div class="debug-message">${e}</div>`:`<div class="debug-message ${e.type}">${e.text}</div>`).join(""),e.scrollTop=e.scrollHeight)}debug.clear=function(){_debugMessages=[],_debugPanel&&_updateDebugDisplay(),console.clear()},window.debug=debug,window.debugError=debugError,window.debugWarn=debugWarn,window.showDebug=showDebug,window.hideDebug=hideDebug,window.toggleDebug=toggleDebug,window.lockGestures=lockGestures,window.enableGyroTap=enableGyroTap,window.enableGyroButton=enableGyroButton,window.enableMicTap=enableMicTap,window.enableMicButton=enableMicButton,window.enableSoundTap=enableSoundTap,window.enableSoundButton=enableSoundButton,window.enableVibrationTap=enableVibrationTap,window.enableVibrationButton=enableVibrationButton,window.vibrate=vibrate,window.stopVibration=stopVibration,window.enableAllTap=enableAllTap,window.enableAllButton=enableAllButton;class PhoneCamera{constructor(e="user",n=!0,t="fitHeight"){this._active=e,this._mirror=n,this._mode=t,this._fixedWidth=640,this._fixedHeight=480,this._video=null,this._ready=!1,this._p5Instance=window,this._onReadyCallback=null,this._createCaptureRef=null,window._phoneCameras||(window._phoneCameras=[]),window._phoneCameras.push(this)}get ready(){return this._ready}get video(){return this._video}get videoElement(){return this._video?this._video.elt:null}get width(){if(!this._ready)return 0;return this.getDimensions().width}get height(){if(!this._ready)return 0;return this.getDimensions().height}get active(){return this._active}set active(e){"user"===e||"environment"===e?this._active!==e&&(this._active=e,this._ready&&this._switchCamera()):console.error('PhoneCamera: active must be "user" or "environment"')}get mirror(){return this._mirror}set mirror(e){this._mirror=!!e}get mode(){return this._mode}set mode(e){const n=["fitWidth","fitHeight","cover","contain","fixed"];n.includes(e)?this._mode=e:console.error("PhoneCamera: mode must be one of:",n.join(", "))}get fixedWidth(){return this._fixedWidth}set fixedWidth(e){this._fixedWidth=Math.max(1,e)}get fixedHeight(){return this._fixedHeight}set fixedHeight(e){this._fixedHeight=Math.max(1,e)}onReady(e){this._onReadyCallback=e,this._ready&&this._video&&this._video.elt&&this._video.elt.readyState>=2?e():this._video&&this._checkVideoReady()}_initializeCamera(){if(this._ready||this._video)return;const e={video:{facingMode:this._active},audio:!1};this._video=createCapture(e,()=>{this._ready=!0,this._video.hide(),console.log("✅ PhoneCamera ready"),this._checkVideoReady()}),this._video&&this._video.elt&&this._video.elt.addEventListener("loadeddata",()=>{this._ready=!0,this._checkVideoReady()})}_checkVideoReady(){if(this._video&&this._video.elt&&this._video.elt.readyState>=2){if(this._onReadyCallback){const e=this._onReadyCallback;this._onReadyCallback=null,e()}}else setTimeout(()=>this._checkVideoReady(),100)}_switchCamera(){if(!this._video)return;this._ready;this._ready=!1,this._video.remove();const e={video:{facingMode:this._active},audio:!1};this._video=createCapture(e,()=>{this._ready=!0,this._video.hide(),console.log(`✅ PhoneCamera switched to ${this._active} camera`)}),this._video&&this._video.elt&&this._video.elt.addEventListener("loadeddata",()=>{this._ready=!0})}remove(){this._video&&(this._video.remove(),this._video=null),this._ready=!1}getDimensions(){if(!this._ready||!this._video)return{x:0,y:0,width:0,height:0,scaleX:1,scaleY:1};const e=this._video.width,n=this._video.height,t=window.width||window.innerWidth,o=window.height||window.innerHeight;let i,r,a,s;if("fixed"===this._mode)i=this._fixedWidth,r=this._fixedHeight,a=(t-i)/2,s=(o-r)/2;else if("fitWidth"===this._mode)i=t,r=n/e*i,a=0,s=(o-r)/2;else if("fitHeight"===this._mode)r=o,i=e/n*r,a=(t-i)/2,s=0;else if("cover"===this._mode){const d=Math.max(t/e,o/n);i=e*d,r=n*d,a=(t-i)/2,s=(o-r)/2}else if("contain"===this._mode){const d=Math.min(t/e,o/n);i=e*d,r=n*d,a=(t-i)/2,s=(o-r)/2}return{x:a,y:s,width:i,height:r,scaleX:i/e,scaleY:r/n}}mapPoint(e,n){const t=this.getDimensions();let o=e*t.scaleX;const i=n*t.scaleY;this._mirror&&(o=t.width-o);return{x:o+Math.max(0,t.x),y:i+Math.max(0,t.y)}}mapKeypoint(e){if(!e||void 0===e.x||void 0===e.y)return console.warn("PhoneCamera.mapKeypoint: invalid keypoint",e),e;const n=this.mapPoint(e.x,e.y);return{...e,x:n.x,y:n.y}}mapKeypoints(e){return Array.isArray(e)?e.map(e=>this.mapKeypoint(e)):(console.warn("PhoneCamera.mapKeypoints: expected array, got",typeof e),e)}_draw(){if(!this._ready||!this._video)return;const e=this.getDimensions();push(),this._mirror?(translate(e.x+e.width,e.y),scale(-1,1),image(this._video,0,0,e.width,e.height)):image(this._video,e.x,e.y,e.width,e.height),pop()}}function createPhoneCamera(e="user",n=!0,t="fitHeight"){return new PhoneCamera(e,n,t)}function enableCameraButton(e="ENABLE CAMERA",n="Starting camera..."){_createPermissionButton(e,n,async()=>{await _requestCameraPermission(),console.log("✅ Camera enabled via button")})}function enableCameraTap(e="Tap screen to enable camera"){navigator.permissions&&navigator.permissions.query?navigator.permissions.query({name:"camera"}).then(n=>{"granted"===n.state?(console.log("✅ Camera permission already granted - auto-starting"),_requestCameraPermission()):_createTapToEnable(e,async()=>{await _requestCameraPermission(),console.log("✅ Camera enabled via tap")})}).catch(()=>{_createTapToEnable(e,async()=>{await _requestCameraPermission(),console.log("✅ Camera enabled via tap")})}):_createTapToEnable(e,async()=>{await _requestCameraPermission(),console.log("✅ Camera enabled via tap")})}async function _requestCameraPermission(){try{if(void 0!==window._phoneCameras&&Array.isArray(window._phoneCameras))for(let e of window._phoneCameras)!e||e._ready||e._video||e._initializeCamera();"function"==typeof userCameraReady&&userCameraReady(),_notifySketchReady()}catch(e){console.error("Camera permission error:",e),_debugVisible&&debugError("Camera permission error:",e),_notifySketchReady()}}if(window.createPhoneCamera=createPhoneCamera,window.enableCameraButton=enableCameraButton,window.enableCameraTap=enableCameraTap,"undefined"!=typeof p5&&p5.prototype){const e=p5.prototype.image;p5.prototype.image=function(...n){if(n[0]instanceof PhoneCamera){const t=n[0];if(n.length>=3){if(!t.ready||!t.video)return;const o=n[1],i=n[2],r=n[3]||t.width,a=n[4]||t.height;this.push(),t.mirror?(this.translate(o+r,i),this.scale(-1,1),e.call(this,t.video,0,0,r,a)):e.call(this,t.video,o,i,r,a),this.pop()}else t._draw()}else e.apply(this,n)}}"undefined"!=typeof p5&&p5.prototype&&(p5.prototype.lockGestures=lockGestures,p5.prototype.enableGyroTap=enableGyroTap,p5.prototype.enableGyroButton=enableGyroButton,p5.prototype.enableMicTap=enableMicTap,p5.prototype.enableMicButton=enableMicButton,p5.prototype.enableSoundTap=enableSoundTap,p5.prototype.enableSoundButton=enableSoundButton,p5.prototype.enableVibrationTap=enableVibrationTap,p5.prototype.enableVibrationButton=enableVibrationButton,p5.prototype.vibrate=vibrate,p5.prototype.stopVibration=stopVibration,p5.prototype.enableAllTap=enableAllTap,p5.prototype.enableAllButton=enableAllButton,p5.prototype.createPhoneCamera=createPhoneCamera,p5.prototype.enableCameraButton=enableCameraButton,p5.prototype.enableCameraTap=enableCameraTap,p5.prototype.showDebug=showDebug,p5.prototype.hideDebug=hideDebug,p5.prototype.toggleDebug=toggleDebug,p5.prototype.debug=debug,p5.prototype.debugError=debugError,p5.prototype.debugWarn=debugWarn,console.log("✅ Mobile p5.js Permissions: p5.prototype functions registered"));
10
+ window._originalConsoleError=console.error,window._originalConsoleWarn=console.warn,window._debugErrorHandlersSet||(window._debugErrorHandlersSet=!0,window._earlyErrors=window._earlyErrors||[],window.addEventListener("error",function(e){const n=`${e.error?.message||e.message||"Unknown error"} (${e.filename?e.filename.split("/").pop():"unknown file"}:${e.lineno||"unknown line"})`;console.error("🚨 Error caught:",n),e.error?.stack&&console.error("Stack:",e.error.stack),window._earlyErrors.push({type:"error",message:"JavaScript Error: "+n,stack:e.error?.stack}),!1===window.SHOW_DEBUG||window._debugVisible||"function"==typeof showDebug&&showDebug(),window._debugVisible&&"function"==typeof debugError&&(debugError("JavaScript Error:",n),e.error?.stack&&debugError("Stack trace:",e.error.stack))}),window.addEventListener("unhandledrejection",function(e){const n=e.reason?.message||e.reason||"Unknown promise rejection";console.error("🚨 Promise rejection caught:",n),window._earlyErrors.push({type:"error",message:"Unhandled Promise Rejection: "+n}),window._debugVisible&&"function"==typeof debugError&&debugError("Unhandled Promise Rejection:",n)})),window.sensorsEnabled=!1,window.micEnabled=!1,window.soundEnabled=!1,window.gesturesLocked=!1,window.vibrationEnabled=!1;let _permissionsInitialized=!1,_micInstance=null;function lockGestures(){window.gesturesLocked||(console.log("🔒 Locking mobile gestures..."),_initializeGestureBlocking(),_initializeP5TouchOverrides(),window.gesturesLocked=!0,console.log("✅ Mobile gestures locked"))}function enableGyroButton(e="ENABLE MOTION SENSORS",n="Requesting motion sensors..."){_createPermissionButton(e,n,async()=>{await _requestMotionPermissions(),console.log("✅ Gyroscope enabled via button")})}function enableGyroTap(e="Tap screen to enable motion sensors"){_createTapToEnable(e,async()=>{await _requestMotionPermissions(),console.log("✅ Gyroscope enabled via tap")})}function enableMicButton(e="ENABLE MICROPHONE",n="Requesting microphone access..."){_createPermissionButton(e,n,async()=>{await _requestMicrophonePermissions(),console.log("✅ Microphone enabled via button")})}function enableMicTap(e="Tap screen to enable microphone"){_createTapToEnable(e,async()=>{await _requestMicrophonePermissions(),console.log("✅ Microphone enabled via tap")})}function enableSoundButton(e="ENABLE SOUND",n="Enabling audio..."){_createPermissionButton(e,n,async()=>{await _requestSoundOutput(),console.log("✅ Sound output enabled via button")})}function enableSoundTap(e="Tap screen to enable sound"){_createTapToEnable(e,async()=>{await _requestSoundOutput(),console.log("✅ Sound output enabled via tap")})}function enableVibrationButton(e="ENABLE VIBRATION",n="Enabling vibration..."){_createPermissionButton(e,n,async()=>{await _requestVibrationPermission(),console.log("✅ Vibration enabled via button")})}function enableVibrationTap(e="Tap screen to enable vibration"){_createTapToEnable(e,async()=>{await _requestVibrationPermission(),console.log("✅ Vibration enabled via tap")})}function enableAllButton(e="ENABLE MOTION & MICROPHONE",n="Requesting permissions..."){_createPermissionButton(e,n,async()=>{await _requestMotionPermissions(),await _requestMicrophonePermissions(),console.log("✅ Motion sensors and microphone enabled via button")})}function enableAllTap(e="Tap screen to enable motion sensors & microphone"){_createTapToEnable(e,async()=>{await _requestMotionPermissions(),await _requestMicrophonePermissions(),console.log("✅ Motion sensors and microphone enabled via tap")})}function vibrate(e){return window.vibrationEnabled?navigator.vibrate?navigator.vibrate(e):(console.warn("⚠️ Vibration API not supported on this device"),!1):(console.warn("⚠️ Vibration not enabled. Call enableVibrationTap() or enableVibrationButton() first."),!1)}function stopVibration(){navigator.vibrate&&navigator.vibrate(0)}async function _requestMotionPermissions(){try{if("undefined"!=typeof DeviceOrientationEvent&&"function"==typeof DeviceOrientationEvent.requestPermission){const e=await DeviceOrientationEvent.requestPermission();if(console.log("Orientation permission:",e),"undefined"!=typeof DeviceMotionEvent&&"function"==typeof DeviceMotionEvent.requestPermission){const e=await DeviceMotionEvent.requestPermission();console.log("Motion permission:",e)}}window.sensorsEnabled=!0,_notifySketchReady()}catch(e){console.error("Motion sensor permission error:",e),_debugVisible&&debugError("Motion sensor permission error:",e),window.sensorsEnabled=!0,_notifySketchReady()}}async function _requestMicrophonePermissions(){try{"undefined"!=typeof userStartAudio&&await userStartAudio(),"undefined"!=typeof mic&&mic&&mic.start?(mic.start(),_micInstance=mic,window.micEnabled=!0):console.warn("No microphone object found. Create one with: mic = new p5.AudioIn();"),_notifySketchReady()}catch(e){console.error("Microphone permission error:",e),_debugVisible&&debugError("Microphone permission error:",e),_notifySketchReady()}}async function _requestSoundOutput(){try{"undefined"!=typeof userStartAudio&&await userStartAudio(),window.soundEnabled=!0,_notifySketchReady()}catch(e){console.error("Sound output error:",e),_debugVisible&&debugError("Sound output error:",e),window.soundEnabled=!0,_notifySketchReady()}}async function _requestVibrationPermission(){try{if(!navigator.vibrate)return console.warn("⚠️ Vibration API not supported on this device (likely iOS)"),_debugVisible&&debugWarn("Vibration API not supported on this device"),window.vibrationEnabled=!1,void _notifySketchReady();navigator.vibrate(1)?(window.vibrationEnabled=!0,console.log("✅ Vibration enabled")):(console.warn("⚠️ Vibration API available but vibration failed"),window.vibrationEnabled=!1),_notifySketchReady()}catch(e){console.error("Vibration permission error:",e),_debugVisible&&debugError("Vibration permission error:",e),window.vibrationEnabled=!1,_notifySketchReady()}}function _notifySketchReady(){"function"==typeof userSetupComplete&&userSetupComplete(),window.dispatchEvent(new CustomEvent("permissionsReady",{detail:{sensors:window.sensorsEnabled,microphone:window.micEnabled,sound:window.soundEnabled,vibration:window.vibrationEnabled,gestures:window.gesturesLocked}}))}function _createPermissionButton(e,n,t){_removeExistingUI();const o=document.createElement("button");o.id="permissionButton",o.textContent=e,o.style.cssText="\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n padding: 20px 40px;\n font-size: 18px;\n font-weight: bold;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n border: none;\n border-radius: 12px;\n cursor: pointer;\n z-index: 999999;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n box-shadow: 0 4px 15px rgba(0,0,0,0.2);\n transition: transform 0.2s ease;\n touch-action: manipulation;\n ";const i=document.createElement("div");i.id="permissionStatus",i.textContent=n,i.style.cssText="\n position: fixed;\n top: 60%;\n left: 50%;\n transform: translate(-50%, 0);\n color: white;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n text-align: center;\n z-index: 999998;\n display: none;\n ",o.addEventListener("mouseenter",()=>{o.style.transform="translate(-50%, -50%) scale(1.05)"}),o.addEventListener("mouseleave",()=>{o.style.transform="translate(-50%, -50%) scale(1)"});const r=async()=>{o.parentNode&&(o.style.display="none",i.style.display="block",await t(),i.style.display="none",_removeExistingUI())};o.addEventListener("click",r),o.addEventListener("touchend",function(e){e.preventDefault(),e.stopPropagation(),r()}),o.addEventListener("pointerup",function(e){e.preventDefault(),e.stopPropagation(),r()}),document.body.appendChild(o),document.body.appendChild(i)}function _createTapToEnable(e,n){_removeExistingUI();const t=document.createElement("div");t.id="tapOverlay",t.style.cssText="\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.8);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 999999;\n cursor: pointer;\n touch-action: manipulation;\n ";const o=document.createElement("div");o.textContent=e,o.style.cssText="\n color: white;\n font-size: 24px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n text-align: center;\n padding: 40px;\n border: 2px solid rgba(255, 255, 255, 0.3);\n border-radius: 12px;\n background: rgba(255, 255, 255, 0.1);\n backdrop-filter: blur(10px);\n ",t.appendChild(o);const i=async()=>{t.parentNode&&(o.textContent="Enabling...",await n(),t.parentNode&&document.body.removeChild(t))};t.addEventListener("click",i),t.addEventListener("touchend",function(e){e.preventDefault(),e.stopPropagation(),i()}),t.addEventListener("pointerup",function(e){e.preventDefault(),e.stopPropagation(),i()}),document.body.appendChild(t)}function _removeExistingUI(){const e=document.getElementById("permissionButton"),n=document.getElementById("permissionStatus"),t=document.getElementById("tapOverlay");e&&e.remove(),n&&n.remove(),t&&t.remove()}function _initializeGestureBlocking(){window.history.pushState(null,"",window.location.href),window.onpopstate=function(){window.history.pushState(null,"",window.location.href)},window.addEventListener("beforeunload",function(e){e.preventDefault(),e.returnValue=""}),_initializeEdgeSwipePrevention(),_initializeOtherGesturePrevention()}function _initializeEdgeSwipePrevention(){let e=0,n=0;document.addEventListener("touchstart",function(t){t.touches&&t.touches.length>0&&(e=t.touches[0].clientX,n=t.touches[0].clientY,(e<20||e>window.innerWidth-20)&&t.preventDefault())},{passive:!1,capture:!0}),document.addEventListener("touchmove",function(t){if(!t.touches||0===t.touches.length)return;let o=t.touches[0].clientX,i=t.touches[0].clientY,r=o-e,a=i-n;(e<20&&r>0||e>window.innerWidth-20&&r<0)&&(t.preventDefault(),t.stopPropagation()),0===window.pageYOffset&&a>0&&t.preventDefault(),!t.target||"CANVAS"!==t.target.tagName||document.getElementById("tapOverlay")||document.getElementById("permissionButton")||t.preventDefault()},{passive:!1,capture:!0})}function _initializeOtherGesturePrevention(){document.addEventListener("gesturestart",function(e){e.preventDefault()}),document.addEventListener("gesturechange",function(e){e.preventDefault()}),document.addEventListener("gestureend",function(e){e.preventDefault()});let e=0;document.addEventListener("touchend",function(n){if(n.target&&("tapOverlay"===n.target.id||n.target.closest("#tapOverlay")||"permissionButton"===n.target.id||"permissionStatus"===n.target.id||n.target.closest("#permissionButton")||n.target.closest("#permissionStatus")))return;const t=Date.now();t-e<=300&&n.preventDefault(),e=t},!1),window.oncontextmenu=function(e){return e.preventDefault(),e.stopPropagation(),!1}}function _initializeP5TouchOverrides(){setTimeout(()=>{if(window._setupDone)_overrideP5Touch();else{const e=setInterval(()=>{window._setupDone&&(_overrideP5Touch(),clearInterval(e))},100)}},100)}function _overrideP5Touch(){const e=window.touchStarted||function(){},n=window.touchMoved||function(){},t=window.touchEnded||function(){},o=window.mousePressed||function(){},i=window.mouseDragged||function(){},r=window.mouseReleased||function(){};window.touchStarted=function(n){return e(n),!1},window.touchMoved=function(e){return n(e),!1},window.touchEnded=function(e){return t(e),!1},window.mousePressed=function(e){return o(e),!1},window.mouseDragged=function(e){return i(e),!1},window.mouseReleased=function(e){return r(e),!1}}document.addEventListener("DOMContentLoaded",function(){const e=document.getElementById("startButton"),n=document.getElementById("statusText");e&&n&&(console.warn("⚠️ Legacy HTML elements detected. Consider using the new API functions instead."),e.addEventListener("click",async()=>{e.classList.add("hidden"),n.classList.remove("hidden"),n.textContent="Requesting permissions...",await _requestMotionPermissions(),await _requestMicrophonePermissions(),n.classList.add("hidden")}),lockGestures())});let _debugPanel=null,_debugVisible=!1,_debugMessages=[];const MAX_DEBUG_MESSAGES=20;function showDebug(){_createDebugPanel(),_debugPanel.style.display="block",_debugVisible=!0,window._debugVisible=!0,_setupConsoleOverrides(),_displayEarlyErrors()}function hideDebug(){_debugPanel&&(_debugPanel.style.display="none",_debugVisible=!1)}function toggleDebug(){_debugVisible?hideDebug():showDebug()}function debug(...e){console.log(...e);_addDebugMessage(e.map(e=>{if("object"==typeof e&&null!==e)try{return JSON.stringify(e,null,2)}catch(n){return String(e)}return String(e)}).join(" "),"log")}function debugError(...e){(window._originalConsoleError||console.error).apply(console,e);_addDebugMessage(`❌ ERROR: ${e.map(e=>{if("object"==typeof e&&null!==e)try{return JSON.stringify(e,null,2)}catch(n){return String(e)}return String(e)}).join(" ")}`,"error")}function debugWarn(...e){(window._originalConsoleWarn||console.warn).apply(console,e);_addDebugMessage(`⚠️ WARNING: ${e.map(e=>{if("object"==typeof e&&null!==e)try{return JSON.stringify(e,null,2)}catch(n){return String(e)}return String(e)}).join(" ")}`,"warning")}function _addDebugMessage(e,n="log"){const t={text:`[${(new Date).toLocaleTimeString("en-US",{hour12:!1,hour:"2-digit",minute:"2-digit",second:"2-digit",fractionalSecondDigits:3})}] ${e}`,type:n};_debugMessages.push(t),_debugMessages.length>20&&_debugMessages.shift(),_debugPanel&&_updateDebugDisplay()}function _setupConsoleOverrides(){window._consoleOverrideSet||(window._consoleOverrideSet=!0,window._originalConsoleError=console.error,window._originalConsoleWarn=console.warn,console.error=function(...e){window._originalConsoleError.apply(console,e),_debugVisible&&debugError(...e)},console.warn=function(...e){window._originalConsoleWarn.apply(console,e),_debugVisible&&debugWarn(...e)})}function _displayEarlyErrors(){window._earlyErrors&&window._earlyErrors.length>0&&(debugError(`🚨 Found ${window._earlyErrors.length} early error(s):`),window._earlyErrors.forEach(e=>{debugError(e.message),e.stack&&debugError("Stack trace:",e.stack)}),window._earlyErrors=[])}function _createDebugPanel(){if(_debugPanel)return;_debugPanel=document.createElement("div"),_debugPanel.id="mobile-debug-panel",_debugPanel.innerHTML='\n <div id="mobile-debug-header">\n <span>Debug</span>\n <button id="mobile-debug-close">×</button>\n </div>\n <div id="mobile-debug-content"></div>\n ';const e=document.createElement("style");e.textContent="\n #mobile-debug-panel {\n position: fixed;\n top: 20px;\n right: 20px;\n width: 350px;\n max-width: calc(100vw - 40px);\n max-height: 400px;\n background: rgba(0, 0, 0, 0.9);\n color: #ffffff;\n font-family: 'Courier New', monospace;\n font-size: 12px;\n border-radius: 8px;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);\n z-index: 10000;\n display: none;\n }\n \n #mobile-debug-header {\n background: rgba(255, 255, 255, 0.1);\n padding: 8px 12px;\n border-bottom: 1px solid rgba(255, 255, 255, 0.2);\n display: flex;\n justify-content: space-between;\n align-items: center;\n border-radius: 8px 8px 0 0;\n }\n \n #mobile-debug-header span {\n font-weight: bold;\n font-size: 13px;\n }\n \n #mobile-debug-close {\n background: none;\n border: none;\n color: #ffffff;\n font-size: 18px;\n cursor: pointer;\n padding: 0;\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n \n #mobile-debug-close:hover {\n background: rgba(255, 255, 255, 0.1);\n border-radius: 4px;\n }\n \n #mobile-debug-content {\n padding: 12px;\n max-height: 340px;\n overflow-y: auto;\n word-wrap: break-word;\n line-height: 1.4;\n }\n \n .debug-message {\n margin-bottom: 4px;\n white-space: pre-wrap;\n }\n \n .debug-message.error {\n color: #ff6b6b;\n background: rgba(255, 107, 107, 0.1);\n padding: 4px;\n border-radius: 3px;\n border-left: 3px solid #ff6b6b;\n }\n \n .debug-message.warning {\n color: #ffd93d;\n background: rgba(255, 217, 61, 0.1);\n padding: 4px;\n border-radius: 3px;\n border-left: 3px solid #ffd93d;\n }\n \n .debug-timestamp {\n color: #888;\n font-size: 10px;\n }\n \n @media (max-width: 480px) {\n #mobile-debug-panel {\n width: calc(100vw - 20px);\n right: 10px;\n top: 10px;\n }\n }\n ",document.head.appendChild(e),document.body.appendChild(_debugPanel),document.getElementById("mobile-debug-close").onclick=hideDebug,_updateDebugDisplay()}function _updateDebugDisplay(){if(!_debugPanel)return;const e=document.getElementById("mobile-debug-content");e&&(e.innerHTML=_debugMessages.map(e=>"string"==typeof e?`<div class="debug-message">${e}</div>`:`<div class="debug-message ${e.type}">${e.text}</div>`).join(""),e.scrollTop=e.scrollHeight)}debug.clear=function(){_debugMessages=[],_debugPanel&&_updateDebugDisplay(),console.clear()},window.debug=debug,window.debugError=debugError,window.debugWarn=debugWarn,window.showDebug=showDebug,window.hideDebug=hideDebug,window.toggleDebug=toggleDebug,window.lockGestures=lockGestures,window.enableGyroTap=enableGyroTap,window.enableGyroButton=enableGyroButton,window.enableMicTap=enableMicTap,window.enableMicButton=enableMicButton,window.enableSoundTap=enableSoundTap,window.enableSoundButton=enableSoundButton,window.enableVibrationTap=enableVibrationTap,window.enableVibrationButton=enableVibrationButton,window.vibrate=vibrate,window.stopVibration=stopVibration,window.enableAllTap=enableAllTap,window.enableAllButton=enableAllButton;class PhoneCamera{constructor(e="user",n=!0,t="fitHeight"){this._active=e,this._mirror=n,this._mode=t,this._fixedWidth=640,this._fixedHeight=480,this._video=null,this._ready=!1,this._p5Instance=window,this._onReadyCallback=null,this._createCaptureRef=null,window._phoneCameras||(window._phoneCameras=[]),window._phoneCameras.push(this)}get ready(){return this._ready}get video(){return this._video}get videoElement(){return this._video?this._video.elt:null}get width(){if(!this._ready)return 0;return this.getDimensions().width}get height(){if(!this._ready)return 0;return this.getDimensions().height}get active(){return this._active}set active(e){"user"===e||"environment"===e?this._active!==e&&(this._active=e,this._ready&&this._switchCamera()):console.error('PhoneCamera: active must be "user" or "environment"')}get mirror(){return this._mirror}set mirror(e){this._mirror=!!e}get mode(){return this._mode}set mode(e){const n=["fitWidth","fitHeight","cover","contain","fixed"];n.includes(e)?this._mode=e:console.error("PhoneCamera: mode must be one of:",n.join(", "))}get fixedWidth(){return this._fixedWidth}set fixedWidth(e){this._fixedWidth=Math.max(1,e)}get fixedHeight(){return this._fixedHeight}set fixedHeight(e){this._fixedHeight=Math.max(1,e)}onReady(e){this._onReadyCallback=e,this._ready&&this._video&&this._video.elt&&this._video.elt.readyState>=2?e():this._video&&this._checkVideoReady()}_initializeCamera(){if(this._ready||this._video)return;const e={video:{facingMode:this._active},audio:!1};this._video=createCapture(e,()=>{this._ready=!0,this._video.hide(),console.log("✅ PhoneCamera ready"),this._checkVideoReady()}),this._video&&this._video.elt&&this._video.elt.addEventListener("loadeddata",()=>{this._ready=!0,this._checkVideoReady()})}_checkVideoReady(){if(this._video&&this._video.elt&&this._video.elt.readyState>=2){if(this._onReadyCallback){const e=this._onReadyCallback;this._onReadyCallback=null,e()}}else setTimeout(()=>this._checkVideoReady(),100)}_switchCamera(){if(!this._video)return;this._ready;this._ready=!1,this._video.remove();const e={video:{facingMode:this._active},audio:!1};this._video=createCapture(e,()=>{this._ready=!0,this._video.hide(),console.log(`✅ PhoneCamera switched to ${this._active} camera`)}),this._video&&this._video.elt&&this._video.elt.addEventListener("loadeddata",()=>{this._ready=!0})}remove(){this._video&&(this._video.remove(),this._video=null),this._ready=!1}getDimensions(){if(!this._ready||!this._video)return{x:0,y:0,width:0,height:0,scaleX:1,scaleY:1};const e=this._video.width,n=this._video.height,t="undefined"!=typeof width?width:window.innerWidth,o="undefined"!=typeof height?height:window.innerHeight;let i,r,a,s;if("fixed"===this._mode)i=this._fixedWidth,r=this._fixedHeight,a=(t-i)/2,s=(o-r)/2;else if("fitWidth"===this._mode)i=t,r=n/e*i,a=0,s=(o-r)/2;else if("fitHeight"===this._mode)r=o,i=e/n*r,a=(t-i)/2,s=0;else if("cover"===this._mode){const d=Math.max(t/e,o/n);i=e*d,r=n*d,a=(t-i)/2,s=(o-r)/2}else if("contain"===this._mode){const d=Math.min(t/e,o/n);i=e*d,r=n*d,a=(t-i)/2,s=(o-r)/2}return{x:a,y:s,width:i,height:r,scaleX:i/e,scaleY:r/n}}mapPoint(e,n){const t=this.getDimensions();let o=e*t.scaleX;const i=n*t.scaleY;this._mirror&&(o=t.width-o);return{x:o+t.x,y:i+t.y}}mapKeypoint(e){if(!e||void 0===e.x||void 0===e.y)return console.warn("PhoneCamera.mapKeypoint: invalid keypoint",e),e;const n=this.mapPoint(e.x,e.y);return{...e,x:n.x,y:n.y}}mapKeypoints(e){return Array.isArray(e)?e.map(e=>this.mapKeypoint(e)):(console.warn("PhoneCamera.mapKeypoints: expected array, got",typeof e),e)}_draw(){if(!this._ready||!this._video)return;const e=this.getDimensions(),n="undefined"!=typeof width?width:window.innerWidth;this._drawDebugLogged||(console.log("_draw() params:",{x:e.x,y:e.y,width:e.width,height:e.height,canvasWidth:n,mirror:this._mirror}),this._drawDebugLogged=!0),push(),this._mirror?(translate(n,0),scale(-1,1),image(this._video,e.x,e.y,e.width,e.height)):image(this._video,e.x,e.y,e.width,e.height),pop()}}function createPhoneCamera(e="user",n=!0,t="fitHeight"){return new PhoneCamera(e,n,t)}function enableCameraButton(e="ENABLE CAMERA",n="Starting camera..."){_createPermissionButton(e,n,async()=>{await _requestCameraPermission(),console.log("✅ Camera enabled via button")})}function enableCameraTap(e="Tap screen to enable camera"){navigator.permissions&&navigator.permissions.query?navigator.permissions.query({name:"camera"}).then(n=>{"granted"===n.state?(console.log("✅ Camera permission already granted - auto-starting"),_requestCameraPermission()):_createTapToEnable(e,async()=>{await _requestCameraPermission(),console.log("✅ Camera enabled via tap")})}).catch(()=>{_createTapToEnable(e,async()=>{await _requestCameraPermission(),console.log("✅ Camera enabled via tap")})}):_createTapToEnable(e,async()=>{await _requestCameraPermission(),console.log("✅ Camera enabled via tap")})}async function _requestCameraPermission(){try{if(void 0!==window._phoneCameras&&Array.isArray(window._phoneCameras))for(let e of window._phoneCameras)!e||e._ready||e._video||e._initializeCamera();"function"==typeof userCameraReady&&userCameraReady(),_notifySketchReady()}catch(e){console.error("Camera permission error:",e),_debugVisible&&debugError("Camera permission error:",e),_notifySketchReady()}}if(window.createPhoneCamera=createPhoneCamera,window.enableCameraButton=enableCameraButton,window.enableCameraTap=enableCameraTap,"undefined"!=typeof p5&&p5.prototype){const e=p5.prototype.image;p5.prototype.image=function(...n){if(n[0]instanceof PhoneCamera){n[0]._draw()}else e.apply(this,n)}}"undefined"!=typeof p5&&p5.prototype&&(p5.prototype.lockGestures=lockGestures,p5.prototype.enableGyroTap=enableGyroTap,p5.prototype.enableGyroButton=enableGyroButton,p5.prototype.enableMicTap=enableMicTap,p5.prototype.enableMicButton=enableMicButton,p5.prototype.enableSoundTap=enableSoundTap,p5.prototype.enableSoundButton=enableSoundButton,p5.prototype.enableVibrationTap=enableVibrationTap,p5.prototype.enableVibrationButton=enableVibrationButton,p5.prototype.vibrate=vibrate,p5.prototype.stopVibration=stopVibration,p5.prototype.enableAllTap=enableAllTap,p5.prototype.enableAllButton=enableAllButton,p5.prototype.createPhoneCamera=createPhoneCamera,p5.prototype.enableCameraButton=enableCameraButton,p5.prototype.enableCameraTap=enableCameraTap,p5.prototype.showDebug=showDebug,p5.prototype.hideDebug=hideDebug,p5.prototype.toggleDebug=toggleDebug,p5.prototype.debug=debug,p5.prototype.debugError=debugError,p5.prototype.debugWarn=debugWarn,console.log("✅ Mobile p5.js Permissions: p5.prototype functions registered"));
@@ -4,7 +4,7 @@
4
4
  <title>P5.js Mobile - Microphone Level</title>
5
5
  <script src="https://cdn.jsdelivr.net/npm/p5@1.11.10/lib/p5.min.js"></script>
6
6
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.0/addons/p5.sound.min.js"></script>
7
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
7
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
8
8
  <style>
9
9
  body {
10
10
  margin: 0;
@@ -18,7 +18,7 @@
18
18
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.10/p5.js"></script>
19
19
 
20
20
  <!-- Load the mobile p5.js permissions library -->
21
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.js"></script>
21
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.js"></script>
22
22
 
23
23
  </head>
24
24
  <body>
@@ -18,7 +18,7 @@
18
18
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.10/p5.js"></script>
19
19
 
20
20
  <!-- Load the mobile p5.js permissions library -->
21
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.js"></script>
21
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.js"></script>
22
22
 
23
23
  </head>
24
24
  <body>
@@ -18,7 +18,7 @@
18
18
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.10/p5.js"></script>
19
19
 
20
20
  <!-- Load the mobile p5.js permissions library -->
21
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.js"></script>
21
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.js"></script>
22
22
 
23
23
  </head>
24
24
  <body>
@@ -21,7 +21,7 @@
21
21
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.10/addons/p5.sound.min.js"></script>
22
22
 
23
23
  <!-- Load the mobile p5.js permissions library -->
24
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
24
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
25
25
 
26
26
  </head>
27
27
  <body>
@@ -21,7 +21,7 @@
21
21
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.10/addons/p5.sound.min.js"></script>
22
22
 
23
23
  <!-- Load the mobile p5.js permissions library -->
24
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
24
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
25
25
 
26
26
  </head>
27
27
  <body>
@@ -18,7 +18,7 @@
18
18
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.10/p5.min.js"></script>
19
19
 
20
20
  <!-- Load the mobile p5.js permissions library -->
21
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
21
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
22
22
 
23
23
  </head>
24
24
  <body>
@@ -18,7 +18,7 @@
18
18
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.10/p5.min.js"></script>
19
19
 
20
20
  <!-- Load the mobile p5.js permissions library -->
21
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
21
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
22
22
 
23
23
  </head>
24
24
  <body>
@@ -18,7 +18,7 @@
18
18
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.10/p5.min.js"></script>
19
19
 
20
20
  <!-- Load the mobile p5.js permissions library -->
21
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
21
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
22
22
 
23
23
  </head>
24
24
  <body>
@@ -18,7 +18,7 @@
18
18
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.10/p5.min.js"></script>
19
19
 
20
20
  <!-- Load the mobile p5.js permissions library -->
21
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
21
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
22
22
 
23
23
  </head>
24
24
  <body>
@@ -18,7 +18,7 @@
18
18
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.10/p5.min.js"></script>
19
19
 
20
20
  <!-- Load the mobile p5.js permissions library -->
21
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
21
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
22
22
 
23
23
  </head>
24
24
  <body>
@@ -18,7 +18,7 @@
18
18
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.10/p5.min.js"></script>
19
19
 
20
20
  <!-- Load the mobile p5.js permissions library -->
21
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
21
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
22
22
 
23
23
  </head>
24
24
  <body>
@@ -4,7 +4,7 @@
4
4
  <title>P5.js Mobile - Mic Level (Minimal)</title>
5
5
  <script src="https://cdn.jsdelivr.net/npm/p5@1.11.0/lib/p5.min.js"></script>
6
6
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.0/addons/p5.sound.min.js"></script>
7
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
7
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
8
8
  <style>
9
9
  body {
10
10
  margin: 0;
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <title>P5.js Mobile - Orientation Basic (Minimal)</title>
5
5
  <script src="https://cdn.jsdelivr.net/npm/p5@1.11.0/lib/p5.min.js"></script>
6
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
6
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
7
7
  <style>
8
8
  body {
9
9
  margin: 0;
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <title>P5.js Mobile - Rotational Velocity (Minimal)</title>
5
5
  <script src="https://cdn.jsdelivr.net/npm/p5@1.11.0/lib/p5.min.js"></script>
6
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
6
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
7
7
  <style>
8
8
  body {
9
9
  margin: 0;
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <title>P5.js Mobile - Acceleration (Minimal)</title>
5
5
  <script src="https://cdn.jsdelivr.net/npm/p5@1.11.0/lib/p5.min.js"></script>
6
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
6
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
7
7
  <style>
8
8
  body {
9
9
  margin: 0;
@@ -4,7 +4,7 @@
4
4
  <title>P5.js Mobile - Sound Basic (Minimal)</title>
5
5
  <script src="https://cdn.jsdelivr.net/npm/p5@1.11.0/lib/p5.min.js"></script>
6
6
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.0/addons/p5.sound.min.js"></script>
7
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
7
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
8
8
  <style>
9
9
  body {
10
10
  margin: 0;
@@ -4,7 +4,7 @@
4
4
  <title>P5.js Mobile - Sound Amplitude (Minimal)</title>
5
5
  <script src="https://cdn.jsdelivr.net/npm/p5@1.11.0/lib/p5.min.js"></script>
6
6
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.0/addons/p5.sound.min.js"></script>
7
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
7
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
8
8
  <style>
9
9
  body {
10
10
  margin: 0;
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <title>P5.js Mobile - Touch Basic (Minimal)</title>
5
5
  <script src="https://cdn.jsdelivr.net/npm/p5@1.11.0/lib/p5.min.js"></script>
6
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
6
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
7
7
  <style>
8
8
  body {
9
9
  margin: 0;
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <title>P5.js Mobile - Touch Zones (Minimal)</title>
5
5
  <script src="https://cdn.jsdelivr.net/npm/p5@1.11.0/lib/p5.min.js"></script>
6
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
6
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
7
7
  <style>
8
8
  body {
9
9
  margin: 0;
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <title>P5.js Mobile - Touch Count (Minimal)</title>
5
5
  <script src="https://cdn.jsdelivr.net/npm/p5@1.11.0/lib/p5.min.js"></script>
6
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
6
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
7
7
  <style>
8
8
  body {
9
9
  margin: 0;
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <title>P5.js Mobile - Touch Distance (Minimal)</title>
5
5
  <script src="https://cdn.jsdelivr.net/npm/p5@1.11.0/lib/p5.min.js"></script>
6
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
6
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
7
7
  <style>
8
8
  body {
9
9
  margin: 0;
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <title>P5.js Mobile - Touch Angle (Minimal)</title>
5
5
  <script src="https://cdn.jsdelivr.net/npm/p5@1.11.0/lib/p5.min.js"></script>
6
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
6
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
7
7
  <style>
8
8
  body {
9
9
  margin: 0;
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <title>P5.js Mobile - Vibration Haptic Feedback (Minimal)</title>
5
5
  <script src="https://cdn.jsdelivr.net/npm/p5@1.11.0/lib/p5.min.js"></script>
6
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
6
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
7
7
  <style>
8
8
  body {
9
9
  margin: 0;
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <title>P5.js Mobile - Touch Collision with GIF</title>
5
5
  <script src="https://cdn.jsdelivr.net/npm/p5@1.11.0/lib/p5.min.js"></script>
6
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
6
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
7
7
  <script src="https://cdn.jsdelivr.net/gh/bmoren/p5.collide2D/p5.collide2d.min.js"></script>
8
8
  <style>
9
9
  body {
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <title>P5.js Mobile - Touch with GIF</title>
5
5
  <script src="https://cdn.jsdelivr.net/npm/p5@1.11.0/lib/p5.min.js"></script>
6
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
6
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
7
7
  <style>
8
8
  body {
9
9
  margin: 0;
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <title>P5.js Mobile - Fly Control</title>
5
5
  <script src="https://cdn.jsdelivr.net/npm/p5@1.11.0/lib/p5.min.js"></script>
6
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
6
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
7
7
  <style>
8
8
  body {
9
9
  margin: 0;
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <title>P5.js Mobile - Roll Control</title>
5
5
  <script src="https://cdn.jsdelivr.net/npm/p5@1.11.0/lib/p5.min.js"></script>
6
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
6
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
7
7
  <style>
8
8
  body {
9
9
  margin: 0;
@@ -37,7 +37,7 @@
37
37
  </style>
38
38
 
39
39
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.min.js"></script>
40
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
40
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
41
41
  </head>
42
42
  <body>
43
43
  <script src="sketch.js"></script>
@@ -19,7 +19,7 @@
19
19
  </head>
20
20
  <body>
21
21
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.min.js"></script>
22
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
22
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
23
23
  <script src="sketch.js"></script>
24
24
  </body>
25
25
  </html>
@@ -37,7 +37,7 @@
37
37
  </style>
38
38
 
39
39
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.min.js"></script>
40
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
40
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
41
41
  </head>
42
42
  <body>
43
43
  <script src="sketch.js"></script>
@@ -67,7 +67,7 @@
67
67
  </style>
68
68
 
69
69
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.min.js"></script>
70
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
70
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
71
71
  </head>
72
72
  <body>
73
73
  <button id="startButton">START GAME</button>
@@ -68,7 +68,7 @@
68
68
 
69
69
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.min.js"></script>
70
70
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/addons/p5.sound.min.js"></script>
71
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
71
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
72
72
  </head>
73
73
  <body>
74
74
  <button id="startButton">START VISUALIZER</button>
@@ -19,7 +19,7 @@
19
19
  </head>
20
20
  <body>
21
21
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.min.js"></script>
22
- <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.5.0/dist/p5-phone.min.js"></script>
22
+ <script src="https://cdn.jsdelivr.net/npm/p5-phone@1.6.2/dist/p5-phone.min.js"></script>
23
23
  <script src="sketch.js"></script>
24
24
  </body>
25
25
  </html>