@zappar/zappar-cv 2.0.0 → 2.0.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.0.2] - 2023-05-04
4
+
5
+ ### Fixed
6
+
7
+ - Unique user calculation when using the Zapworks built-in analytics system
8
+
9
+ ## [2.0.1] - 2023-03-24
10
+
11
+ ### Fixed
12
+
13
+ - Workaround for bug in iOS Safari 16.4 that selects the wrong rear-facing camera on some devices
14
+
3
15
  ## [2.0.0] - 2022-08-23
4
16
 
5
17
  ### Added
package/README.md CHANGED
@@ -18,8 +18,8 @@ npm i @zappar/zappar-cv
18
18
 
19
19
  You can use our CDN from within your HTML:
20
20
  ```
21
- <script src="https://libs.zappar.com/zappar-cv/2.0.0/zappar-cv.js"></script>
21
+ <script src="https://libs.zappar.com/zappar-cv/2.0.2/zappar-cv.js"></script>
22
22
  ```
23
23
 
24
24
  Or you can download and host our standalone JavaScript bundle:
25
- [https://libs.zappar.com/zappar-cv/2.0.0/zappar-cv.zip](https://libs.zappar.com/zappar-cv/2.0.0/zappar-cv.zip)
25
+ [https://libs.zappar.com/zappar-cv/2.0.2/zappar-cv.zip](https://libs.zappar.com/zappar-cv/2.0.2/zappar-cv.zip)
@@ -23,4 +23,5 @@ export interface Additional {
23
23
  browser_incompatible: () => boolean;
24
24
  browser_incompatible_ui: () => void;
25
25
  sequence_source_time_set: (o: zappar_sequence_source_t, ms: number) => void;
26
+ cookies_permitted: (p: boolean) => void;
26
27
  }
@@ -7,6 +7,8 @@ export declare class CameraSource extends HTMLElementSource {
7
7
  static DEFAULT_DEVICE_ID: string;
8
8
  private _currentStream;
9
9
  private _activeDeviceId;
10
+ private _explicitUserCameraId;
11
+ private _explicitEnvironmentCameraId;
10
12
  constructor(_impl: zappar_camera_source_t, pipeline: zappar_pipeline_t, _deviceId: string);
11
13
  destroy(): void;
12
14
  private _stop;
@@ -84,6 +84,20 @@ export class CameraSource extends HTMLElementSource {
84
84
  }
85
85
  else {
86
86
  facingMode = (this._deviceId === CameraSource.DEFAULT_DEVICE_ID) ? "environment" : "user";
87
+ if (profile.ios164CameraSelection) {
88
+ if (!this._explicitEnvironmentCameraId || !this._explicitUserCameraId) {
89
+ const stream = yield navigator.mediaDevices.getUserMedia({ audio: false, video: { facingMode } });
90
+ let tracks = stream.getTracks();
91
+ tracks.forEach(t => t.stop());
92
+ let devices = yield navigator.mediaDevices.enumerateDevices();
93
+ devices = devices.filter(val => val.kind === 'videoinput');
94
+ if (devices.length >= 2) {
95
+ this._explicitUserCameraId = devices[0].deviceId;
96
+ this._explicitEnvironmentCameraId = devices[1].deviceId;
97
+ }
98
+ }
99
+ deviceId = (facingMode === 'environment') ? this._explicitEnvironmentCameraId : this._explicitUserCameraId;
100
+ }
87
101
  }
88
102
  let constraints = {
89
103
  audio: false,
@@ -29,9 +29,10 @@ export class zappar_client {
29
29
  m.logLevel(level);
30
30
  });
31
31
  },
32
- analytics_project_id_set: (id) => {
32
+ analytics_project_id_set: (id, uid) => {
33
33
  this.serializer.sendMessage(31, m => {
34
34
  m.string(id);
35
+ m.string(uid);
35
36
  });
36
37
  },
37
38
  // #### pipeline ####
@@ -4,7 +4,7 @@ export function getRuntimeObject(mod) {
4
4
  "number"
5
5
  ]);
6
6
  let analytics_project_id_set_wrapped = mod.cwrap("zappar_analytics_project_id_set", null, [
7
- "string"
7
+ "string", "string"
8
8
  ]);
9
9
  let pipeline_create_wrapped = mod.cwrap("zappar_pipeline_create", "number", []);
10
10
  let pipeline_destroy_wrapped = mod.cwrap("zappar_pipeline_destroy", null, ["number"]);
@@ -195,9 +195,10 @@ export function getRuntimeObject(mod) {
195
195
  let ret = log_level_set_wrapped(arg_level);
196
196
  return ret;
197
197
  },
198
- analytics_project_id_set: (id) => {
198
+ analytics_project_id_set: (id, uid) => {
199
199
  let arg_id = id;
200
- let ret = analytics_project_id_set_wrapped(arg_id);
200
+ let arg_uid = uid;
201
+ let ret = analytics_project_id_set_wrapped(arg_id, arg_uid);
201
202
  return ret;
202
203
  },
203
204
  pipeline_create: () => {
@@ -91,7 +91,7 @@ export declare type zappar_instant_world_tracker_t = number & {
91
91
  export interface zappar_cwrap {
92
92
  log_level(): log_level_t;
93
93
  log_level_set(level: log_level_t): void;
94
- analytics_project_id_set(id: string): void;
94
+ analytics_project_id_set(id: string, uid: string): void;
95
95
  pipeline_create(): zappar_pipeline_t;
96
96
  pipeline_destroy(o: zappar_pipeline_t): void;
97
97
  pipeline_frame_update(o: zappar_pipeline_t): void;
@@ -34,7 +34,7 @@ export class zappar_server {
34
34
  break;
35
35
  }
36
36
  case 31: {
37
- this._impl.analytics_project_id_set(msg.string());
37
+ this._impl.analytics_project_id_set(msg.string(), msg.string());
38
38
  break;
39
39
  }
40
40
  case 27: {
@@ -58,7 +58,7 @@ export interface zappar {
58
58
  permission_denied_any(): boolean;
59
59
  permission_denied_camera(): boolean;
60
60
  permission_denied_motion(): boolean;
61
- analytics_project_id_set(id: string): void;
61
+ analytics_project_id_set(id: string, uid: string): void;
62
62
  pipeline_create(): zappar_pipeline_t;
63
63
  pipeline_destroy(o: zappar_pipeline_t): void;
64
64
  pipeline_camera_frame_upload_gl(o: zappar_pipeline_t): void;
@@ -48,6 +48,11 @@ function cylindrical(info) {
48
48
  }
49
49
  function conical(info) {
50
50
  const radius_diff = info.topRadius - info.bottomRadius;
51
+ // Prevents divide by zero errors.
52
+ if (radius_diff === 0) {
53
+ console.warn("Conical target has matching radii, using cylindrical preview mesh with a defined image size instead.");
54
+ return cylindrical(info);
55
+ }
51
56
  const height_3d = Math.sqrt(info.sideLength * info.sideLength - radius_diff * radius_diff);
52
57
  const flip = info.bottomRadius > info.topRadius;
53
58
  let aspect_ratio = info.trainedWidth / info.trainedHeight;
package/lib/native.js CHANGED
@@ -40,10 +40,12 @@ export function initialize(opts) {
40
40
  d: ab
41
41
  }, [ab]);
42
42
  });
43
+ const uid = getUID();
44
+ let hasPersistedUID = false;
43
45
  if (window.location.hostname.toLowerCase().indexOf(".zappar.io") > 0 || window.location.hostname.toLowerCase().indexOf(".webar.run") > 0) {
44
46
  let pathParts = window.location.pathname.split("/");
45
47
  if (pathParts.length > 1 && pathParts[1].length > 0)
46
- c.impl.analytics_project_id_set(".wiz" + pathParts[1]);
48
+ c.impl.analytics_project_id_set(".wiz" + pathParts[1], uid);
47
49
  }
48
50
  messageManager.onIncomingMessage.bind(msg => {
49
51
  var _a, _b, _c, _d, _e, _f, _g;
@@ -479,6 +481,16 @@ export function initialize(opts) {
479
481
  }, html_element_source_create: (pipeline, elm) => HTMLElementSource.createVideoElementSource(pipeline, elm), html_element_source_start: o => { var _a; return (_a = HTMLElementSource.getVideoElementSource(o)) === null || _a === void 0 ? void 0 : _a.start(); }, html_element_source_pause: o => { var _a; return (_a = HTMLElementSource.getVideoElementSource(o)) === null || _a === void 0 ? void 0 : _a.pause(); }, html_element_source_destroy: o => { var _a; return (_a = HTMLElementSource.getVideoElementSource(o)) === null || _a === void 0 ? void 0 : _a.destroy(); }, sequence_source_create: p => SequenceSource.create(p), sequence_source_load_from_memory: (o, data) => { var _a; return (_a = SequenceSource.get(o)) === null || _a === void 0 ? void 0 : _a.loadFromMemory(data); }, sequence_source_pause: o => { var _a; return (_a = SequenceSource.get(o)) === null || _a === void 0 ? void 0 : _a.pause(); }, sequence_source_start: o => { var _a; return (_a = SequenceSource.get(o)) === null || _a === void 0 ? void 0 : _a.start(); }, sequence_source_max_playback_fps_set: (o, fps) => { var _a; return (_a = SequenceSource.get(o)) === null || _a === void 0 ? void 0 : _a.maxPlaybackFpsSet(fps); }, sequence_source_time_set: (o, t) => { var _a; return (_a = SequenceSource.get(o)) === null || _a === void 0 ? void 0 : _a.setTime(t); }, sequence_source_destroy: o => { var _a; return (_a = SequenceSource.get(o)) === null || _a === void 0 ? void 0 : _a.destroy(); }, permission_granted_all: permissionGrantedAll, permission_granted_camera: permissionGrantedCamera, permission_granted_motion: permissionGrantedMotion, permission_denied_any: permissionDeniedAny, permission_denied_camera: permissionDeniedCamera, permission_denied_motion: permissionDeniedMotion, permission_request_motion: permissionRequestMotion, permission_request_camera: permissionRequestCamera, permission_request_all: permissionRequestAll, permission_request_ui: permissionRequestUI, permission_request_ui_promise: permissionRequestUI, permission_denied_ui: permissionDeniedUI, browser_incompatible: compatibility.incompatible, browser_incompatible_ui: compatibility.incompatible_ui, log_level_set: l => {
480
482
  setLogLevel(l);
481
483
  c.impl.log_level_set(l);
484
+ }, cookies_permitted: p => {
485
+ if (p) {
486
+ if (!hasPersistedUID) {
487
+ persistUID(uid);
488
+ hasPersistedUID = true;
489
+ }
490
+ }
491
+ else {
492
+ deleteUID();
493
+ }
482
494
  } });
483
495
  return client;
484
496
  }
@@ -490,3 +502,25 @@ function loadDefaultFaceModel(o) {
490
502
  client === null || client === void 0 ? void 0 : client.face_tracker_model_load_from_memory(o, ab);
491
503
  });
492
504
  }
505
+ function getUID() {
506
+ let uid = window.localStorage.getItem('z_uar_lid');
507
+ if (uid === null) {
508
+ const destination = new Uint8Array(8);
509
+ window.crypto.getRandomValues(destination);
510
+ uid = '';
511
+ for (let i = 0; i < destination.byteLength; i++) {
512
+ const part = destination[i].toString(16);
513
+ if (part.length === 1)
514
+ uid += '0' + part;
515
+ else if (part.length === 2)
516
+ uid += part;
517
+ }
518
+ }
519
+ return uid;
520
+ }
521
+ function persistUID(u) {
522
+ window.localStorage.setItem('z_uar_lid', u);
523
+ }
524
+ function deleteUID() {
525
+ window.localStorage.removeItem('z_uar_lid');
526
+ }
package/lib/permission.js CHANGED
@@ -8,6 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { UAParser } from "ua-parser-js";
11
+ import { STRINGS, tr } from "./tr";
11
12
  let parser = new UAParser();
12
13
  let _permissionGrantedCamera = false;
13
14
  let _permissionGrantedMotion = false;
@@ -120,9 +121,9 @@ export function permissionRequestUI() {
120
121
  }
121
122
  </style>
122
123
  <div class="zappar-inner">
123
- <div class="zappar-title">Almost there...</div>
124
- <div class="zappar-text">In order to provide this augmented reality experience, we need access to your device's camera and motion sensors.</div>
125
- <button id="zappar-permission-request-button">Grant Access</button>
124
+ <div class="zappar-title">${tr(STRINGS.PermissionTitle)}</div>
125
+ <div class="zappar-text">${tr(STRINGS.PermissionDescription)}</div>
126
+ <button id="zappar-permission-request-button">${tr(STRINGS.PermissionButton)}</button>
126
127
  </div>
127
128
  `;
128
129
  document.body.append(div);
package/lib/profile.d.ts CHANGED
@@ -15,4 +15,5 @@ export declare let profile: {
15
15
  videoElementInDOM: boolean;
16
16
  preferMediaStreamTrackProcessorCamera: boolean;
17
17
  preferImageBitmapCamera: boolean;
18
+ ios164CameraSelection: boolean;
18
19
  };
package/lib/profile.js CHANGED
@@ -16,7 +16,8 @@ export let profile = {
16
16
  dataHeight: 240,
17
17
  videoElementInDOM: false,
18
18
  preferMediaStreamTrackProcessorCamera: false,
19
- preferImageBitmapCamera: false
19
+ preferImageBitmapCamera: false,
20
+ ios164CameraSelection: false
20
21
  };
21
22
  if (typeof window !== "undefined") {
22
23
  window["zeeProfile"] = profile;
@@ -74,5 +75,8 @@ function iDevice(version) {
74
75
  profile.dataHeight = 180;
75
76
  }
76
77
  }
78
+ if ((majorVersion === 16 && minorVersion >= 4) || (majorVersion > 16)) {
79
+ profile.ios164CameraSelection = true;
80
+ }
77
81
  }
78
82
  }
package/lib/tr.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export declare enum STRINGS {
2
+ PermissionTitle = 0,
3
+ PermissionDescription = 1,
4
+ PermissionButton = 2
5
+ }
6
+ export declare function tr(str: STRINGS): string;
package/lib/tr.js ADDED
@@ -0,0 +1,42 @@
1
+ export var STRINGS;
2
+ (function (STRINGS) {
3
+ STRINGS[STRINGS["PermissionTitle"] = 0] = "PermissionTitle";
4
+ STRINGS[STRINGS["PermissionDescription"] = 1] = "PermissionDescription";
5
+ STRINGS[STRINGS["PermissionButton"] = 2] = "PermissionButton";
6
+ })(STRINGS || (STRINGS = {}));
7
+ function parseLanguage(inp) {
8
+ const [lang, locale] = inp.toLowerCase().split("-");
9
+ return [lang, locale || ""];
10
+ }
11
+ const [lang, locale] = parseLanguage(navigator.language);
12
+ export function tr(str) {
13
+ switch (lang) {
14
+ case "es":
15
+ switch (str) {
16
+ case STRINGS.PermissionTitle: return "Ya casi...";
17
+ case STRINGS.PermissionDescription: return "Para brindar esta experiencia de realidad aumentada, necesitamos acceso a la cámara y los sensores de movimiento de su dispositivo.";
18
+ case STRINGS.PermissionButton: return "Permitir acceso";
19
+ }
20
+ break;
21
+ case "de":
22
+ switch (str) {
23
+ case STRINGS.PermissionTitle: return "Fast am Ziel..";
24
+ case STRINGS.PermissionDescription: return "Um dir dieses Augmented Reality Erlebnis zu liefern, brauchen wir Zugriff auf die Kamera und Bewegungssensoren deines Gerätes.";
25
+ case STRINGS.PermissionButton: return "Gewähre Zugriff";
26
+ }
27
+ break;
28
+ case "pt":
29
+ switch (str) {
30
+ case STRINGS.PermissionTitle: return "Está quase!";
31
+ case STRINGS.PermissionDescription: return "Esta experiência de realidade aumentada precisa de acesso à câmera e aos sensores de movimento deste dispositivo.";
32
+ case STRINGS.PermissionButton: return "Permitir acesso";
33
+ }
34
+ break;
35
+ }
36
+ switch (str) {
37
+ case STRINGS.PermissionTitle: return "Almost there...";
38
+ case STRINGS.PermissionDescription: return "In order to provide this augmented reality experience, we need access to your device's camera and motion sensors.";
39
+ case STRINGS.PermissionButton: return "Grant Access";
40
+ }
41
+ return "";
42
+ }
package/lib/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "2.0.0";
1
+ export declare const VERSION = "2.0.2";
package/lib/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = "2.0.0";
1
+ export const VERSION = "2.0.2";