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.