@maravilla-labs/platform 0.16.0 → 0.17.0

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,23 @@
1
1
  # @maravilla-labs/platform
2
2
 
3
+ ## 0.17.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 16d4f8d: Extend `resize({ crop: 'focal' })` framing with three more opt-in knobs (on top
8
+ of the initial `zoom` factor):
9
+ - **`zoom`** now also accepts values `< 1` (crop _into_ the subject) and
10
+ `'auto'` (a curated, consistent occupancy); range is `0.4..=100.0` | `'auto'`.
11
+ - **`padding`** — margin around the subject box (`0.0..=2.0`, fraction per side)
12
+ so a tight crop keeps breathing room around the head.
13
+ - **`subject`** — `'union'` (all faces, default) or `'primary'` (the
14
+ highest-confidence face, re-centred on it), so a group photo can crop to one
15
+ person.
16
+
17
+ Still fully backward compatible: the new fields never serialize when omitted, so
18
+ existing derived keys are byte-identical. The SDK CSS helpers gain the same
19
+ knobs plus a new `primaryFaceBox()` for parity.
20
+
3
21
  ## 0.16.0
4
22
 
5
23
  ### Minor Changes
package/dist/config.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { T as TransformsConfig } from './transforms-DkAlUPu6.js';
2
- export { a as TransformsPatternSpec } from './transforms-DkAlUPu6.js';
1
+ import { T as TransformsConfig } from './transforms-C2zafn5k.js';
2
+ export { a as TransformsPatternSpec } from './transforms-C2zafn5k.js';
3
3
 
4
4
  /**
5
5
  * @fileoverview Typed schema for `maravilla.config.{ts,yaml,json}` files.
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ export { ActAsContext, AddCircleMemberOptions, AddRelationOptions, ApiKeyInfo, A
3
3
  export { b as RenClient, a as RenClientOptions, R as RenEvent, g as getOrCreateClientId, r as renFetch, c as storageDelete, s as storageUpload } from './ren-DetHRhCL.js';
4
4
  import { LocalParticipant } from 'livekit-client';
5
5
  export { RegisterPushOptions, RegisterPushResult, offsetBefore, registerPush, unregisterPush } from './push.js';
6
- export { D as DetachAudioOpts, e as DetectFacesOpts, l as DocConvertOpts, i as DocFormat, q as DocInsertQrCodeOpts, p as DocReplaceImagesOpts, s as DocTemplateMergeOpts, k as DocThumbnailOpts, n as DocToHtmlOpts, m as DocToMarkdownOpts, j as DocToPdfOpts, d as ExtractAudioOpts, E as ExtractFramesOpts, g as FaceBox, z as FocalCssFrame, y as FocalCssFrameInput, f as FocalPoint, h as FocalPointRecord, F as FramesetManifest, I as ImageFormat, o as ImageRef, u as JobHandle, J as JobStatus, v as JobStatusResponse, M as MediaInfo, O as OcrOpts, Q as QrCodeSpec, r as QrPayload, R as ResizeOpts, S as SubjectBox, c as ThumbnailOpts, b as TranscodeOpts, t as TransformSpec, T as TransformsConfig, a as TransformsPatternSpec, w as TransformsService, V as VideoFormat, B as focalCssFrame, x as keyFor, C as transforms, A as unionFaceBox } from './transforms-DkAlUPu6.js';
6
+ export { D as DetachAudioOpts, e as DetectFacesOpts, l as DocConvertOpts, i as DocFormat, q as DocInsertQrCodeOpts, p as DocReplaceImagesOpts, s as DocTemplateMergeOpts, k as DocThumbnailOpts, n as DocToHtmlOpts, m as DocToMarkdownOpts, j as DocToPdfOpts, d as ExtractAudioOpts, E as ExtractFramesOpts, g as FaceBox, z as FocalCssFrame, y as FocalCssFrameInput, f as FocalPoint, h as FocalPointRecord, F as FramesetManifest, I as ImageFormat, o as ImageRef, u as JobHandle, J as JobStatus, v as JobStatusResponse, M as MediaInfo, O as OcrOpts, Q as QrCodeSpec, r as QrPayload, R as ResizeOpts, S as SubjectBox, c as ThumbnailOpts, b as TranscodeOpts, t as TransformSpec, T as TransformsConfig, a as TransformsPatternSpec, w as TransformsService, V as VideoFormat, C as focalCssFrame, x as keyFor, B as primaryFaceBox, G as transforms, A as unionFaceBox } from './transforms-C2zafn5k.js';
7
7
 
8
8
  /**
9
9
  * Media service for video/audio room management.
package/dist/index.js CHANGED
@@ -2096,6 +2096,7 @@ function keyFor(srcKey, spec) {
2096
2096
  const ext = outputExtension(spec);
2097
2097
  return `__derived/${srcHash}/${variantHash}.${ext}`;
2098
2098
  }
2099
+ var AUTO_ZOOM = 1.22;
2099
2100
  var clamp01 = (n) => Math.min(1, Math.max(0, n));
2100
2101
  function unionFaceBox(faces) {
2101
2102
  if (!faces || faces.length === 0) return null;
@@ -2115,17 +2116,42 @@ function unionFaceBox(faces) {
2115
2116
  if (w <= 0 || h <= 0) return null;
2116
2117
  return { x: x0, y: y0, w, h };
2117
2118
  }
2119
+ function primaryFaceBox(faces) {
2120
+ if (!faces || faces.length === 0) return null;
2121
+ const f = faces.reduce((a, b) => b.score > a.score ? b : a);
2122
+ const x0 = clamp01(f.x);
2123
+ const y0 = clamp01(f.y);
2124
+ const x1 = clamp01(f.x + f.w);
2125
+ const y1 = clamp01(f.y + f.h);
2126
+ const w = x1 - x0;
2127
+ const h = y1 - y0;
2128
+ if (w <= 0 || h <= 0) return null;
2129
+ return {
2130
+ box: { x: x0, y: y0, w, h },
2131
+ focal: { x: x0 + w / 2, y: clamp01(y0 + 0.4 * h) }
2132
+ };
2133
+ }
2118
2134
  function focalCssFrame(input) {
2119
- const { focal, faces, imgWidth, imgHeight, containerAspect } = input;
2120
- const zoom = input.zoom ?? 1;
2135
+ const { faces, imgWidth, imgHeight, containerAspect } = input;
2136
+ let box;
2137
+ let focal = input.focal;
2138
+ if (input.subject === "primary") {
2139
+ const p = primaryFaceBox(faces);
2140
+ box = p?.box ?? null;
2141
+ if (p) focal = p.focal;
2142
+ } else {
2143
+ box = unionFaceBox(faces);
2144
+ }
2121
2145
  const objectPosition = `${(clamp01(focal.x) * 100).toFixed(1)}% ${(clamp01(focal.y) * 100).toFixed(1)}%`;
2122
2146
  const base = { objectPosition, scale: 1, transformOrigin: objectPosition };
2123
- const box = unionFaceBox(faces);
2124
2147
  if (!box || imgWidth <= 0 || imgHeight <= 0 || !(containerAspect > 0)) return base;
2125
2148
  const iar = imgWidth / imgHeight;
2126
2149
  const car = containerAspect;
2127
- const z = Math.max(1, zoom);
2128
- const targetW = z * Math.max(box.w, box.h * car / iar);
2150
+ const z = input.zoom === "auto" ? AUTO_ZOOM : Math.max(0.01, input.zoom ?? 1);
2151
+ const grow = 1 + 2 * Math.max(0, input.padding ?? 0);
2152
+ const bw = box.w * grow;
2153
+ const bh = box.h * grow;
2154
+ const targetW = z * Math.max(bw, bh * car / iar);
2129
2155
  const coverW = car >= iar ? 1 : car / iar;
2130
2156
  const scale = Math.max(1, coverW / targetW);
2131
2157
  return { objectPosition, scale: Math.round(scale * 1e3) / 1e3, transformOrigin: objectPosition };
@@ -2133,7 +2159,8 @@ function focalCssFrame(input) {
2133
2159
  var transforms = {
2134
2160
  keyFor,
2135
2161
  focalCssFrame,
2136
- unionFaceBox
2162
+ unionFaceBox,
2163
+ primaryFaceBox
2137
2164
  };
2138
2165
 
2139
2166
  // src/index.ts
@@ -2186,6 +2213,7 @@ export {
2186
2213
  getPlatform,
2187
2214
  keyFor,
2188
2215
  offsetBefore,
2216
+ primaryFaceBox,
2189
2217
  registerPush,
2190
2218
  renFetch,
2191
2219
  runWithRequest,