=== ConvertNow Analytics ===
Contributors: prateekzare
Donate link: https://paypal.me/prateekzare16
Tags: analytics, statistics, ai analytics, cookieless, privacy
Requires at least: 6.2
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.2.2
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Complete website analytics in your own database, with AI assistant traffic as its own channel. Cookieless, self hosted, no paywall.

== Description ==

ConvertNow Analytics is free analytics for your site. Tracks visitors, visits, pageviews, bounce rate, time on page, landing and exit pages, referrers, channels, campaigns, countries, languages, browsers, devices, goals, funnels, journeys, retention, segments, cohorts, read depth, engaged time, live visitors, email and sharing.

Free in full. No account, key, tier or upgrade.

AI Visibility separates AI referrals from search traffic. It recognises ChatGPT, Perplexity, Claude, Gemini, Copilot, Grok, DeepSeek, Meta AI and Le Chat. GPTBot, ClaudeBot, CCBot and PerplexityBot are excluded. Reports show assistants, cited pages and growth.

Editorial reports cover authors, posts, content types, read depth and engaged time.

Reports cover AI, Editorial, Pages, Referrers, Campaigns, Geographic, Devices and Growth. SVG charts export as PNG or JPG. No external services for charts, maps, favicons or logos.

Performance: tracking adds about 1.5 KB of JavaScript. Not render blocking and no CDN. Country lookups use a bundled table.

Behaviour includes goals, funnels, journeys, retention, segments and cohorts. Export supports CSV, TSV, JSON and NDJSON.

They show only what the data supports.

German, French, Spanish, Dutch and Italian are included. New languages: <a href="https://translate.wordpress.org/projects/wp-plugins/convertnow-analytics/">translate.wordpress.org</a>.

Chart layers include a trend line, 7 day average, variation ring and projected trend.

Insights compares two periods and reports trends, page changes, channel shifts, read depth and AI visibility. It runs on your server when requested. No data leaves it. Export is CSV or JSON.

Visitor recognition is daily by default, with 30, 90 or 365 day options.No cookies.

Privacy: no cookies, localStorage or persistent identifier. Raw IPs are never stored. Do Not Track is supported. The only possible outbound request is an optional monthly usage report, off by default with no visitor data.

No account, key or paywall. Works on activation.

Upcoming: AI citations by author, analytics imports, tracking health checks, author emails, live screen, WP CLI, WooCommerce revenue, consent integration and multisite reporting.

Requests: <a href="mailto:prateekzare@gmail.com">prateekzare@gmail.com</a>.

ConvertNow Analytics is written and maintained by Prateek Zare. <a href="https://convertnow.tools">convertnow.tools</a>. Support: <a href="mailto:contact@convertnow.tools">contact@convertnow.tools</a>.

== Installation ==

From your dashboard:

1. Go to **Plugins → Add New** and search for **ConvertNow Analytics**.
2. Click Install Now, then Activate.
3. Open **ConvertNow** in the admin menu. Data starts appearing immediately.

Or by hand:

1. Upload the `convertnow-analytics` folder to `/wp-content/plugins/`.
2. Activate it from the Plugins screen.
3. Open **ConvertNow** in the admin menu.

Either way that is it. No key, no account, no configuration. Country data is built in, so the map and the Countries panel fill in on their own. Your own visits are not counted while you are logged in as an administrator or editor, which is why the numbers stay at zero until real traffic arrives.

== Frequently Asked Questions ==

= Do I need an account or a licence key? =

No, and there is nowhere to put one. There is no account, no key, no activation and no paid tier. The plugin contains no code that makes an outbound request, so there is nothing to opt out of either.

= My host says I am making too many requests. Is it this plugin? =

Partly, possibly. A page read sends one small request to your own site, and the last page of a visit sends a second. Those cannot be page-cached, so on a site that serves cached HTML they may be most of what actually reaches PHP.

As of 1.2.0 there is far less of it. The reading of a page now travels inside the next pageview rather than costing a request of its own, so a five page visit sends six requests where it used to send ten, and no figure is lost doing it. The beacon also obeys a 429 or 503 from your server: it reads `Retry-After` and stops entirely until that has passed, so it can no longer add to a rate limit once one starts. And it will not send more than sixty times in one visit however badly a theme misbehaves.

What it is not: the plugin makes no outbound requests of any kind, so it cannot be the source of automated traffic from Meta, AWS or Microsoft, and it contacts no third party. It also adds no cron work beyond one hourly summary job.

= Why are my numbers lower than Jetpack, Google Analytics or my host's stats? =

Four ordinary reasons, in the order they usually matter.

1. **You installed it partway through the period.** Days before the install are empty because nothing was recorded then, not because they were quiet.
2. **Administrators and editors are not counted**, by default. Your own visits, and your team's, are missing on purpose. Settings → Tracking changes it.
3. **Do Not Track.** If that setting is on, those readers are dropped entirely, and most other tools ignore the signal. New installs default to off; a site upgrading from an earlier version keeps it on until changed.
4. **Bots.** ConvertNow refuses crawlers, monitors, previewers and AI training bots before a row is written. Some tools count a share of them, which raises their numbers rather than lowering yours.

If the gap still looks wrong after that, the usual cause is the beacon being blocked: a security plugin that hardens `/wp-json/`, or a firewall rule. Since 1.2.0 the plugin retries on a front-end URL when that happens, and counts readers with no JavaScript at all.

= How do you tell an AI visitor from an AI crawler? =

They arrive by completely different routes and are handled at different points. A crawler identifies itself in the user agent, and GPTBot, ClaudeBot, CCBot, PerplexityBot, Bytespider, Applebot and Amazonbot are all refused by the collector before a row is written, so they never become traffic. A visitor is a browser carrying a referrer from an assistant's own domain. Only the second one reaches the AI screens, which is why every figure there is a person who read an answer and followed the citation.

= Why did my Gemini traffic used to show up as Google? =

Because Gemini is served from gemini.google.com, and a rule that looks for "google" in the referrer catches it. Copilot has the same problem on microsoft.com. ConvertNow checks the assistants first, so a visit from Gemini is counted as an assistant and a visit from Google Search is counted as search. Existing summaries are rebuilt on upgrade, so past days are reclassified too.

= An assistant is missing. Can I add it? =

Yes, with the `cnwa_ai_sources` filter. Each entry is a pattern matched against the referrer host and the name to show. The list is checked in order, so a narrow host goes above a broad one.

= Do the trend line and forecast use AI? =

No, and the plugin does not claim they do. They are a least squares fit and the standard deviation of the days around it, computed in your browser from the figures already on the screen. The forecast is that straight line continued, and the band around it is how much the measured days actually varied. Nothing is sent anywhere and no model runs. Every layer is off until you switch it on in Settings.

= Is the AI insights screen actually AI? =

It is statistics, and the screen says so at the bottom of every run. Least squares fits for direction, median absolute deviation for outliers, share and concentration comparisons against the previous period of equal length. It runs on your server against your own rows, no model is called and nothing leaves the site. The name reflects what the screen is for, reading your numbers the way an analyst would, not a claim about how it works.

= Will generating insights slow my site down? =

It cannot touch your front end, because it only runs from the dashboard when somebody presses the button. The run itself reads the selected period and the one before it across several dimensions, which on a large site takes a few seconds, and the result is cached for five minutes so a second press costs nothing. Nothing runs on opening the screen.

= Can I count returning visitors? =

Yes, but it is off by default. Settings → Tracking → Visitor recognition widens the salt window from one day to 30, 90 or 365 days. Until you change it the salt rotates daily and a reader returning tomorrow is a new visitor, which is the honest default for a plugin that stores nothing on the reader's device. Widening it changes what you are doing with visitor data, so update your privacy disclosures before you do.

= Where do I set up a goal or a funnel? =

On the Goals or Funnels screen itself, under the report. Open the report, expand the editor below it, pick a page from your own site, save. Creating a definition needs the same capability as changing a setting, so a user who can view reports but not manage the site sees the report and no editor.

= Why does Retention not show whether visitors came back next week? =

Because ConvertNow cannot tell. A visitor is identified by a hash that is re-salted every day, on purpose, so the same person is unrecognisable tomorrow. Rather than print a number that looks like week-over-week retention and is not, the report answers what the data actually supports: how a page holds its traffic over the days after it lands, and how often a visit is a return within the same day.

= How far back do the behaviour reports go? =

As far as your raw retention setting keeps pageviews, ninety days by default. Goals, funnels, journeys, retention and cohorts all need the shape of individual visits, and the daily summaries have already rolled that away. Each of those screens says the date it can see back to.

= How does it know who wrote a post? =

WordPress already does. The tracker resolves each URL to the post behind it and stores the author ID with the pageview, then the report turns IDs back into display names when it draws. Nothing is sent anywhere to work that out.

= Will author reports cover posts published before I installed it? =

Views recorded before you installed it do not exist, so no. Views recorded before version 2.0 carry no content type yet; Settings has a Classify button that resolves them in batches and backfills Authors, Blog Posts and Content Types for that history.

= Does it work with caching plugins? =

Yes. The beacon is client side and posts to a REST endpoint, so a cached HTML page still reports its own view.

= Does it work with a CDN or Cloudflare? =

Yes. Set the visitor IP source in Settings so country lookups and visitor counts use the real client address instead of the proxy.

= Does it support IPv6? =

Yes. Country lookups cover IPv4 and IPv6.

= Does the country lookup add load to my server? =

Almost none. The table ships with the plugin, so there is no download and no import. A lookup reads one small block of a file, about three microseconds, with no database query and no network request. Results are reused within a request.

= How accurate is the country data? =

It resolves IPv4 to /24 and IPv6 to /48, which is right for about 98% of addresses when checked against the full DB-IP dataset. That is a deliberate trade: a coarser table means a much smaller file and a much cheaper lookup, and it is more than enough to see where an audience is.

= Why do my visitor counts differ from other analytics tools? =

ConvertNow filters bots aggressively and counts a visitor as unique within a single day. Tools that use persistent cookies count differently. Neither number is wrong, they measure different things.

= A content blocker is blocking the endpoint. =

Rename the endpoint in Settings. The tracker picks up the new name automatically.

= Can I track a static page hosted elsewhere? =

Yes. Settings has a snippet. Add the other domain to the allowed domains list first.

= Can I filter the dashboard? =

Yes. Click any row label in a breakdown panel and everything recalculates against that value. Filters stack and combine with AND. Because the daily summaries store each dimension separately, a filtered view reads raw rows, so it reaches back as far as your raw retention setting allows. The filter bar tells you that date.

= Is the trend line a forecast? =

No. It is a least squares fit through the period you are viewing, continued a short way past the end. It knows nothing about seasonality, campaigns or what you publish next. Treat it as direction of travel.

= Does it track clicks? =

No. ConvertNow deliberately records pageviews and engagement only, which keeps the database small and the dashboard readable.

= Where is my data stored? =

In your own WordPress database, in four tables prefixed `cnwa_`. Deleting the plugin removes all of them. The country lookup table is a read only file inside the plugin folder and holds nothing about your visitors.

**Clicks, downloads and searches, when you want them**

Off by default, and honest about why. A page view writes one database row per page; a click writes one per interaction, so an events table grows with how much people do on your site rather than with how many of them turn up. Nothing is collected until you choose it, one type at a time:

* Outbound links, with the destination and the domain
* File downloads, matched by extension
* Email and phone links
* Anything you name with a CSS selector, labelled by `data-cnwa-label` or its own text
* Page views that returned a 404, and the pages that linked to them
* What people typed into your search box

The last two are effectively free: they ride along with a page view that is already being recorded, so they cost one row and no extra request. Broken links and empty searches are usually the fastest wins on any site.

The settings screen tells you what switching this on will cost before you switch it on, using your site's own traffic from the last thirty days and a per-event size measured on a real database rather than guessed. Events have their own retention window, separate from page views, because they are the rows that grow fastest.

**Notes on the chart**

A spike six weeks ago is just a shape unless something tells you what it was. Mark the day you redesigned, sent the newsletter or changed your prices, and the note stays on the chart with the traffic it explains. They are stored in one option row, so there is no table and nothing left behind.

**A weekly email**

Last week against the week before, your five most read pages and five biggest sources, in an email you can read in fifteen seconds. It comes from your own site, contains no tracking pixel, and reads from the daily summaries, so it costs the same whether you had a hundred visitors or a million. Off until you ask for it, and there is a button to send one now and find out whether email leaves your site at all.

== Screenshots ==

1. The Overview: visitors, visits, views, bounce rate and time on page, with the chart's optional trend, average, unusual-day and forecast layers switched on
2. AI at a Glance: which assistants send people, what they were sent to, and how AI compares with every other channel
3. AI Assistants, ranked, with each one's share over time and how deeply its readers read
4. Pages at a Glance: what gets read, where visits begin and where they end
5. Referrers at a Glance: channels, search engines and social networks together
6. Campaigns at a Glance: UTM sources, mediums and campaigns in one place
7. Geographic at a Glance: countries and languages, with a world map
8. Goals, with the builder open: each rule reads back in a sentence and says how many of your pages it matches
9. Settings: the switches for the chart insights, data retention, and the weekly summary email

== External services ==

ConvertNow uses no external service for anything it does. There is one optional service, off by default, described in full below.

Tracking, reporting, goals, funnels, journeys, retention, segments, cohorts, insights, country lookups and exports all run on your own server against your own database. There is no activation call, no licence check and no key. Nothing about your visitors ever leaves your site under any setting.

**Optional: anonymous usage reporting (off by default)**

If, and only if, you switch this on, the plugin sends one report a month to convertnow.tools, the author's site, at `https://convertnow.tools/wp-json/cnwa-hub/v1/report`. It exists so the author can see which versions are in use and how the plugin is actually being used, and it is used for nothing else.

It is off on every install. You are asked once, on the plugin's own screen, with the exact payload from your site shown to you before you decide. Declining is remembered permanently. If you never answer, nothing is ever sent. You can switch it on or off at any time in Settings → Data retention → Anonymous usage report, and switching it off removes the scheduled event immediately.

This is the complete payload, and there is nothing else in it:

* Your site address and site name
* The date this plugin was first activated on your site
* Your total pageviews and total visitors for the last 30 days, as two numbers
* The ConvertNow, WordPress and PHP versions, and your site locale

It contains nothing about your visitors: no page paths, no referrers, no IP addresses, no visitor hashes, no user accounts, no email addresses, no post or page titles. The request is sent once every 30 days, non blocking, and a failure is silent.

Terms of service: <a href="https://convertnow.tools/terms/">https://convertnow.tools/terms/</a>. Privacy policy: <a href="https://convertnow.tools/privacy/">https://convertnow.tools/privacy/</a>.

The country lookup tables ship inside the plugin as plain text files and are read from disk. There is nothing to download and nothing to import.

== Other Notes ==

**Support**

Email <a href="mailto:contact@convertnow.tools">contact@convertnow.tools</a> or visit <a href="https://convertnow.tools">convertnow.tools</a>.

**Bundled data**

IP Geolocation by <a href="https://db-ip.com">DB-IP</a>, used under <a href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a>.

Country lookups read two plain text tables built from the DB-IP IP to Country Lite database: `assets/data/geo-ipv4.csv` and `assets/data/geo-ipv6.csv`. Every line is one boundary, written as an uppercase hex address prefix and an ISO 3166-1 alpha-2 country code, so both files can be opened and read in any text editor. The world map outlines are plain JSON path data at `assets/data/world.json`. Nothing in the plugin is compiled, minified or obfuscated.

== Changelog ==

= 1.2.2 =

**Anonymous usage reporting, off by default.** The plugin can now send one report a month to its author, so that decisions about what to build next come from how the plugin is actually used rather than guesswork. It is off on every install and it stays off unless you say yes.

* You are asked once, on ConvertNow's own screen, and the notice shows the exact payload from your own site before you decide. Saying no is remembered permanently and you are never asked again.
* The payload is your site address and name, the date you installed the plugin, your pageview and visitor totals for the last 30 days, and the ConvertNow, WordPress, PHP and locale strings. Nothing about your visitors is included under any circumstances: no pages, no referrers, no IP addresses, no visitor hashes.
* Settings → Data retention → Anonymous usage report turns it on or off at any time. Off removes the scheduled event straight away, and deactivating or deleting the plugin removes it too.
* The readme's External services section documents every field, the endpoint, the frequency and the links to the terms and privacy policy, as WordPress.org requires.

= 1.2.1 =

**Insights on demand.** Data → AI insights runs a statistical read of the selected period and hands back fifteen to twenty ranked findings across traffic shape, content, engagement, acquisition, assistant visibility and audience. Pick which groups to run, press generate, export as CSV or JSON. Nothing runs until you ask, because it reads the whole period and the one before it; results are cached for five minutes so a second press is free. Administrators and anyone with dashboard access.

* Every finding carries the figure behind it, a confidence taken from the fit or the sample size, and plain language about what it does and does not prove.
* The methods are least squares fits, median absolute deviation, share and concentration comparisons. Everything runs on your server against your own rows. No model is called and nothing leaves the site, and the screen says so rather than implying otherwise.
* An incomplete final day is excluded from any trend or forecast, so a range that ends today no longer reads half a day as a collapse.
* Direct is excluded from referrer concentration, where counting the absence of a referrer as the largest referrer was a category error.

**Returning readers, if you want them.** Settings → Tracking → Visitor recognition widens the visitor salt window from one day to 30, 90 or 365. Off by default and staying that way. The setting carries the privacy note it needs: no cookies and nothing stored on the reader's device either way, but you will need to update your own disclosures before turning it on.

= 1.2.0 =

**Fewer requests, and it stops when your host says stop.** If your host has been reporting 429s or rate limiting, this release is for you.

* **The engagement beacon no longer repeats.** Switching to another tab and back re-armed it, so a reader who did that five times sent six requests for one page read instead of two. It now sends once, and a second time only if the reader came back and did enough to change the number materially. Never more than twice.
* **A 429 or 503 is obeyed.** The beacon reads the status, honours `Retry-After`, and sends nothing at all until that window has passed. Until now it could not see the response and kept sending into a rate limit, which turns a busy minute into a sustained one.
* **A request budget per visit.** At most one beacon every 0.8 seconds and 60 in a visit. A theme that calls `pushState` in a loop used to be able to produce hundreds of requests from a single reader; measured on 200 route changes, that is 411 requests before and 60 after.
* **Flood protection now answers 429 with a Retry-After** instead of a silent 204, so a flooding client is told to stop rather than ignored and left to continue.
* **A page read costs one request instead of two, and nothing is lost.** How a page was read used to be its own request, every time. It now travels inside the next pageview from the same tab, which was going to be sent anyway. A visit to five pages costs six requests instead of ten, and all five readings still arrive. Only the last page of a visit spends a request of its own, because there is no next request to put it in. Nothing to configure and nothing to trade away.
**More accurate counting.** Three reasons a figure here could come out lower than a hosted service reporting on the same site, all addressed.

* **Readers whose browser ran no JavaScript are now counted.** Script blockers, text browsers, accessibility tools and JavaScript simply switched off were invisible to a beacon and missing from every figure. A one pixel image inside a `noscript` tag records them: page and referrer, since screen size and read depth need a script. A browser that runs the beacon never requests it, so it costs nothing on almost every visit. Settings → Tracking.
* **A blocked REST route no longer means lost traffic.** Some security plugins harden `/wp-json/` off by default and some firewall rules refuse it, and on those sites every beacon was quietly rejected, which looks exactly like undercounting. A pageview refused there is retried once on an ordinary front-end URL, and whichever route answered is used for the rest of the visit.
* **Do Not Track is no longer skipped by default on new installs.** ConvertNow identifies nobody, sets no cookie, stores no personal data and sends nothing anywhere, so the signal is asking it not to do a thing it does not do — while dropping those readers was the single biggest reason its numbers sat below a service that ignores the signal. Existing sites keep whatever they have; upgrading changes no setting. The switch is still there, and when it is on the signal is now honoured on the pixel as well, not only in the browser.

* `beforeunload` is no longer used. It duplicated `pagehide` and blocks the browser's back-forward cache.
* Fixed: on a browser without `sendBeacon`, the engagement beacon could be dropped instead of falling back to a keepalive request.

= 1.1.1 =

**Deleting the plugin no longer deletes your data, unless you ask it to.**

Updating a plugin by deleting the old copy and uploading the new one is a normal thing to do, and WordPress runs the uninstall routine on the delete. Until now that meant an update done this way took your settings, your shared dashboard link and every day of history with it. It does not any more: nothing is removed unless **Settings → Data retention → If the plugin is deleted** says so, and that box says keep by default. A clean removal is still one switch away for anyone who wants it.

**The AI screens describe AI traffic and nothing else.**

* AI at a Glance was drawing a site-wide trend line above assistant-only numbers, and comparing AI against every other channel in a panel. Both are gone. The chart now plots assistant traffic, so the line and the figures under it describe the same visits.
* The panels are assistants, assistants over time, and the pages they sent people to.

**Filtering reaches every report.**

* Authors, content types, AI assistants, pages cited by AI, UTM mediums and UTM campaigns can all be filtered on now. Previously clicking those names did nothing.
* The glance screens carry the open-in-a-new-tab link the report tables already had, so a page name behaves the same wherever it appears.
* A filter chip shows the name rather than the stored value: filtering by an author reads "Author: Amara Okafor", not "Author: 4".

= 1.1.0 =

**AI visibility.** Visits arriving from an AI assistant are now counted as their own channel and reported on their own screens.

* A new **AI Visibility** section: AI at a Glance, AI Assistants, Pages Cited by AI, and Fastest-Growing Assistants.
* **AI assistant** joins direct, organic search, social, email, referral and paid as a channel, so it appears everywhere a channel appears, including the Overview and the Channels report.
* An **AI** tab on the Overview's Sources panel.
* ChatGPT, Perplexity, Claude, Gemini, Copilot, Grok, DeepSeek, Meta AI and Le Chat are recognised by name. `cnwa_ai_sources` adds more.
* **Fixed: Gemini was being counted as organic search.** Gemini is served from gemini.google.com and Copilot from microsoft.com, so the search-engine rule matched both. Assistants are now tested before search engines. Summaries are rebuilt on upgrade, so past days are reclassified as well.
* Crawlers are unaffected: GPTBot, ClaudeBot, CCBot, PerplexityBot and the rest are still refused before a row is written, so nothing on these screens is a machine.

**Chart insights, all off by default.** Four statistical layers for the main chart, each switched on separately in Settings.

* A least squares trend line.
* A seven day centred average, which takes the weekday cycle out.
* Unusual days, ringed when they sit further from the trend than this site normally varies. The threshold is configurable.
* A forecast: the trend carried past today inside a band the width of the measured variation, so an irregular site gets a wide band rather than a confident wrong line.
* These are arithmetic, computed in the browser from the numbers already on screen. Nothing is sent anywhere, no model runs and the plugin does not describe them as AI.

**Goals and funnels are easier to build.**

* Every goal row now reads its own rule back as a sentence and says how many of your pages match it, updated as you type, so a mistyped path is obvious before you save rather than after an empty report.
* Funnel steps can be reordered without deleting and retyping them.
* "Add an empty row" is now "Add a goal" and "Add a funnel", and both put the cursor where you are about to type.

**Fixed**

* Pages Cited by AI and other path lists no longer truncate the path to a single character in the glance panels.

= 1.0.0 =

First public release on WordPress.org.

* **Editorial reporting is the point of it.** Traffic by author with real display names, Fastest-Growing Authors measured against the previous period of the same length, Blog Posts on a screen of their own so the home page stops drowning out the writing, and Content Types splitting posts from pages, products and archives.
* **Real engagement, not guessed engagement.** Bounce rate and time on page come from an engagement beacon rather than from the gap between two timestamps, and read depth is recorded per post.
* Pages, entry pages, exit pages, referrers, channels, UTM campaigns, countries, languages, browsers, systems, devices and screen sizes, each on its own screen and in an at a glance summary.
* Goals, funnels, journeys and retention, all defined and edited from the report they feed.
* **Cookieless by design.** No cookie, no browser storage, no device fingerprint. Visitors are counted with a daily rotating hash that cannot be reversed or carried across days, and no IP address is ever written to the database.
* **Self hosted, end to end.** Every figure is computed in your own tables. Nothing is sent anywhere, there is no account, no API key and no paid tier.
* Country lookup runs locally against a bundled DB-IP table. No lookup service is contacted.
* Daily rollups keep the reports fast on large sites, with configurable retention for raw hits, events and summaries.
* Weekly email digest, a dashboard widget, a read only shareable dashboard link, CSV export and annotations.
* Every table and column name binds through `$wpdb->prepare()` with the `%i` placeholder, which is why WordPress 6.2 is the minimum. Nothing the plugin runs is assembled from a string.
* Report caching is keyed by permission scope, so a payload built for an administrator can never be served to a shared dashboard link.

== Upgrade Notice ==

= 1.2.2 =
Adds an optional anonymous usage report, off by default, which sends your site address, install date, 30 day totals and version numbers to the plugin author once a month if you agree to it. You are asked once, shown the exact payload first, and never asked again. Nothing about your visitors is ever included.

= 1.2.1 =
Adds an on demand insights screen under Data that reports what actually moved in the selected period, with the figure and the confidence behind each finding, exportable as CSV or JSON. Also adds an optional longer visitor recognition window for counting returning readers, off by default.

= 1.2.0 =
Counts readers without JavaScript, survives a blocked REST route, and no longer drops Do Not Track readers on new installs, so figures line up with what other tools report. A page read now costs one request instead of two, with nothing lost: the reading travels inside the next pageview. The beacon also backs off when your host returns 429, and will not send more than sixty times in a visit. Recommended for anyone seeing rate limiting.

= 1.1.1 =
Deleting the plugin now keeps your settings, shared link and history by default, so updating by hand no longer wipes them. The AI screens are scoped to assistant traffic only, and authors, content types, assistants and campaigns can now be filtered on.

= 1.1.0 =
Adds AI assistant traffic as its own channel and its own reports, and fixes Gemini and Copilot being counted as organic search. Daily summaries are rebuilt once on upgrade so past days are reclassified too. Also adds optional trend, average, anomaly and forecast layers to the chart, all off until you switch them on.

= 1.0.0 =
First public release.
