PageSourceSearch

https://reviewmyelearning.com/

html reviewmyelearning.com collected 2026-10-03 22:02:20 UTC 36,689 bytes, 459 lines download raw bytes

1<!DOCTYPE html>
2<html class="h-full min-h-screen w-full bg-white" lang="en">
3  <head>
4    
4<script>
5      // Account-change links carry one-time capabilities. Strip them before
6      // analytics or any other third-party JavaScript can initialize.
7      (function () {
8        var path = window.location.pathname.replace(/\/+$/, "");
9        var isEmailChange = path === "/email-change";
10        var isOwnershipTransfer = path === "/ownership-transfer";
11        var isPasswordReset =
12          path === "/reset-password" || path.indexOf("/reset-password/") === 0;
13        if (!isEmailChange && !isOwnershipTransfer && !isPasswordReset) return;
14
15        Object.defineProperty(window, "__rmeSensitiveRoute", {
16          value: true,
17          configurable: true,
18        });
19
20        // First-party code may still reference these globals after an SPA
21        // navigation. Keep them inert for this document instead of loading
22        // third-party trackers while a confirmation capability is in memory.
23        var noop = function () {};
24        window.gtag = noop;
25        window.lintrk = noop;
26        window.posthog = {
27          capture: noop,
28          captureException: noop,
29          identify: noop,
30          reset: noop,
31          register: noop,
32          unregister: noop,
33          isFeatureEnabled: function () { return false; },
34        };
35        window._cio = {
36          identify: noop,
37          reset: noop,
38          track: noop,
39          page: noop,
40        };
41
42        var token = new URLSearchParams(
43          window.location.hash.replace(/^#/, "")
44        ).get("token");
45        if (!token && path.indexOf("/reset-password/") === 0) {
46          token = path.slice("/reset-password/".length);
47        }
48        var safePath = isPasswordReset ? "/reset-password" : path;
49        window.history.replaceState(
50          window.history.state,
51          document.title,
52          safePath + window.location.search
53        );
54
55        if (isEmailChange && token && /^[a-f0-9]{64}$/i.test(token)) {
56          Object.defineProperty(window, "__rmeEmailChangeBootstrapToken", {
57            value: token,
58            writable: true,
59            configurable: true,
60            enumerable: false,
61          });
62        } else if (
63          isOwnershipTransfer &&
64          token &&
65          /^[a-f0-9]{64}$/i.test(token)
66        ) {
67          Object.defineProperty(
68            window,
69            "__rmeOwnershipTransferBootstrapToken",
70            {
71              value: token,
72              writable: true,
73              configurable: true,
74              enumerable: false,
75            }
76          );
77        } else if (
78          isPasswordReset &&
79          token &&
80          /^(?:[a-f0-9]{32}|[a-f0-9]{40})$/i.test(token)
81        ) {
82          Object.defineProperty(window, "__rmePasswordResetBootstrapToken", {
83            value: token,
84            writable: true,
85            configurable: true,
86            enumerable: false,
87          });
88        }
89      })();
90    </script>
90
91    <meta charset="UTF-8" />
92    <link rel="icon" type="image/svg+xml" href="/logos/favicon.ico" />
93    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
94    <!-- Primary Meta Tags -->
95    <title>Review My eLearning | First AI-Powered Course Review Tool</title>
96    <meta
97      name="title"
98      content="Review My eLearning | First AI-Powered Course Review Tool"
99    />
100    <meta
101      name="description"
102      content="Review eLearning courses from any authoring tool, including courses built by AI. Comments land on the exact screen as tracked work. Built-in MCP server for Claude, ChatGPT and other AI assistants."
103    />
104
105    <!-- Open Graph / Facebook -->
106    <meta property="og:type" content="website" />
107    <meta property="og:url" content="https://reviewmyelearning.com/" />
108    <meta
109      property="og:title"
110      content="Review My eLearning | First AI-Powered Course Review Tool"
111    />
112    <meta
113      property="og:description"
114      content="Review eLearning courses from any authoring tool, including courses built by AI. Comments land on the exact screen as tracked work. Built-in MCP server for Claude, ChatGPT and other AI assistants."
115    />
116    <meta property="og:image" content="/imgs/ogimage.png" />
117
118    <!-- Twitter -->
119    <meta property="twitter:card" content="summary_large_image" />
120    <meta property="twitter:url" content="https://reviewmyelearning.com/" />
121    <meta
122      property="twitter:title"
123      content="Review My eLearning | First AI-Powered Course Review Tool"
124    />
125    <meta
126      property="twitter:description"
127      content="Review eLearning courses from any authoring tool, including courses built by AI. Comments land on the exact screen as tracked work. Built-in MCP server for Claude, ChatGPT and other AI assistants."
128    />
129    <meta property="twitter:image" content="/imgs/ogimage.png" />
130
131    <!-- What RME is, for search engines and AI crawlers that don't run JavaScript.
132         Keep in step with product.md (and /llms.txt, which says it at length). -->
133    
133<script type="application/ld+json">
134      {
135        "@context": "https://schema.org",
136        "@type": "SoftwareApplication",
137        "name": "Review My eLearning",
138        "url": "https://reviewmyelearning.com/",
139        "applicationCategory": "BusinessApplication",
140        "operatingSystem": "Web",
141        "description": "Course review for eLearning teams. Upload a SCORM or HTML5 course from any authoring tool, including courses written by AI, invite reviewers, and every comment lands on the exact screen as a tracked, assignable work item. A built-in MCP server lets Claude, ChatGPT and other MCP-capable AI assistants read review data and publish courses for review.",
142        "featureList": [
143          "Per-screen comments on SCORM and HTML5 courses",
144          "Purpose-built trackers for Storyline, Captivate, Rise, Lectora, iSpring, Gomo, Essemble and SAP Enable Now",
145          "Universal tracking for any course that runs in a browser, including hand-coded and AI-built courses",
146          "Built-in MCP server for MCP-capable AI assistants",
147          "AI Reviewers for accessibility, UX and design (Beta)",
148          "Course Ingest API",
149          "Comment status, assignment, tags, threaded discussion and attachments"
150        ],
151        "sameAs": [
152          "https://blog.reviewmyelearning.com",
153          "https://kb.reviewmyelearning.com"
154        ]
155      }
156    </script>
156
157
158    <!-- Meta Tags Generated with https://metatags.io -->
159    <link
160      rel="preload"
161      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/css/all.min.css"
162      as="style"
163      onload="this.onload=null;this.rel='stylesheet'"
164    />
165    <link
166      rel="preload"
167      href="https://cdn.jsdelivr.net/npm/@voerro/[email protected]/dist/style.css"
168      as="style"
169      onload="this.onload=null;this.rel='stylesheet'"
170    />
171    
172    
173    <style type="text/css">@font-face {font-family:'Poppins';font-style:normal;font-weight:100;src:url(/cf-fonts/s/poppins/5.2.7/latin-ext/100/normal.woff2);unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;font-display:swap;}@font-face {font-family:'Poppins';font-style:normal;font-weight:100;src:url(/cf-fonts/s/poppins/5.2.7/latin/100/normal.woff2);unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;font-display:swap;}@font-face {font-family:'Poppins';font-style:normal;font-weight:100;src:url(/cf-fonts/s/poppins/5.2.7/devanagari/100/normal.woff2);unicode-range:U+0900-097F,U+1CD0-1CF9,U+200C-200D,U+20A8,U+20B9,U+20F0,U+25CC,U+A830-A839,U+A8E0-A8FF,U+11B00-11B09;font-display:swap;}@font-face {font-family:'Poppins';font-style:normal;font-weight:200;src:url(/cf-fonts/s/poppins/5.2.7/latin/200/normal.woff2);unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;font-display:swap;}@font-face {font-family:'Poppins';font-style:normal;font-weight:200;src:url(/cf-fonts/s/poppins/5.2.7/latin-ext/200/normal.woff2);unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;font-display:swap;}@font-face {font-family:'Poppins';font-style:normal;font-weight:200;src:url(/cf-fonts/s/poppins/5.2.7/devanagari/200/normal.woff2);unicode-range:U+0900-097F,U+1CD0-1CF9,U+200C-200D,U+20A8,U+20B9,U+20F0,U+25CC,U+A830-A839,U+A8E0-A8FF,U+11B00-11B09;font-display:swap;}@font-face {font-family:'Poppins';font-style:normal;font-weight:300;src:url(/cf-fonts/s/poppins/5.2.7/latin/300/normal.woff2);unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;font-display:swap;}@font-face {font-family:'Poppins';font-style:normal;font-weight:300;src:url(/cf-fonts/s/poppins/5.2.7/latin-ext/300/normal.woff2);unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;font-display:swap;}@font-face {font-family:'Poppins';font-style:normal;font-weight:300;src:url(/cf-fonts/s/poppins/5.2.7/devanagari/300/normal.woff2);unicode-range:U+0900-097F,U+1CD0-1CF9,U+200C-200D,U+20A8,U+20B9,U+20F0,U+25CC,U+A830-A839,U+A8E0-A8FF,U+11B00-11B09;font-display:swap;}@font-face {font-family:'Poppins';font-style:normal;font-weight:400;src:url(/cf-fonts/s/poppins/5.2.7/devanagari/400/normal.woff2);unicode-range:U+0900-097F,U+1CD0-1CF9,U+200C-200D,U+20A8,U+20B9,U+20F0,U+25CC,U+A830-A839,U+A8E0-A8FF,U+11B00-11B09;font-display:swap;}@font-face {font-family:'Poppins';font-style:normal;font-weight:400;src:url(/cf-fonts/s/poppins/5.2.7/latin/400/normal.woff2);unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;font-display:swap;}@font-face {font-family:'Poppins';font-style:normal;font-weight:400;src:url(/cf-fonts/s/poppins/5.2.7/latin-ext/400/normal.woff2);unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;font-display:swap;}@font-face {font-family:'Poppins';font-style:normal;font-weight:500;src:url(/cf-fonts/s/poppins/5.2.7/latin-ext/500/normal.woff2);
173unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;font-display:swap;}@font-face {font-family:'Poppins';font-style:normal;font-weight:500;src:url(/cf-fonts/s/poppins/5.2.7/latin/500/normal.woff2);unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;font-display:swap;}@font-face {font-family:'Poppins';font-style:normal;font-weight:500;src:url(/cf-fonts/s/poppins/5.2.7/devanagari/500/normal.woff2);unicode-range:U+0900-097F,U+1CD0-1CF9,U+200C-200D,U+20A8,U+20B9,U+20F0,U+25CC,U+A830-A839,U+A8E0-A8FF,U+11B00-11B09;font-display:swap;}@font-face {font-family:'Poppins';font-style:normal;font-weight:600;src:url(/cf-fonts/s/poppins/5.2.7/latin/600/normal.woff2);unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;font-display:swap;}@font-face {font-family:'Poppins';font-style:normal;font-weight:600;src:url(/cf-fonts/s/poppins/5.2.7/latin-ext/600/normal.woff2);unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;font-display:swap;}@font-face {font-family:'Poppins';font-style:normal;font-weight:600;src:url(/cf-fonts/s/poppins/5.2.7/devanagari/600/normal.woff2);unicode-range:U+0900-097F,U+1CD0-1CF9,U+200C-200D,U+20A8,U+20B9,U+20F0,U+25CC,U+A830-A839,U+A8E0-A8FF,U+11B00-11B09;font-display:swap;}@font-face {font-family:'Poppins';font-style:normal;font-weight:700;src:url(/cf-fonts/s/poppins/5.2.7/devanagari/700/normal.woff2);unicode-range:U+0900-097F,U+1CD0-1CF9,U+200C-200D,U+20A8,U+20B9,U+20F0,U+25CC,U+A830-A839,U+A8E0-A8FF,U+11B00-11B09;font-display:swap;}@font-face {font-family:'Poppins';font-style:normal;font-weight:700;src:url(/cf-fonts/s/poppins/5.2.7/latin/700/normal.woff2);unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;font-display:swap;}@font-face {font-family:'Poppins';font-style:normal;font-weight:700;src:url(/cf-fonts/s/poppins/5.2.7/latin-ext/700/normal.woff2);unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;font-display:swap;}@font-face {font-family:'Poppins';font-style:normal;font-weight:800;src:url(/cf-fonts/s/poppins/5.2.7/latin-ext/800/normal.woff2);unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;font-display:swap;}@font-face {font-family:'Poppins';font-style:normal;font-weight:800;src:url(/cf-fonts/s/poppins/5.2.7/devanagari/800/normal.woff2);unicode-range:U+0900-097F,U+1CD0-1CF9,U+200C-200D,U+20A8,U+20B9,U+20F0,U+25CC,U+A830-A839,U+A8E0-A8FF,U+11B00-11B09;font-display:swap;}@font-face {font-family:'Poppins';font-style:normal;font-weight:800;src:url(/cf-fonts/s/poppins/5.2.7/latin/800/normal.woff2);unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;font-display:swap;}@font-face {font-family:'Poppins';font-style:normal;font-weight:900;src:url(/cf-fonts/s/poppins/5.2.7/latin/900/normal.woff2);unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;font-display:swap;}@font-face {font-family:'Poppins';font-style:normal;font-weight:900;src:url(/cf-fonts/s/poppins/5.2.7/latin-ext/900/normal.woff2);unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1D
173BF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;font-display:swap;}@font-face {font-family:'Poppins';font-style:normal;font-weight:900;src:url(/cf-fonts/s/poppins/5.2.7/devanagari/900/normal.woff2);unicode-range:U+0900-097F,U+1CD0-1CF9,U+200C-200D,U+20A8,U+20B9,U+20F0,U+25CC,U+A830-A839,U+A8E0-A8FF,U+11B00-11B09;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:100;src:url(/cf-fonts/s/poppins/5.2.7/latin/100/italic.woff2);unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:100;src:url(/cf-fonts/s/poppins/5.2.7/latin-ext/100/italic.woff2);unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:100;src:url(/cf-fonts/s/poppins/5.2.7/devanagari/100/italic.woff2);unicode-range:U+0900-097F,U+1CD0-1CF9,U+200C-200D,U+20A8,U+20B9,U+20F0,U+25CC,U+A830-A839,U+A8E0-A8FF,U+11B00-11B09;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:200;src:url(/cf-fonts/s/poppins/5.2.7/latin/200/italic.woff2);unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:200;src:url(/cf-fonts/s/poppins/5.2.7/latin-ext/200/italic.woff2);unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:200;src:url(/cf-fonts/s/poppins/5.2.7/devanagari/200/italic.woff2);unicode-range:U+0900-097F,U+1CD0-1CF9,U+200C-200D,U+20A8,U+20B9,U+20F0,U+25CC,U+A830-A839,U+A8E0-A8FF,U+11B00-11B09;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:300;src:url(/cf-fonts/s/poppins/5.2.7/devanagari/300/italic.woff2);unicode-range:U+0900-097F,U+1CD0-1CF9,U+200C-200D,U+20A8,U+20B9,U+20F0,U+25CC,U+A830-A839,U+A8E0-A8FF,U+11B00-11B09;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:300;src:url(/cf-fonts/s/poppins/5.2.7/latin-ext/300/italic.woff2);unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:300;src:url(/cf-fonts/s/poppins/5.2.7/latin/300/italic.woff2);unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:400;src:url(/cf-fonts/s/poppins/5.2.7/latin-ext/400/italic.woff2);unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:400;src:url(/cf-fonts/s/poppins/5.2.7/devanagari/400/italic.woff2);unicode-range:U+0900-097F,U+1CD0-1CF9,U+200C-200D,U+20A8,U+20B9,U+20F0,U+25CC,U+A830-A839,U+A8E0-A8FF,U+11B00-11B09;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:400;src:url(/cf-fonts/s/poppins/5.2.7/latin/400/italic.woff2);unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:500;src:url(/cf-fonts/s/poppins/5.2.7/latin-ext/500/italic.woff2);
173unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:500;src:url(/cf-fonts/s/poppins/5.2.7/devanagari/500/italic.woff2);unicode-range:U+0900-097F,U+1CD0-1CF9,U+200C-200D,U+20A8,U+20B9,U+20F0,U+25CC,U+A830-A839,U+A8E0-A8FF,U+11B00-11B09;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:500;src:url(/cf-fonts/s/poppins/5.2.7/latin/500/italic.woff2);unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:600;src:url(/cf-fonts/s/poppins/5.2.7/devanagari/600/italic.woff2);unicode-range:U+0900-097F,U+1CD0-1CF9,U+200C-200D,U+20A8,U+20B9,U+20F0,U+25CC,U+A830-A839,U+A8E0-A8FF,U+11B00-11B09;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:600;src:url(/cf-fonts/s/poppins/5.2.7/latin-ext/600/italic.woff2);unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:600;src:url(/cf-fonts/s/poppins/5.2.7/latin/600/italic.woff2);unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:700;src:url(/cf-fonts/s/poppins/5.2.7/latin-ext/700/italic.woff2);unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:700;src:url(/cf-fonts/s/poppins/5.2.7/devanagari/700/italic.woff2);unicode-range:U+0900-097F,U+1CD0-1CF9,U+200C-200D,U+20A8,U+20B9,U+20F0,U+25CC,U+A830-A839,U+A8E0-A8FF,U+11B00-11B09;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:700;src:url(/cf-fonts/s/poppins/5.2.7/latin/700/italic.woff2);unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:800;src:url(/cf-fonts/s/poppins/5.2.7/latin/800/italic.woff2);unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:800;src:url(/cf-fonts/s/poppins/5.2.7/latin-ext/800/italic.woff2);unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:800;src:url(/cf-fonts/s/poppins/5.2.7/devanagari/800/italic.woff2);unicode-range:U+0900-097F,U+1CD0-1CF9,U+200C-200D,U+20A8,U+20B9,U+20F0,U+25CC,U+A830-A839,U+A8E0-A8FF,U+11B00-11B09;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:900;src:url(/cf-fonts/s/poppins/5.2.7/latin-ext/900/italic.woff2);unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:900;src:url(/cf-fonts/s/poppins/5.2.7/latin/900/italic.woff2);unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;font-display:swap;}@font-face {font-family:'Poppins';font-style:italic;font-weight:900;src:url(/cf-fonts/s/poppins/5.2.7/devanagari/900/italic.woff2);
173unicode-range:U+0900-097F,U+1CD0-1CF9,U+200C-200D,U+20A8,U+20B9,U+20F0,U+25CC,U+A830-A839,U+A8E0-A8FF,U+11B00-11B09;font-display:swap;}</style>
174
175    
175<script>
176      if (!window.__rmeSensitiveRoute) {
177        
vendor: 173 bytes, lines 177-183
177window.dataLayer = window.dataLayer || [];
178        function gtag() {
179          dataLayer.push(arguments);
180        }
181        gtag("js", new Date());
182
183        gtag("config", "
183G-2X09DQ1SJ1
vendor: 10 bytes, lines 183-184
183");
184      
184}
185    </script>
185
186
187    
187<script>
188      // PostHog sends only from production builds. Vite substitutes production at
189      // build time (development / staging / production) and leaves an unset
190      // %VITE_…% placeholder untouched, hence the "%" check. Mirrors
191      // shouldSend() in server/posthogClient.js; keep the two rules the same.
192      // VITE_POSTHOG_ENABLED=true in client/.env.staging turns staging on when
193      // a change needs watching there first; =false silences production.
194      (function () {
195        var mode = "production";
196        var override = "%VITE_POSTHOG_ENABLED%";
197        if (override.charAt(0) === "%") override = "";
198        var enabled =
199          override === "true" || (override !== "false" && mode === "production");
200        if (enabled || window.__rmeSensitiveRoute) return;
201
202        window.__rmePostHogOff = true;
203        // Same inert stub the sensitive-route guard installs, so first-party
204        // code that reaches for window.posthog finds something harmless.
205        var noop = function () {};
206        window.posthog = {
207          capture: noop,
208          captureException: noop,
209          identify: noop,
210          reset: noop,
211          register: noop,
212          unregister: noop,
213          isFeatureEnabled: function () { return false; },
214        };
215      })();
216
217      if (!window.__rmeSensitiveRoute && !window.__rmePostHogOff) {
218        // The browser raises "ResizeObserver loop completed with undelivered
219        // notifications." when an observer callback changes layout in the same
220        // frame. It is non-fatal by spec and nothing PostHog can act on.
221        // NOISE_EXCEPTIONS below already keeps it from being sent, but that is
222        // not enough: posthog-js rate-limits exceptions per type *before*
223        // before_send runs (a bucket of 10 per type, refilled one token per
224        // 10s), every one of these warnings is type "Error" like most real
225        // bugs, and the review page emits them in bursts while its panes
226        // resize. One burst empties the bucket and the next real error is
227        // dropped unseen. Stopping the event here, ahead of the window.onerror
228        // hook PostHog installs, keeps it out of that budget. The browser still
229        // logs the warning to the console, and nothing else is affected: the
230        // check is an exact message prefix and never touches the posthog
231        // global, so a blocker removing it changes nothing.
232        window.addEventListener(
233          "error",
234          function (event) {
235            var message = event && event.message;
236            if (
237              typeof message === "string" &&
238              message.indexOf("ResizeObserver loop") === 0
239            ) {
240              event.stopImmediatePropagation();
241            }
242          },
243          true
244        );
245
246        !(function (t, e) {
247          var o, n, p, r;
248          e.__SV ||
249            ((window.posthog = e),
250          (e._i = []),
251          (e.init = function (i, s, a) {
252            function g(t, e) {
253              var o = e.split(".");
254              2 == o.length && ((t = t[o[0]]), (e = o[1])),
255                (t[e] = function () {
256                  t.push([e].concat(Array.prototype.slice.call(arguments, 0)));
257                });
258            }
259            ((p = t.createElement("script")).type = "text/javascript"),
260              (p.async = !0),
261              (p.src = s.api_host + "/static/array.js"),
262              (r = t.getElementsByTagName("script")[0]).parentNode.insertBefore(
263                p,
264                r
265              );
266            var u = e;
267            for (
268              void 0 !== a ? (u = e[a] = []) : (a = "posthog"),
269                u.people = u.people || [],
270                u.toString = function (t) {
271                  var e = "posthog";
272                  return (
273                    "posthog" !== a && (e += "." + a), t || (e += " (stub)"), e
274                  );
275                },
276                u.people.toString = function () {
277                  return u.toString(1) + ".people (stub)";
278                },
279                o =
280                  "capture captureException identify alias people.set people.set_once set_config register register_once unregister opt_out_capturing has_opted_out_capturing opt_in_capturing reset isFeatureEnabled onFeatureFlags".split(
281                    " "
282                  ),
283                n = 0;
284              n < o.length;
285              n++
286            )
287              g(u, o[n]);
288            e._i.push([i, s, a]);
289          }),
290            (e.__SV = 1));
291        })(document, window.posthog || []);
292        posthog.init("phc_79EH3wT90EYwTJUYvIOwvTXnkhwkoC6rO972Qw5bf7X", {
293          api_host: "https://app.posthog.com",
294          // Unrestricted autocapture reported a click on every element, so most
295          // events were "div clicked" / "h3 clicked" with no answerable question
296          // behind them. Buttons and links keep a safety net for interactions
297          // nobody has instrumented explicitly; anything worth a funnel should
298          // be an explicit capture (see helpers/analytics.js).
299          autocapture: { element_allowlist: ["button", "a"] },
300          // Error tracking. Replaces Rollbar, whose client half had been
301          // commented out in main.js long enough that nobody was watching it.
302          // Covers window.onerror and unhandledrejection; Vue's own render
303          // errors don't reach either, so main.js reports those explicitly.
304          capture_exceptions: true,
305          before_send: dropNoiseExceptions,
306        });
307      }
308
309      // Exceptions nobody can act on. Each of these was a top issue in PostHog
310      // while real bugs sat below them, so they are dropped at the source
311      // rather than suppressed one issue at a time in the dashboard.
312      // Everything else — including anything new — still goes through.
313      var NOISE_EXCEPTIONS = [
314        // Browser-internal, fires when a layout settles in the same frame it
315        // was observed. Harmless and unfixable from application code.
316        /^ResizeObserver loop/,
317        // Microsoft SafeLinks / Outlook link scanner evaluating the page,
318        // not a person.
319        /Object Not Found Matching Id/,
320        // The user navigated away, went offline, or the request was cancelled.
321        // Server faults show up as 5xx and uptime alerts, not here.
322        /^Request aborted$/,
323        /^Network Error$/,
324        /^timeout of \d+ms exceeded$/,
325        /^canceled$/i,
326        // 4xx is the client asking for something it may not have — an expired
327        // session, a revoked reviewer — and is answered in the UI, not by us.
328        // Same rule as helpers/apiErrorReporting.js.
329        /^Request failed with status code 4\d\d$/,
330        // A cross-origin script threw and the browser withheld every detail.
331        /^Script error\.?$/,
332        // A tab open since before a deploy still references the PREVIOUS build's
333        // content-hashed filenames; once the new build replaces them in
334        // server/public/site, that tab's next lazy-loaded route 404s trying to
335        // preload/import a chunk that no longer exists. Unfixable from application
336        // code — the fix is the user's next navigation or refresh, which requests
337        // the current index.html and gets the current hashes. Recurs after every
338        // deploy for whoever has a stale tab open, same as ResizeObserver recurs
339        // for whoever resizes a pane.
340        /^Unable to preload CSS for /,
341        /^Failed to fetch dynamically imported module/,
342        /^error loading dynamically imported module/,
343        /^Importing a module script failed$/,
344      ];
345
346      function dropNoiseExceptions(event) {
347        if (!event || event.event !== "$exception") return event;
348        var props = event.properties || {};
349        var list = props.$exception_list || [];
350        var messages = [];
351        for (var i = 0; i < list.length; i++) {
352          if (list[i] && list[i].value) messages.push(String(list[i].value));
353        }
354        if (props.$exception_message) {
355          messages.push(String(props.$exception_message));
356        }
357        for (var m = 0; m < messages.length; m++) {
358          for (var n = 0; n < NOISE_EXCEPTIONS.length; n++) {
359            if (NOISE_EXCEPTIONS[n].test(messages[m])) return null;
360          }
361        }
362        if (onlyInjectedFrames(list)) return null;
363        return event;
364      }
365
366      // Code a browser-automation tool or extension injects into the page runs
367      // with no source file, so every one of its stack frames reads "<anonymous>".
368      // A scanner from a cloud data centre did this on 24 Sep 2026: its own
369      // injected fetch hook failed, seven times in one burst, as unhandled
370      // "Failed to fetch" on our homepage. Our code always has at least one frame
371      // from a real file (the bundle, or index.html for inline scripts), so a
372      // real bug is never dropped by this; an exception with no frames is kept.
373      function onlyInjectedFrames(list) {
374        var seen = 0;
375        for (var i = 0; i < list.length; i++) {
376          var frames = (list[i] && list[i].stacktrace && list[i].stacktrace.frames) || [];
377          for (var j = 0; j < frames.length; j++) {
378            if (!frames[j] || frames[j].filename !== "<anonymous>") return false;
379            seen++;
380          }
381        }
382        return seen > 0;
383      }
384    </script>
384
385    
385<script async type="module" crossorigin src="/assets/index-BzauN4-I.js"></script>
385
386    <link rel="stylesheet" crossorigin href="/assets/index-CriZp4VY.css">
387  </head>
388  <body class="">
389    <div id="app" class="flex flex-col min-h-screen"></div>
390    <noscript>
391      <h1>Review My eLearning</h1>
392      <p>
393        Course review for eLearning teams. Upload a SCORM or HTML5 course from any
394        authoring tool, including courses written by AI, invite reviewers, and every
395        comment lands on the exact screen as a tracked, assignable work item.
396      </p>
397      <p>
398        A built-in MCP server lets Claude, ChatGPT and other MCP-capable AI assistants
399        read your review data, publish courses and request AI reviews.
400      </p>
401      <p>
402        <a href="/features">Features</a> · <a href="/pricing">Pricing</a> ·
403        <a href="/docs/mcp">Connect an AI assistant</a> ·
404        <a href="/docs/course-ingest-api">Course Ingest API</a> ·
405        <a href="/llms.txt">llms.txt</a>
406      </p>
407    </noscript>
408    
408<script type="text/javascript">
409      if (!window.__rmeSensitiveRoute) {
410        _linkedin_partner_id = "15600";
411        window._linkedin_data_partner_ids =
412          window._linkedin_data_partner_ids || [];
413        window._linkedin_data_partner_ids.push(_linkedin_partner_id);
414      }
415    </script>
415
416    
416<script type="text/javascript">
417      (function (l) {
418        // The queue stub always exists: app code calls lintrk() directly. The
419        // Insight script only loads in production, so staging and local clicks
420        // stay out of the ad data (and out of the console: its beta build logs
421        // a CORS failure on every page).
422        if (!l) {
423          window.lintrk = function (a, b) {
424            window.lintrk.q.push([a, b]);
425          };
426          window.lintrk.q = [];
427        }
428        if (window.__rmeSensitiveRoute || "production" !== "production") return;
429        var s = document.getElementsByTagName("script")[0];
430        var b = document.createElement("script");
431        b.type = "text/javascript";
432        b.async = true;
433        b.defer = true;
434        b.src = "https://snap.licdn.com/li.lms-analytics/insight.min.js";
435        s.parentNode.insertBefore(b, s);
436      })(window.lintrk);
437    </script>
437
438    <!-- Start of Customer.io Embed Code -->
439    
439<script type="text/javascript">
440      if (!window.__rmeSensitiveRoute) {
441        var _cio = _cio || [];
442        (function() {
443        var a,b,c;a=function(f){return function(){_cio.push([f].concat(Array.prototype.slice.call(arguments,0)))}};
444        b=["load","identify","sidentify","track","page","on","off"];for(c=0;c<b.length;c++){_cio[b[c]]=a(b[c])};
445        var t = document.createElement('script'),
446            s = document.getElementsByTagName('script')[0];
447        t.async = true;
448        t.id    = 'cio-tracker';
449        t.setAttribute('data-site-id', '84b6358f268101f27a2d');
450        t.setAttribute('data-use-array-params', 'true');
451        t.src = 'https://assets.customer.io/assets/track.js';
452        s.parentNode.insertBefore(t, s);
453        })();
454      }
455    </script>
455
456    <!-- End of Customer.io Embed Code -->
457  
457<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"eaa252c02a1743b781c7b73eab860450","r":1,"spa":2}' crossorigin="anonymous"></script>
457
458</body>
459</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.