{
  "slug": "bw-dev",
  "name": "BW Dev",
  "version": "1.13.0",
  "download_url": "https://plugins.bowden.works/wp-content/uploads/plugin-updates/bw-dev-1.13.0.zip",
  "download_hash": "sha256:9830cf2b1bc94321d5c089a36e1414dc5735dfdfd9ab4aaf71f8f7c672461786",
  "download_size": 477639,
  "requires": "6.0",
  "tested": "",
  "requires_php": "7.4",
  "last_updated": "2026-05-29",
  "homepage": "https://plugins.bowden.works/bw-dev/",
  "author": "Bowden Works",
  "description": "Bowden Works dev toolkit — admin columns, favicon, sticky elements, post-link blocks, YouTube embed, menu visibility, SVG uploads, admin notes, and Flywheel auto-update support in one actively-maintained plugin. Required for several site features. See Settings → BW Dev → About.",
  "changelog": "## [1.13.0] - 2026-05-29\n\n### Added\n- **Analytics module** (`analytics`, group `frontend`) — drops Google Tag Manager script tags + the Search Console verification meta into every frontend page (admin / login / REST stay untouched). Two independent features:\n  - **GTM**: gated by an in-module \"Emit GTM tags\" checkbox that defaults OFF (so updating bw-dev on an existing client site doesn't surprise-inject tracking). When on, the `<head>` snippet hooks `wp_head` priority 1 and the `<noscript>` iframe hooks `wp_body_open` priority 1. When on with an empty GTM ID field, the placeholder `GTM-NOIDSET` is used so the markup structure is present (handy when a third party hands over the real container ID later) — matches the documented \"if no id, use 'GTM-NOIDSET'\" behavior.\n  - **Search Console**: a single paste-tolerant text field. Sanitizer extracts the bare verification token from the full `<meta name=\"google-site-verification\" content=\"…\">` tag, a verification-file URL like `https://example.com/google123abcd.html`, the bare `google123abcd.html` filename, or just the raw token. Empty value = no meta tag emitted.\n  - Settings tab shows a live \"Markup that will be emitted\" preview reflecting the current GTM ID / placeholder, plus a \"Stored as / Will emit\" pair under the SC field once a token is configured.\n- **Inline Search module** (`inline_search`, group `frontend`) — merges the standalone `bw-inline-search` plugin. An elegant search field that expands from a search icon, scoped to one configurable container (the site header by default) so its styles and behavior never leak onto the rest of the page. Three placements: the `[bw_dev_inline_search]` shortcode (attributes: `placeholder`, `icon_color`, `theme=\"light|dark\"`, `align`), a \"BW Inline Search\" widget, and automatic replacement of the theme's own header search toggle (notably Kadence's search drawer) inside the container. Settings tab has a single \"Container CSS selector\" field. The selector is interpolated into a scoped `<style>` block, so it's stripped of CSS-structural characters (`; { } \\ < > \" '`) on both save and output. Re-prefixed throughout: option → `bw_dev_settings[inline_search][container_selector]`, JS config `bwInlineSearchSettings` → `bwDevInlineSearchConfig`, CSS `.bw-inline-search-*` → `.bw-dev-inline-search-*`. The legacy `[bw_inline_search]` shortcode is kept as a back-compat alias, registered only when no other plugin already claims it.\n- **Animate Row module** (`animate_row`, group `frontend`) — merges the standalone `bw-animate-row` plugin. Applies a global AOS scroll-in animation to Kadence rows / top-level columns / sections that don't already carry their own `data-aos` attribute. Per-site config: animation type (27 AOS keywords), duration, easing (17 keywords), delay, trigger offset, animate-once, and which Kadence element types to target. **AOS is now bundled with the plugin** (`assets/vendor/aos/`, v2.3.4) and enqueued locally instead of hot-loaded from the unpkg CDN — removing the supply-chain + visitor-privacy exposure of running third-party JS from a CDN on every public page, and the CDN single-point-of-failure. The ten flat `bw_animation_*` / `bw_target_*` options collapse into the single nested `bw_dev_settings[animate_row]` section; the inline footer init script becomes a localized handle on `assets/js/animate-row.js`. AOS + the init script load only when the module is enabled AND at least one target type is selected.\n- **Scroll Down module** (`scroll_down`, group `frontend`) — merges the standalone `bw-scroll-down` plugin (v4.0.0). A scroll-down indicator (one of six animated SVG icons) that smooth-scrolls to the next section or a configured anchor. Two placements: the `[bw_dev_scroll_down]` shortcode, or a trigger CSS class added to any Kadence row (the indicator is injected + wired automatically). Settings tab: icon picker, size, color (wp-color-picker), label text, bottom offset (`%` or `px`), anchor target, trigger class, auto-target-next-section toggle, float-animation toggle, plus a live hero preview. Re-prefixed: option `bw_scroll_down_settings` → `bw_dev_settings[scroll_down]`, JS config → `bwDevScrollDownConfig`, CSS `.bw-scroll-down*` → `.bw-dev-scroll-down*`, `@keyframes bw-float` → `bw-dev-float`. Frontend logic ported from the plugin's clean inlined footer script (not the stale debug copy in its `assets/`). Legacy `[bw_scroll_down]` kept as a back-compat alias when unclaimed.\n- **Migration v2.** Activation migration bumped to version 2 so already-activated sites re-run the (conservative, fill-missing-only) migration and pick up the three new sections: `bw_search_container_selector` → `inline_search`; the ten `bw_animation_*`/`bw_target_*` options → `animate_row`; `bw_scroll_down_settings` → `scroll_down`. Legacy options are never deleted (the source plugins own their own uninstall). `legacy_map()` extended with the three new source-plugin basenames so the deactivation diagnostics cover them."
}
