# Build the FlyLo CamFX macOS .dmg

The Electron config is set up. To produce a universal `.dmg` (Apple
Silicon + Intel in one bundle) you need a Mac with Node 20+ installed.
electron-builder cannot cross-compile macOS bundles from Linux/Windows
reliably, so the build itself has to happen on a Mac.

## One-time setup on the Mac

```bash
# Clone or copy the FLYLO_CAMFX_WEB_2026 project onto the Mac.
cd FLYLO_CAMFX_WEB_2026
npm install
```

That pulls electron + electron-builder + everything else (~600 MB
node_modules, takes 1-2 min on a fast connection).

## App icon (optional but recommended)

The .dmg will use a generic Electron app icon unless you drop a
`.icns` file at `electron/build-resources/icon.icns`. Make one from a
1024×1024 PNG:

```bash
mkdir icon.iconset
sips -z 16 16     master.png --out icon.iconset/icon_16x16.png
sips -z 32 32     master.png --out icon.iconset/icon_16x16@2x.png
sips -z 32 32     master.png --out icon.iconset/icon_32x32.png
sips -z 64 64     master.png --out icon.iconset/icon_32x32@2x.png
sips -z 128 128   master.png --out icon.iconset/icon_128x128.png
sips -z 256 256   master.png --out icon.iconset/icon_128x128@2x.png
sips -z 256 256   master.png --out icon.iconset/icon_256x256.png
sips -z 512 512   master.png --out icon.iconset/icon_256x256@2x.png
sips -z 512 512   master.png --out icon.iconset/icon_512x512.png
cp master.png icon.iconset/icon_512x512@2x.png
iconutil -c icns icon.iconset -o electron/build-resources/icon.icns
```

Without an icon, the DMG still builds fine — it'll just show the
default Electron diamond.

## Build commands

```bash
# Universal binary (Apple Silicon + Intel, recommended for distribution)
npm run dist:mac

# Apple Silicon only (smaller download, ~20% faster build)
npm run dist:mac:arm64

# Intel only (legacy machines)
npm run dist:mac:x64
```

Output appears in `release/`:
- `release/FlyLo CamFX-1.0.0.dmg` — the disk image (~250 MB universal,
  ~150 MB single-arch)
- `release/mac-universal/FlyLo CamFX.app` — the unpackaged .app
  bundle, useful for quick testing without going through the .dmg
  install flow

## What's bundled

- The Vite-built `dist/` (HTML, JS, WGSL shaders, styles)
- DepthAnything V2 ONNX models from `public/models/`
  (~99 MB ViT-S + ~100 MB ViT-B)
- MediaPipe selfie_segmenter is loaded from Google's CDN at runtime —
  requires internet on first launch unless you bundle it (see "Offline
  install" below)

## First-launch UX

The app is **unsigned** unless you provide an Apple Developer ID.
First launch will show "FlyLo CamFX can't be opened because Apple
cannot check it for malicious software". To bypass:

1. **Right-click** the .app in Applications → **Open**
2. Click **Open** in the confirmation dialog
3. macOS now trusts the app for all future launches

This is the standard "indie unsigned app" flow. Annoying but works
and doesn't require us paying for an Apple Developer account ($99/yr)
just to ship a tour utility.

Camera + microphone prompts appear on first use — required for the
audio-reactive FX to work. Permissions persist in System Settings →
Privacy & Security.

## Dev mode (Mac, optional)

To test the Electron wrapper without packaging:

```bash
# Terminal 1
npm run dev

# Terminal 2 (waits for terminal 1 to print "Network: ...")
npm run electron:dev
```

This launches Electron pointing at the live Vite dev server, so HMR
+ source maps work. Useful when iterating on the Electron main
process or for stage testing without producing a .dmg each time.

## Offline install (bundle MediaPipe)

For show reliability we want zero internet dependency at boot. To
bundle the selfie segmenter model:

```bash
# Download once and stash in public/models/
curl -L 'https://storage.googleapis.com/mediapipe-models/image_segmenter/selfie_segmenter/float16/1/selfie_segmenter.tflite' \
  -o public/models/selfie_segmenter.tflite
```

Then update `src/segmentation/MediaPipeSegmenter.ts` to load from the
local path (`./models/selfie_segmenter.tflite`) instead of the CDN
URL. Not done by default because the CDN is reliable in most venues.

## Troubleshooting

**"App is damaged and can't be opened"** — usually means the app was
quarantined during download. Run:

```bash
xattr -dr com.apple.quarantine "/Applications/FlyLo CamFX.app"
```

**Black screen on launch** — the depth model probably failed to load.
Check the console (Cmd+Option+I to open DevTools if `nodeIntegration`
is true, otherwise check the Activity Monitor's process log). Or run
`npm run electron:dev` for a window with DevTools opened.

**Webcam shows but no FX** — the audio stream couldn't initialize.
Confirm microphone permissions in System Settings → Privacy &
Security → Microphone. The FX won't run without mic input.

## After building

Drop `release/FlyLo CamFX-1.0.0.dmg` into the delivery site at:
```
/mnt/c/Users/STRANGELOOP/MIST/Projects/flylo-fx/cam-fx/FlyLoCamFX-mac.dmg
```

Then deploy the site:
```bash
cd /mnt/c/Users/STRANGELOOP/MIST/Projects/flylo-fx
npx wrangler pages deploy . --project-name=flylo-fx-2026 --commit-dirty=true
```

(Site is `flylo-fx-2026.pages.dev` — David's chosen URL.)
