[{"data":1,"prerenderedAt":2108},["ShallowReactive",2],{"navLinks":3,"sidebar_docs_navigation_\u002Fdocs\u002Fauth-h3client":64,"navigation":217,"navLinks_footer":829,"\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fbot-detection_page":842,"\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fbot-detection_surround":1586,"\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fbot-detection":1589},{"id":4,"extension":5,"links":6,"meta":61,"stem":62,"__hash__":63},"navigationMenu\u002Fnavigation.json","json",[7,52,57],{"nested":8,"label":9,"icon":10,"to":11,"children":12},true,"Docs","i-lucide-book-open","\u002Fdocs\u002Fgetting-started",[13,19,26,32,39,45],{"label":14,"icon":15,"to":11,"description":16,"github":17,"badge":18},"Getting Started","i-lucide-rocket","An introduction to help you understand the core components.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Fdocshub","Start Here",{"label":20,"icon":21,"to":22,"description":23,"github":24,"badge":25},"Auth H3 Client","i-lucide-key-round","\u002Fdocs\u002Fauth-h3client","Seamlessly enforce OAuth 2.0 authentication and session management integrated directly as the client of the IAM module.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Fauth-h3client","Core",{"label":27,"icon":28,"to":29,"description":30,"github":31,"badge":25},"IAM","i-lucide-shield-check","\u002Fdocs\u002Fiam","Identity and Access Management featuring granular roles, permissions, and security policies.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Fauth",{"label":33,"icon":34,"to":35,"description":36,"github":37,"badge":38},"Bot Detection","i-lucide-cpu","\u002Fdocs\u002Fbot-detection","Advanced behavioral analysis and request fingerprinting to stop malicious automated traffic.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Fbot-detector","Security",{"label":40,"icon":41,"to":42,"description":43,"github":44,"badge":38},"Shield Base","i-lucide-database-zap","\u002Fdocs\u002Fshield-base","CLI and programmatic toolkit for compiling offline-ready IP intelligence databases from BGP, GeoIP, Tor, FireHOL, and other public threat feeds.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Fshield-base-cli",{"label":46,"icon":47,"to":48,"description":49,"github":50,"badge":51},"Utils","i-lucide-wrench","\u002Fdocs\u002Futils","A standard library of highly optimized helpers for formatting, validation, and core logic.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Futils","Library",{"nested":53,"label":54,"icon":55,"to":56},false,"Blog","i-lucide-pen-line","\u002Fblog",{"nested":53,"label":58,"icon":59,"to":60},"Website","lucide:app-window-mac","https:\u002F\u002Friavzon.com",{},"navigation","gkaQ0xRGxSLrLyM3kttLe0oBwkrR1EBjlepF8LSbwF8",[65],{"title":9,"path":66,"stem":67,"children":68,"page":53},"\u002Fdocs","docs",[69],{"title":20,"path":22,"stem":70,"children":71},"docs\u002Fauth-h3client\u002Findex",[72,73,82,119,145,167,170,191,195],{"title":20,"path":22,"stem":70},{"title":14,"path":74,"stem":75,"children":76},"\u002Fdocs\u002Fauth-h3client\u002Fgetting-started","docs\u002Fauth-h3client\u002F00.getting-started\u002Findex",[77,78],{"title":14,"path":74,"stem":75},{"title":79,"path":80,"stem":81},"Nuxt Module","\u002Fdocs\u002Fauth-h3client\u002Fgetting-started\u002Fnuxt","docs\u002Fauth-h3client\u002F00.getting-started\u002F00.nuxt",{"title":83,"path":84,"stem":85,"children":86},"Essentials","\u002Fdocs\u002Fauth-h3client\u002Fessentials","docs\u002Fauth-h3client\u002F01.essentials\u002Findex",[87,88,92,96,100,104,108,111,115],{"title":83,"path":84,"stem":85},{"title":89,"path":90,"stem":91},"Session Management","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fsession","docs\u002Fauth-h3client\u002F01.essentials\u002F00.session",{"title":93,"path":94,"stem":95},"Route Protection","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Froute-protection","docs\u002Fauth-h3client\u002F01.essentials\u002F01.route-protection",{"title":97,"path":98,"stem":99},"CSRF Protection","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fcsrf","docs\u002Fauth-h3client\u002F01.essentials\u002F02.csrf",{"title":101,"path":102,"stem":103},"Auth Flows","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fauth-flows","docs\u002Fauth-h3client\u002F01.essentials\u002F03.auth-flows",{"title":105,"path":106,"stem":107},"OAuth and OIDC","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Foauth","docs\u002Fauth-h3client\u002F01.essentials\u002F04.oauth",{"title":33,"path":109,"stem":110},"\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fbot-detection","docs\u002Fauth-h3client\u002F01.essentials\u002F05.bot-detection",{"title":112,"path":113,"stem":114},"Cookies","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fcookies","docs\u002Fauth-h3client\u002F01.essentials\u002F06.cookies",{"title":116,"path":117,"stem":118},"Logging","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Flogging","docs\u002Fauth-h3client\u002F01.essentials\u002F07.logging",{"title":120,"path":121,"stem":122,"children":123},"MFA","\u002Fdocs\u002Fauth-h3client\u002Fmfa","docs\u002Fauth-h3client\u002F02.mfa\u002Findex",[124,125,129,133,137,141],{"title":120,"path":121,"stem":122},{"title":126,"path":127,"stem":128},"Built-in MFA","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fbuilt-in-flow","docs\u002Fauth-h3client\u002F02.mfa\u002F01.built-in-flow",{"title":130,"path":131,"stem":132},"Password Reset","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fpassword-reset","docs\u002Fauth-h3client\u002F02.mfa\u002F02.password-reset",{"title":134,"path":135,"stem":136},"Email Change","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Femail-change","docs\u002Fauth-h3client\u002F02.mfa\u002F03.email-change",{"title":138,"path":139,"stem":140},"Custom MFA Flow","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fcustom-flow","docs\u002Fauth-h3client\u002F02.mfa\u002F04.custom-flow",{"title":142,"path":143,"stem":144},"Client-Side MFA","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fclient-side","docs\u002Fauth-h3client\u002F02.mfa\u002F05.client-side",{"title":146,"path":147,"stem":148,"children":149},"Client-side","\u002Fdocs\u002Fauth-h3client\u002Fclient","docs\u002Fauth-h3client\u002F03.client\u002Findex",[150,151,155,159,163],{"title":146,"path":147,"stem":148},{"title":152,"path":153,"stem":154},"useAuthData","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fuse-auth-data","docs\u002Fauth-h3client\u002F03.client\u002F00.use-auth-data",{"title":156,"path":157,"stem":158},"useMagicLink","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fuse-magic-link","docs\u002Fauth-h3client\u002F03.client\u002F01.use-magic-link",{"title":160,"path":161,"stem":162},"executeRequest","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fexecute-request","docs\u002Fauth-h3client\u002F03.client\u002F02.execute-request",{"title":164,"path":165,"stem":166},"getCsrfToken","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fget-csrf-token","docs\u002Fauth-h3client\u002F03.client\u002F03.get-csrf-token",{"title":38,"path":168,"stem":169},"\u002Fdocs\u002Fauth-h3client\u002Fsecurity","docs\u002Fauth-h3client\u002F04.security",{"title":171,"path":172,"stem":173,"children":174,"page":53},"Guides","\u002Fdocs\u002Fauth-h3client\u002Fguides","docs\u002Fauth-h3client\u002F05.guides",[175,179,183,187],{"title":176,"path":177,"stem":178},"H3 and Nitro Setup","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fh3-nitro","docs\u002Fauth-h3client\u002F05.guides\u002F00.h3-nitro",{"title":180,"path":181,"stem":182},"HMAC Inter-service Auth","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fhmac","docs\u002Fauth-h3client\u002F05.guides\u002Fhmac",{"title":184,"path":185,"stem":186},"Image Upload","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fimage-upload","docs\u002Fauth-h3client\u002F05.guides\u002Fimage-upload",{"title":188,"path":189,"stem":190},"mTLS Configuration","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fmtls","docs\u002Fauth-h3client\u002F05.guides\u002Fmtls",{"title":192,"path":193,"stem":194},"Configuration","\u002Fdocs\u002Fauth-h3client\u002Fconfiguration","docs\u002Fauth-h3client\u002F06.configuration",{"title":196,"path":197,"stem":198,"children":199},"API Reference","\u002Fdocs\u002Fauth-h3client\u002Fapi","docs\u002Fauth-h3client\u002F07.api\u002Findex",[200,201,205,209,213],{"title":196,"path":197,"stem":198},{"title":202,"path":203,"stem":204},"Routes Reference","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Fcontrollers","docs\u002Fauth-h3client\u002F07.api\u002F00.controllers",{"title":206,"path":207,"stem":208},"Middleware Reference","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Fmiddleware","docs\u002Fauth-h3client\u002F07.api\u002F01.middleware",{"title":210,"path":211,"stem":212},"Client-side Reference","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Fcomposables","docs\u002Fauth-h3client\u002F07.api\u002F02.composables",{"title":214,"path":215,"stem":216},"Utilities","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Futilities","docs\u002Fauth-h3client\u002F07.api\u002F03.utilities",[218],{"title":9,"path":66,"stem":67,"children":219,"page":53},[220,268,386,391,569,636],{"title":20,"path":22,"stem":70,"children":221},[222,223,227,238,246,253,254,260,261],{"title":20,"path":22,"stem":70},{"title":14,"path":74,"stem":75,"children":224},[225,226],{"title":14,"path":74,"stem":75},{"title":79,"path":80,"stem":81},{"title":83,"path":84,"stem":85,"children":228},[229,230,231,232,233,234,235,236,237],{"title":83,"path":84,"stem":85},{"title":89,"path":90,"stem":91},{"title":93,"path":94,"stem":95},{"title":97,"path":98,"stem":99},{"title":101,"path":102,"stem":103},{"title":105,"path":106,"stem":107},{"title":33,"path":109,"stem":110},{"title":112,"path":113,"stem":114},{"title":116,"path":117,"stem":118},{"title":120,"path":121,"stem":122,"children":239},[240,241,242,243,244,245],{"title":120,"path":121,"stem":122},{"title":126,"path":127,"stem":128},{"title":130,"path":131,"stem":132},{"title":134,"path":135,"stem":136},{"title":138,"path":139,"stem":140},{"title":142,"path":143,"stem":144},{"title":146,"path":147,"stem":148,"children":247},[248,249,250,251,252],{"title":146,"path":147,"stem":148},{"title":152,"path":153,"stem":154},{"title":156,"path":157,"stem":158},{"title":160,"path":161,"stem":162},{"title":164,"path":165,"stem":166},{"title":38,"path":168,"stem":169},{"title":171,"path":172,"stem":173,"children":255,"page":53},[256,257,258,259],{"title":176,"path":177,"stem":178},{"title":180,"path":181,"stem":182},{"title":184,"path":185,"stem":186},{"title":188,"path":189,"stem":190},{"title":192,"path":193,"stem":194},{"title":196,"path":197,"stem":198,"children":262},[263,264,265,266,267],{"title":196,"path":197,"stem":198},{"title":202,"path":203,"stem":204},{"title":206,"path":207,"stem":208},{"title":210,"path":211,"stem":212},{"title":214,"path":215,"stem":216},{"title":269,"path":35,"stem":270,"children":271},"Bot Detector","docs\u002Fbot-detection\u002Findex",[272,273,276,280,284,303,377,380,383],{"title":269,"path":35,"stem":270},{"title":14,"path":274,"stem":275},"\u002Fdocs\u002Fbot-detection\u002Fgetting-started","docs\u002Fbot-detection\u002F00.getting-started",{"title":277,"path":278,"stem":279},"CLI","\u002Fdocs\u002Fbot-detection\u002Fcli","docs\u002Fbot-detection\u002F01.cli",{"title":281,"path":282,"stem":283},"Data Sources","\u002Fdocs\u002Fbot-detection\u002Fdata-sources","docs\u002Fbot-detection\u002F02.data-sources",{"title":171,"path":285,"stem":286,"children":287,"page":53},"\u002Fdocs\u002Fbot-detection\u002Fguides","docs\u002Fbot-detection\u002F03.guides",[288,292,296,299],{"title":289,"path":290,"stem":291},"Custom Checkers","\u002Fdocs\u002Fbot-detection\u002Fguides\u002Fcustom","docs\u002Fbot-detection\u002F03.guides\u002FCUSTOM",{"title":293,"path":294,"stem":295},"Scheduling Database Generation","\u002Fdocs\u002Fbot-detection\u002Fguides\u002Fgenerate","docs\u002Fbot-detection\u002F03.guides\u002FGENERATE",{"title":116,"path":297,"stem":298},"\u002Fdocs\u002Fbot-detection\u002Fguides\u002Flogging","docs\u002Fbot-detection\u002F03.guides\u002FLOGGING",{"title":300,"path":301,"stem":302},"Score Modes and Reputation Healing","\u002Fdocs\u002Fbot-detection\u002Fguides\u002Fscore","docs\u002Fbot-detection\u002F03.guides\u002FSCORE",{"title":304,"path":305,"stem":306,"children":307},"Checkers","\u002Fdocs\u002Fbot-detection\u002Fcheckers","docs\u002Fbot-detection\u002F04.checkers\u002Findex",[308,309,313,317,321,325,329,333,337,341,345,349,353,357,361,365,369,373],{"title":304,"path":305,"stem":306},{"title":310,"path":311,"stem":312},"IP Validation","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fip-validation","docs\u002Fbot-detection\u002F04.checkers\u002F01.ip-validation",{"title":314,"path":315,"stem":316},"Good \u002F Bad Bot Verification","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fgood-bots","docs\u002Fbot-detection\u002F04.checkers\u002F02.good-bots",{"title":318,"path":319,"stem":320},"Browser & Device Fingerprint","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fbrowser-device","docs\u002Fbot-detection\u002F04.checkers\u002F03.browser-device",{"title":322,"path":323,"stem":324},"Locale Map","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Flocale-map","docs\u002Fbot-detection\u002F04.checkers\u002F04.locale-map",{"title":326,"path":327,"stem":328},"Known Threats","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fknown-threats","docs\u002Fbot-detection\u002F04.checkers\u002F05.known-threats",{"title":330,"path":331,"stem":332},"ASN Classification","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fasn-classification","docs\u002Fbot-detection\u002F04.checkers\u002F06.asn-classification",{"title":334,"path":335,"stem":336},"Tor Analysis","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Ftor-analysis","docs\u002Fbot-detection\u002F04.checkers\u002F07.tor-analysis",{"title":338,"path":339,"stem":340},"Timezone Consistency","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Ftimezone-consistency","docs\u002Fbot-detection\u002F04.checkers\u002F08.timezone-consistency",{"title":342,"path":343,"stem":344},"Honeypot","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fhoneypot","docs\u002Fbot-detection\u002F04.checkers\u002F09.honeypot",{"title":346,"path":347,"stem":348},"Known Bad IPs","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fknown-bad-ips","docs\u002Fbot-detection\u002F04.checkers\u002F10.known-bad-ips",{"title":350,"path":351,"stem":352},"Behavior Rate","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fbehavior-rate","docs\u002Fbot-detection\u002F04.checkers\u002F11.behavior-rate",{"title":354,"path":355,"stem":356},"Proxy \u002F ISP \u002F Cookie","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fproxy-isp-cookies","docs\u002Fbot-detection\u002F04.checkers\u002F12.proxy-isp-cookies",{"title":358,"path":359,"stem":360},"Session Coherence","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fsession-coherence","docs\u002Fbot-detection\u002F04.checkers\u002F13.session-coherence",{"title":362,"path":363,"stem":364},"Velocity Fingerprint","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fvelocity-fingerprint","docs\u002Fbot-detection\u002F04.checkers\u002F14.velocity-fingerprint",{"title":366,"path":367,"stem":368},"UA & Header Analysis","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fua-header","docs\u002Fbot-detection\u002F04.checkers\u002F15.ua-header",{"title":370,"path":371,"stem":372},"Geolocation","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fgeolocation","docs\u002Fbot-detection\u002F04.checkers\u002F16.geolocation",{"title":374,"path":375,"stem":376},"Known Bad User-Agents","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fknown-bad-ua","docs\u002Fbot-detection\u002F04.checkers\u002F17.known-bad-ua",{"title":38,"path":378,"stem":379},"\u002Fdocs\u002Fbot-detection\u002Fsecurity","docs\u002Fbot-detection\u002F04.security",{"title":196,"path":381,"stem":382},"\u002Fdocs\u002Fbot-detection\u002Fapi","docs\u002Fbot-detection\u002F05.api",{"title":192,"path":384,"stem":385},"\u002Fdocs\u002Fbot-detection\u002Fconfiguration","docs\u002Fbot-detection\u002F06.configuration",{"title":387,"path":11,"stem":388,"children":389},"Introduction","docs\u002Fgetting-started\u002Findex",[390],{"title":387,"path":11,"stem":388},{"title":27,"path":29,"stem":392,"children":393},"docs\u002Fiam\u002Findex",[394,395,398,533,536,552,555],{"title":27,"path":29,"stem":392},{"title":14,"path":396,"stem":397},"\u002Fdocs\u002Fiam\u002Fgetting-started","docs\u002Fiam\u002F00.getting-started",{"title":83,"path":399,"stem":400,"children":401},"\u002Fdocs\u002Fiam\u002Fessentials","docs\u002Fiam\u002F01.essentials\u002Findex",[402,403,407,411,415,419,423,427,431,435,439,443,446,450,454,458,462,465,469,473,476,480,483],{"title":83,"path":399,"stem":400},{"title":404,"path":405,"stem":406},"Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Ftokens","docs\u002Fiam\u002F01.essentials\u002F00.tokens",{"title":408,"path":409,"stem":410},"Access Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Faccess-tokens","docs\u002Fiam\u002F01.essentials\u002F01.access-tokens",{"title":412,"path":413,"stem":414},"Refresh Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Frefresh-tokens","docs\u002Fiam\u002F01.essentials\u002F02.refresh-tokens",{"title":416,"path":417,"stem":418},"Anomaly Detection","\u002Fdocs\u002Fiam\u002Fessentials\u002Fanomalies","docs\u002Fiam\u002F01.essentials\u002F03.anomalies",{"title":420,"path":421,"stem":422},"Signup","\u002Fdocs\u002Fiam\u002Fessentials\u002Fsignup","docs\u002Fiam\u002F01.essentials\u002F04.signup",{"title":424,"path":425,"stem":426},"Login","\u002Fdocs\u002Fiam\u002Fessentials\u002Flogin","docs\u002Fiam\u002F01.essentials\u002F05.login",{"title":428,"path":429,"stem":430},"Logout","\u002Fdocs\u002Fiam\u002Fessentials\u002Flogout","docs\u002Fiam\u002F01.essentials\u002F06.logout",{"title":432,"path":433,"stem":434},"OAuth","\u002Fdocs\u002Fiam\u002Fessentials\u002Foauth","docs\u002Fiam\u002F01.essentials\u002F07.oauth",{"title":436,"path":437,"stem":438},"Magic Links","\u002Fdocs\u002Fiam\u002Fessentials\u002Fmagic-links","docs\u002Fiam\u002F01.essentials\u002F08.magic-links",{"title":440,"path":441,"stem":442},"Emails","\u002Fdocs\u002Fiam\u002Fessentials\u002Femails","docs\u002Fiam\u002F01.essentials\u002F09.emails",{"title":120,"path":444,"stem":445},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fmfa","docs\u002Fiam\u002F01.essentials\u002F10.mfa",{"title":447,"path":448,"stem":449},"Fingerprinting","\u002Fdocs\u002Fiam\u002Fessentials\u002Ffingerprinting","docs\u002Fiam\u002F01.essentials\u002F11.fingerprinting",{"title":451,"path":452,"stem":453},"Backend for Frontend","\u002Fdocs\u002Fiam\u002Fessentials\u002Fbff","docs\u002Fiam\u002F01.essentials\u002F12.bff",{"title":455,"path":456,"stem":457},"HMAC Authentication","\u002Fdocs\u002Fiam\u002Fessentials\u002Fhmac","docs\u002Fiam\u002F01.essentials\u002F13.hmac",{"title":459,"path":460,"stem":461},"XSS Protection","\u002Fdocs\u002Fiam\u002Fessentials\u002Fxss","docs\u002Fiam\u002F01.essentials\u002F14.xss",{"title":116,"path":463,"stem":464},"\u002Fdocs\u002Fiam\u002Fessentials\u002Flogging","docs\u002Fiam\u002F01.essentials\u002F15.logging",{"title":466,"path":467,"stem":468},"Rate Limiting","\u002Fdocs\u002Fiam\u002Fessentials\u002Frate-limiting","docs\u002Fiam\u002F01.essentials\u002F16.rate-limiting",{"title":470,"path":471,"stem":472},"Database","\u002Fdocs\u002Fiam\u002Fessentials\u002Fdatabase","docs\u002Fiam\u002F01.essentials\u002F17.database",{"title":112,"path":474,"stem":475},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fcookies","docs\u002Fiam\u002F01.essentials\u002F18.cookies",{"title":477,"path":478,"stem":479},"Service Startup","\u002Fdocs\u002Fiam\u002Fessentials\u002Fservice","docs\u002Fiam\u002F01.essentials\u002F19.service",{"title":130,"path":481,"stem":482},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fpassword-reset","docs\u002Fiam\u002F01.essentials\u002F20.password-reset",{"title":484,"path":485,"stem":486,"children":487},"API Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi","docs\u002Fiam\u002F01.essentials\u002F21.api\u002Findex",[488,489,493,497,527,530],{"title":484,"path":485,"stem":486},{"title":490,"path":491,"stem":492},"Creating Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fcreation","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F00.creation",{"title":494,"path":495,"stem":496},"Verifying Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fverification","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F01.verification",{"title":498,"path":499,"stem":500,"children":501},"Manage Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002Findex",[502,503,507,511,515,519,523],{"title":498,"path":499,"stem":500},{"title":504,"path":505,"stem":506},"Privileges","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Fprivilege","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F00.privilege",{"title":508,"path":509,"stem":510},"Revocation","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Frevocation","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F01.revocation",{"title":512,"path":513,"stem":514},"Rotation","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Frotation","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F02.rotation",{"title":516,"path":517,"stem":518},"IP Restriction","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Fip-updates","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F03.ip-updates",{"title":520,"path":521,"stem":522},"Metadata","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Fmetadata","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F04.metadata",{"title":524,"path":525,"stem":526},"Token Listing","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Flist","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F05.list",{"title":466,"path":528,"stem":529},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Frate-limiting","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F03.rate-limiting",{"title":38,"path":531,"stem":532},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fsecurity","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F04.security",{"title":38,"path":534,"stem":535},"\u002Fdocs\u002Fiam\u002Fsecurity","docs\u002Fiam\u002F02.security",{"title":171,"path":537,"stem":538,"children":539,"page":53},"\u002Fdocs\u002Fiam\u002Fguides","docs\u002Fiam\u002F03.guides",[540,544,548],{"title":541,"path":542,"stem":543},"Deployment","\u002Fdocs\u002Fiam\u002Fguides\u002Fdeployment","docs\u002Fiam\u002F03.guides\u002Fdeployment",{"title":545,"path":546,"stem":547},"Operation Scripts","\u002Fdocs\u002Fiam\u002Fguides\u002Foperation-scripts","docs\u002Fiam\u002F03.guides\u002Foperation-scripts",{"title":549,"path":550,"stem":551},"Role-Based Access Control","\u002Fdocs\u002Fiam\u002Fguides\u002Frbac","docs\u002Fiam\u002F03.guides\u002Frbac",{"title":192,"path":553,"stem":554},"\u002Fdocs\u002Fiam\u002Fconfiguration","docs\u002Fiam\u002F04.configuration",{"title":556,"path":557,"stem":558,"children":559,"page":53},"Api","\u002Fdocs\u002Fiam\u002Fapi","docs\u002Fiam\u002F05.API",[560,563,566],{"title":196,"path":561,"stem":562},"\u002Fdocs\u002Fiam\u002Fapi\u002Fapi","docs\u002Fiam\u002F05.API\u002F00.api",{"title":206,"path":564,"stem":565},"\u002Fdocs\u002Fiam\u002Fapi\u002Fmiddlewares","docs\u002Fiam\u002F05.API\u002F02.middlewares",{"title":202,"path":567,"stem":568},"\u002Fdocs\u002Fiam\u002Fapi\u002Froutes","docs\u002Fiam\u002F05.API\u002F03.routes",{"title":40,"path":42,"stem":570,"children":571},"docs\u002Fshield-base\u002Findex",[572,573,576,580,621,625,629,633],{"title":40,"path":42,"stem":570},{"title":14,"path":574,"stem":575},"\u002Fdocs\u002Fshield-base\u002Fgetting-started","docs\u002Fshield-base\u002F00.getting-started",{"title":577,"path":578,"stem":579},"CLI Reference","\u002Fdocs\u002Fshield-base\u002Fcli","docs\u002Fshield-base\u002F01.cli",{"title":281,"path":581,"stem":582,"children":583},"\u002Fdocs\u002Fshield-base\u002Fdata-sources","docs\u002Fshield-base\u002F02.data-sources\u002Findex",[584,585,589,593,597,601,605,609,613,617],{"title":281,"path":581,"stem":582},{"title":586,"path":587,"stem":588},"BGP \u002F ASN","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fbgp","docs\u002Fshield-base\u002F02.data-sources\u002Fbgp",{"title":590,"path":591,"stem":592},"City Geolocation","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fcity","docs\u002Fshield-base\u002F02.data-sources\u002Fcity",{"title":594,"path":595,"stem":596},"Country Geolocation","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fcountry","docs\u002Fshield-base\u002F02.data-sources\u002Fcountry",{"title":598,"path":599,"stem":600},"Verified Crawlers","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fcrawlers","docs\u002Fshield-base\u002F02.data-sources\u002Fcrawlers",{"title":602,"path":603,"stem":604},"Disposable Emails","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Femail","docs\u002Fshield-base\u002F02.data-sources\u002Femail",{"title":606,"path":607,"stem":608},"FireHOL Threat Intelligence","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Ffirehol","docs\u002Fshield-base\u002F02.data-sources\u002Ffirehol",{"title":610,"path":611,"stem":612},"Proxy Detection","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fproxy","docs\u002Fshield-base\u002F02.data-sources\u002Fproxy",{"title":614,"path":615,"stem":616},"Tor Nodes","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Ftor","docs\u002Fshield-base\u002F02.data-sources\u002Ftor",{"title":618,"path":619,"stem":620},"Suspicious User-Agents","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fuseragent","docs\u002Fshield-base\u002F02.data-sources\u002Fuseragent",{"title":622,"path":623,"stem":624},"Programmatic Usage","\u002Fdocs\u002Fshield-base\u002Fusage","docs\u002Fshield-base\u002F03.usage",{"title":626,"path":627,"stem":628},"Custom Data Sources","\u002Fdocs\u002Fshield-base\u002Fcustom-data-sources","docs\u002Fshield-base\u002F04.custom-data-sources",{"title":630,"path":631,"stem":632},"TypeScript Types","\u002Fdocs\u002Fshield-base\u002Ftypes","docs\u002Fshield-base\u002F05.types",{"title":196,"path":634,"stem":635},"\u002Fdocs\u002Fshield-base\u002Fapi","docs\u002Fshield-base\u002F06.api",{"title":214,"path":48,"stem":637,"children":638},"docs\u002Futils\u002Findex",[639,640,657,690,787],{"title":214,"path":48,"stem":637},{"title":641,"path":642,"stem":643,"children":644,"page":53},"Eslint","\u002Fdocs\u002Futils\u002Feslint","docs\u002Futils\u002Feslint",[645,649,653],{"title":646,"path":647,"stem":648},"React Config","\u002Fdocs\u002Futils\u002Feslint\u002Freact","docs\u002Futils\u002Feslint\u002Freact",{"title":650,"path":651,"stem":652},"TypeScript Config","\u002Fdocs\u002Futils\u002Feslint\u002Ftypescript","docs\u002Futils\u002Feslint\u002Ftypescript",{"title":654,"path":655,"stem":656},"Vue Config","\u002Fdocs\u002Futils\u002Feslint\u002Fvue","docs\u002Futils\u002Feslint\u002Fvue",{"title":658,"path":659,"stem":660,"children":661,"page":53},"Server","\u002Fdocs\u002Futils\u002Fserver","docs\u002Futils\u002Fserver",[662,666,670,674,678,682,686],{"title":663,"path":664,"stem":665},"Encryption","\u002Fdocs\u002Futils\u002Fserver\u002Fencryption","docs\u002Futils\u002Fserver\u002Fencryption",{"title":667,"path":668,"stem":669},"Path Resolver","\u002Fdocs\u002Futils\u002Fserver\u002Fpathresolver","docs\u002Futils\u002Fserver\u002FpathResolver",{"title":671,"path":672,"stem":673},"File Replacements","\u002Fdocs\u002Futils\u002Fserver\u002Freplace","docs\u002Futils\u002Fserver\u002Freplace",{"title":675,"path":676,"stem":677},"run","\u002Fdocs\u002Futils\u002Fserver\u002Frun","docs\u002Futils\u002Fserver\u002Frun",{"title":679,"path":680,"stem":681},"scheduleTask","\u002Fdocs\u002Futils\u002Fserver\u002Fscheduletask","docs\u002Futils\u002Fserver\u002FscheduleTask",{"title":683,"path":684,"stem":685},"spawnRun","\u002Fdocs\u002Futils\u002Fserver\u002Fspawnrun","docs\u002Futils\u002Fserver\u002FspawnRun",{"title":687,"path":688,"stem":689},"uploadCsv","\u002Fdocs\u002Futils\u002Fserver\u002Fuploadcsv","docs\u002Futils\u002Fserver\u002FuploadCsv",{"title":691,"path":692,"stem":693,"children":694,"page":53},"Shared","\u002Fdocs\u002Futils\u002Fshared","docs\u002Futils\u002Fshared",[695,699,703,707,711,715,719,723,727,731,735,739,743,747,751,755,759,763,767,771,775,779,783],{"title":696,"path":697,"stem":698},"BatchQueue","\u002Fdocs\u002Futils\u002Fshared\u002Fbatchqueue","docs\u002Futils\u002Fshared\u002FbatchQueue",{"title":700,"path":701,"stem":702},"capitalize","\u002Fdocs\u002Futils\u002Fshared\u002Fcapitalize","docs\u002Futils\u002Fshared\u002Fcapitalize",{"title":704,"path":705,"stem":706},"chunkProcess","\u002Fdocs\u002Futils\u002Fshared\u002Fchunkprocess","docs\u002Futils\u002Fshared\u002FchunkProcess",{"title":708,"path":709,"stem":710},"cleanObject","\u002Fdocs\u002Futils\u002Fshared\u002Fcleanobject","docs\u002Futils\u002Fshared\u002FcleanObject",{"title":712,"path":713,"stem":714},"createConfigManager","\u002Fdocs\u002Futils\u002Fshared\u002Fconfigurationdefiner","docs\u002Futils\u002Fshared\u002FconfigurationDefiner",{"title":716,"path":717,"stem":718},"debounce","\u002Fdocs\u002Futils\u002Fshared\u002Fdebounce","docs\u002Futils\u002Fshared\u002Fdebounce",{"title":720,"path":721,"stem":722},"ensureArray","\u002Fdocs\u002Futils\u002Fshared\u002Fensurearray","docs\u002Futils\u002Fshared\u002FensureArray",{"title":724,"path":725,"stem":726},"fetchWithRetry","\u002Fdocs\u002Futils\u002Fshared\u002Ffetchwithretry","docs\u002Futils\u002Fshared\u002FfetchWithRetry",{"title":728,"path":729,"stem":730},"filterEmptyValues","\u002Fdocs\u002Futils\u002Fshared\u002Ffilteremptyvalues","docs\u002Futils\u002Fshared\u002FfilterEmptyValues",{"title":732,"path":733,"stem":734},"findStringsInObject","\u002Fdocs\u002Futils\u002Fshared\u002Ffindobjectvalues","docs\u002Futils\u002Fshared\u002FfindObjectValues",{"title":736,"path":737,"stem":738},"fisherYatesShuffle","\u002Fdocs\u002Futils\u002Fshared\u002Ffisheryatesshuffle","docs\u002Futils\u002Fshared\u002FfisherYatesShuffle",{"title":740,"path":741,"stem":742},"getRandomImage","\u002Fdocs\u002Futils\u002Fshared\u002Fgetrandomimage","docs\u002Futils\u002Fshared\u002FgetRandomImage",{"title":744,"path":745,"stem":746},"isObjectHasValues","\u002Fdocs\u002Futils\u002Fshared\u002Fisobjecthasvalues","docs\u002Futils\u002Fshared\u002FisObjectHasValues",{"title":748,"path":749,"stem":750},"isAsyncOrPromise","\u002Fdocs\u002Futils\u002Fshared\u002Fispromise","docs\u002Futils\u002Fshared\u002FisPromise",{"title":752,"path":753,"stem":754},"MiniCache","\u002Fdocs\u002Futils\u002Fshared\u002Fminicache","docs\u002Futils\u002Fshared\u002FminiCache",{"title":756,"path":757,"stem":758},"parseCookies","\u002Fdocs\u002Futils\u002Fshared\u002Fparserawcookies","docs\u002Futils\u002Fshared\u002FparseRawCookies",{"title":760,"path":761,"stem":762},"safeAction","\u002Fdocs\u002Futils\u002Fshared\u002Fpromiselocker","docs\u002Futils\u002Fshared\u002FpromiseLocker",{"title":764,"path":765,"stem":766},"Random","\u002Fdocs\u002Futils\u002Fshared\u002Frandom","docs\u002Futils\u002Fshared\u002Frandom",{"title":768,"path":769,"stem":770},"range","\u002Fdocs\u002Futils\u002Fshared\u002Frange","docs\u002Futils\u002Fshared\u002Frange",{"title":772,"path":773,"stem":774},"rateLimiters","\u002Fdocs\u002Futils\u002Fshared\u002Fratelimiters","docs\u002Futils\u002Fshared\u002FrateLimiters",{"title":776,"path":777,"stem":778},"safeObjectMerge","\u002Fdocs\u002Futils\u002Fshared\u002Fsafemerge","docs\u002Futils\u002Fshared\u002FsafeMerge",{"title":780,"path":781,"stem":782},"textTruncation","\u002Fdocs\u002Futils\u002Fshared\u002Ftexttruncation","docs\u002Futils\u002Fshared\u002FtextTruncation",{"title":784,"path":785,"stem":786},"validateZodSchema","\u002Fdocs\u002Futils\u002Fshared\u002Fvalidatezodschema","docs\u002Futils\u002Fshared\u002FvalidateZodSchema",{"title":788,"path":789,"stem":790,"children":791},"Utility Types","\u002Fdocs\u002Futils\u002Ftypes","docs\u002Futils\u002Ftypes\u002Findex",[792,793,797,801,805,809,813,817,821,825],{"title":788,"path":789,"stem":790},{"title":794,"path":795,"stem":796},"Brand","\u002Fdocs\u002Futils\u002Ftypes\u002Fbrand","docs\u002Futils\u002Ftypes\u002FBrand",{"title":798,"path":799,"stem":800},"DeepPartial","\u002Fdocs\u002Futils\u002Ftypes\u002Fdeeppartial","docs\u002Futils\u002Ftypes\u002FDeepPartial",{"title":802,"path":803,"stem":804},"Merge","\u002Fdocs\u002Futils\u002Ftypes\u002Fmerge","docs\u002Futils\u002Ftypes\u002FMerge",{"title":806,"path":807,"stem":808},"NonNullable","\u002Fdocs\u002Futils\u002Ftypes\u002Fnonnullable","docs\u002Futils\u002Ftypes\u002FNonNullable",{"title":810,"path":811,"stem":812},"Prettify","\u002Fdocs\u002Futils\u002Ftypes\u002Fprettify","docs\u002Futils\u002Ftypes\u002FPrettify",{"title":814,"path":815,"stem":816},"PromiseType","\u002Fdocs\u002Futils\u002Ftypes\u002Fpromisetype","docs\u002Futils\u002Ftypes\u002FPromiseType",{"title":818,"path":819,"stem":820},"RequireKeys","\u002Fdocs\u002Futils\u002Ftypes\u002Frequirekeys","docs\u002Futils\u002Ftypes\u002FRequireKeys",{"title":822,"path":823,"stem":824},"StandardResponse","\u002Fdocs\u002Futils\u002Ftypes\u002Fstandardresponse","docs\u002Futils\u002Ftypes\u002FStandardResponse",{"title":826,"path":827,"stem":828},"ValueOf","\u002Fdocs\u002Futils\u002Ftypes\u002Fvalueof","docs\u002Futils\u002Ftypes\u002FValueOf",{"id":4,"extension":5,"links":830,"meta":841,"stem":62,"__hash__":63},[831,839,840],{"nested":8,"label":9,"icon":10,"to":11,"children":832},[833,834,835,836,837,838],{"label":14,"icon":15,"to":11,"description":16,"github":17,"badge":18},{"label":20,"icon":21,"to":22,"description":23,"github":24,"badge":25},{"label":27,"icon":28,"to":29,"description":30,"github":31,"badge":25},{"label":33,"icon":34,"to":35,"description":36,"github":37,"badge":38},{"label":40,"icon":41,"to":42,"description":43,"github":44,"badge":38},{"label":46,"icon":47,"to":48,"description":49,"github":50,"badge":51},{"nested":53,"label":54,"icon":55,"to":56},{"nested":53,"label":58,"icon":59,"to":60},{},{"id":843,"title":33,"body":844,"description":1578,"extension":1579,"icon":1580,"meta":1581,"module":1582,"navigation":8,"path":109,"rawbody":1583,"seo":1584,"stem":110,"__hash__":1585},"docs\u002Fdocs\u002Fauth-h3client\u002F01.essentials\u002F05.bot-detection.md",{"type":845,"value":846,"toc":1570},"minimark",[847,855,858,863,887,893,896,934,936,941,953,955,960,969,1072,1092,1115,1118,1133,1149,1151,1157,1168,1482,1491,1497,1499,1504,1522,1525,1544,1554,1556,1560,1566],[848,849,850,851,854],"p",{},"The module integrates with the ",[852,853,269],"a",{"href":35}," pipeline running inside the IAM service. The gateway extracts the visitor fingerprint from each request and forwards it to the IAM service, which runs it through the full detection pipeline. Flagged visitors receive a 403 response at the gateway level. On Linux servers with UFW installed, banned IPs can be blocked at the firewall.",[856,857],"hr",{},[859,860,862],"h2",{"id":861},"global-middleware","Global middleware",[848,864,865,866,870,871,874,875,878,879,882,883,886],{},"The bot detection chain is wired as three separate global middlewares that run in order: ",[867,868,869],"code",{},"isIPValid",", ",[867,872,873],{},"botDetectorMiddleware",", and ",[867,876,877],{},"generateCsrfCookie",". Register them on your H3 app or Nitro instance as shown in the ",[852,880,881],{"href":177},"H3 or Nitro setup",". When using the Nuxt module with ",[867,884,885],{},"enableMiddleware: true",", the chain is registered automatically. The bot detection call happens before the CSRF cookie is issued, so flagged visitors never receive a valid session token.",[888,889,890],"warning",{},[848,891,892],{},"The bot detector in this module should be enabled by default, disabling it while using the IAM service will fail session rotation and verification.",[848,894,895],{},"The middleware skips processing for:",[897,898,899,906,913,924],"ul",{},[900,901,902,905],"li",{},[867,903,904],{},"HEAD"," requests",[900,907,908,909,912],{},"The ",[867,910,911],{},"\u002Fapi\u002Fhealth"," path",[900,914,915,916,919,920,923],{},"Framework internal paths starting with ",[867,917,918],{},"\u002F_nuxt"," or ",[867,921,922],{},"\u002Fapi\u002F_mdc"," (only relevant under Nuxt)",[900,925,926,927,919,930,933],{},"Requests with ",[867,928,929],{},"X-Forwarded-For: 127.0.0.1",[867,931,932],{},"::1"," (loopback, trusted internal traffic)",[856,935],{},[859,937,939],{"id":938},"isipvalid",[867,940,869],{},[848,942,943,945,946,949,950,952],{},[867,944,869],{}," extracts the client IP address from the request headers and validates it with ",[867,947,948],{},"net.isIP()",". This function does not make a network call. It runs as the first step of the middleware chain so that any request with an invalid or missing IP is rejected immediately with HTTP 403, before ",[867,951,873],{}," runs.",[856,954],{},[859,956,958],{"id":957},"botdetectormiddleware",[867,959,873],{},[848,961,962,964,965,968],{},[867,963,873],{}," forwards the visitor fingerprint to the IAM service ",[867,966,967],{},"\u002Fcheck"," endpoint. The IAM service runs the full Bot Detector pipeline and returns a bot score. When the score exceeds the ban threshold, the middleware throws HTTP 403.",[970,971,976],"pre",{"className":972,"code":973,"language":974,"meta":975,"style":975},"language-ts shiki shiki-themes light-plus light-plus dracula","\u002F\u002F The middleware is called automatically in the global middleware chain.\n\u002F\u002F To run it manually on a specific route:\nexport default defineEventHandler(async (event) => {\n  isIPValid(event)\n  await botDetectorMiddleware(event)\n  \u002F\u002F Proceed only if the visitor is not flagged\n})\n","ts","",[867,977,978,987,993,1031,1045,1060,1066],{"__ignoreMap":975},[979,980,983],"span",{"class":981,"line":982},"line",1,[979,984,986],{"class":985},"sghk6","\u002F\u002F The middleware is called automatically in the global middleware chain.\n",[979,988,990],{"class":981,"line":989},2,[979,991,992],{"class":985},"\u002F\u002F To run it manually on a specific route:\n",[979,994,996,1000,1003,1007,1011,1015,1018,1022,1025,1028],{"class":981,"line":995},3,[979,997,999],{"class":998},"sZ328","export",[979,1001,1002],{"class":998}," default",[979,1004,1006],{"class":1005},"sHOzp"," defineEventHandler",[979,1008,1010],{"class":1009},"sDd4n","(",[979,1012,1014],{"class":1013},"sl46w","async",[979,1016,1017],{"class":1009}," (",[979,1019,1021],{"class":1020},"sygFZ","event",[979,1023,1024],{"class":1009},") ",[979,1026,1027],{"class":1013},"=>",[979,1029,1030],{"class":1009}," {\n",[979,1032,1034,1037,1039,1042],{"class":981,"line":1033},4,[979,1035,1036],{"class":1005},"  isIPValid",[979,1038,1010],{"class":1009},[979,1040,1021],{"class":1041},"sjsA6",[979,1043,1044],{"class":1009},")\n",[979,1046,1048,1051,1054,1056,1058],{"class":981,"line":1047},5,[979,1049,1050],{"class":998},"  await",[979,1052,1053],{"class":1005}," botDetectorMiddleware",[979,1055,1010],{"class":1009},[979,1057,1021],{"class":1041},[979,1059,1044],{"class":1009},[979,1061,1063],{"class":981,"line":1062},6,[979,1064,1065],{"class":985},"  \u002F\u002F Proceed only if the visitor is not flagged\n",[979,1067,1069],{"class":981,"line":1068},7,[979,1070,1071],{"class":1009},"})\n",[848,1073,1074,1075,1077,1078,1081,1082,1084,1085,1088,1089,1091],{},"On the first request from a visitor, the middleware calls ",[867,1076,967],{}," and sets ",[867,1079,1080],{},"__Host-dr_i_n",", a signed host-only cookie that tracks the result. On subsequent requests where both ",[867,1083,1080],{}," and the ",[867,1086,1087],{},"canary_id"," cookie (issued by the IAM service) are present and the ",[867,1090,1080],{}," signature is valid, the middleware skips the IAM call and returns immediately. This avoids calling the full bot detection pipeline on every page view.",[848,1093,908,1094,1096,1097,1100,1101,870,1104,870,1107,1110,1111,1114],{},[867,1095,1080],{}," cookie is HMAC-signed using ",[867,1098,1099],{},"cryptoCookiesSecret"," and set with ",[867,1102,1103],{},"HttpOnly: true",[867,1105,1106],{},"SameSite: Strict",[867,1108,1109],{},"Secure: true",", and a 2-hour TTL. If the signature verification fails for any reason, the middleware returns HTTP 403 with code ",[867,1112,1113],{},"CANARY_TEMPERING",".",[848,1116,1117],{},"Bot detection is also skipped for static assets such as CSS, images, and font files, and for OAuth redirect routes.",[848,1119,1120,1121,1124,1125,1128,1129,1132],{},"When ",[867,1122,1123],{},"enableFireWallBans"," is ",[867,1126,1127],{},"true"," in the configuration and the visitor is flagged, ",[867,1130,1131],{},"banIp"," is called to add a UFW rule blocking the IP at the OS level.",[1134,1135,1136],"caution",{},[848,1137,1138,1140,1141,1144,1145,1148],{},[867,1139,1123],{}," requires a Linux environment with ",[867,1142,1143],{},"ufw"," installed and passwordless ",[867,1146,1147],{},"sudo"," configured for the Node.js process. Do not enable this on serverless or edge environments such as Vercel, Netlify, or Cloudflare Workers.",[856,1150],{},[859,1152,1154],{"id":1153},"checkforbots",[867,1155,1156],{},"checkForBots",[848,1158,1159,1161,1162,1164,1165,1167],{},[867,1160,1156],{}," is a low-level helper that calls the IAM ",[867,1163,967],{}," endpoint with a prepared signed cookie and visitor context. It is used internally by ",[867,1166,873],{}," and is exported for cases where you need to run the check with explicit control over the cookie and method, for example when building a custom middleware chain.",[970,1169,1171],{"className":972,"code":1170,"language":974,"meta":975,"style":975},"import { crypto } from 'node:crypto'\nimport { checkForBots, getLogger, createSignedValue } from 'auth-h3client\u002Fv2'\n\nconst log = getLogger().child({ service: 'api' })\nconst uuid = crypto.randomBytes(32).toString('hex')\nconst cookieValue = createSignedValue(uuid, 1000 * 60 * 60 * 2, 'normal')\n\nawait checkForBots(\n  { name: '__Host-dr_i_n', value: cookieValue },\n  event,\n  event.req.method,\n  log,\n  config.enableFireWallBans,\n  getCookie(event, 'canary_id')\n)\n",[867,1172,1173,1201,1230,1235,1278,1318,1366,1370,1382,1411,1420,1437,1445,1457,1477],{"__ignoreMap":975},[979,1174,1175,1178,1181,1184,1187,1190,1194,1198],{"class":981,"line":982},[979,1176,1177],{"class":998},"import",[979,1179,1180],{"class":1009}," { ",[979,1182,1183],{"class":1041},"crypto",[979,1185,1186],{"class":1009}," } ",[979,1188,1189],{"class":998},"from",[979,1191,1193],{"class":1192},"sFkSl"," '",[979,1195,1197],{"class":1196},"sFB1V","node:crypto",[979,1199,1200],{"class":1192},"'\n",[979,1202,1203,1205,1207,1209,1211,1214,1216,1219,1221,1223,1225,1228],{"class":981,"line":989},[979,1204,1177],{"class":998},[979,1206,1180],{"class":1009},[979,1208,1156],{"class":1041},[979,1210,870],{"class":1009},[979,1212,1213],{"class":1041},"getLogger",[979,1215,870],{"class":1009},[979,1217,1218],{"class":1041},"createSignedValue",[979,1220,1186],{"class":1009},[979,1222,1189],{"class":998},[979,1224,1193],{"class":1192},[979,1226,1227],{"class":1196},"auth-h3client\u002Fv2",[979,1229,1200],{"class":1192},[979,1231,1232],{"class":981,"line":995},[979,1233,1234],{"emptyLinePlaceholder":8},"\n",[979,1236,1237,1240,1244,1248,1251,1254,1257,1260,1263,1267,1269,1272,1275],{"class":981,"line":1033},[979,1238,1239],{"class":1013},"const",[979,1241,1243],{"class":1242},"s3JHE"," log",[979,1245,1247],{"class":1246},"saOXh"," =",[979,1249,1250],{"class":1005}," getLogger",[979,1252,1253],{"class":1009},"().",[979,1255,1256],{"class":1005},"child",[979,1258,1259],{"class":1009},"({ ",[979,1261,1262],{"class":1041},"service",[979,1264,1266],{"class":1265},"s34zl",":",[979,1268,1193],{"class":1192},[979,1270,1271],{"class":1196},"api",[979,1273,1274],{"class":1192},"'",[979,1276,1277],{"class":1009}," })\n",[979,1279,1280,1282,1285,1287,1290,1292,1295,1297,1301,1304,1307,1309,1311,1314,1316],{"class":981,"line":1047},[979,1281,1239],{"class":1013},[979,1283,1284],{"class":1242}," uuid",[979,1286,1247],{"class":1246},[979,1288,1289],{"class":1041}," crypto",[979,1291,1114],{"class":1009},[979,1293,1294],{"class":1005},"randomBytes",[979,1296,1010],{"class":1009},[979,1298,1300],{"class":1299},"spgvN","32",[979,1302,1303],{"class":1009},").",[979,1305,1306],{"class":1005},"toString",[979,1308,1010],{"class":1009},[979,1310,1274],{"class":1192},[979,1312,1313],{"class":1196},"hex",[979,1315,1274],{"class":1192},[979,1317,1044],{"class":1009},[979,1319,1320,1322,1325,1327,1330,1332,1335,1337,1340,1343,1346,1348,1350,1352,1355,1357,1359,1362,1364],{"class":981,"line":1062},[979,1321,1239],{"class":1013},[979,1323,1324],{"class":1242}," cookieValue",[979,1326,1247],{"class":1246},[979,1328,1329],{"class":1005}," createSignedValue",[979,1331,1010],{"class":1009},[979,1333,1334],{"class":1041},"uuid",[979,1336,870],{"class":1009},[979,1338,1339],{"class":1299},"1000",[979,1341,1342],{"class":1246}," *",[979,1344,1345],{"class":1299}," 60",[979,1347,1342],{"class":1246},[979,1349,1345],{"class":1299},[979,1351,1342],{"class":1246},[979,1353,1354],{"class":1299}," 2",[979,1356,870],{"class":1009},[979,1358,1274],{"class":1192},[979,1360,1361],{"class":1196},"normal",[979,1363,1274],{"class":1192},[979,1365,1044],{"class":1009},[979,1367,1368],{"class":981,"line":1068},[979,1369,1234],{"emptyLinePlaceholder":8},[979,1371,1373,1376,1379],{"class":981,"line":1372},8,[979,1374,1375],{"class":998},"await",[979,1377,1378],{"class":1005}," checkForBots",[979,1380,1381],{"class":1009},"(\n",[979,1383,1385,1388,1391,1393,1395,1397,1399,1401,1404,1406,1408],{"class":981,"line":1384},9,[979,1386,1387],{"class":1009},"  { ",[979,1389,1390],{"class":1041},"name",[979,1392,1266],{"class":1265},[979,1394,1193],{"class":1192},[979,1396,1080],{"class":1196},[979,1398,1274],{"class":1192},[979,1400,870],{"class":1009},[979,1402,1403],{"class":1041},"value",[979,1405,1266],{"class":1265},[979,1407,1324],{"class":1041},[979,1409,1410],{"class":1009}," },\n",[979,1412,1414,1417],{"class":981,"line":1413},10,[979,1415,1416],{"class":1041},"  event",[979,1418,1419],{"class":1009},",\n",[979,1421,1423,1425,1427,1430,1432,1435],{"class":981,"line":1422},11,[979,1424,1416],{"class":1041},[979,1426,1114],{"class":1009},[979,1428,1429],{"class":1041},"req",[979,1431,1114],{"class":1009},[979,1433,1434],{"class":1041},"method",[979,1436,1419],{"class":1009},[979,1438,1440,1443],{"class":981,"line":1439},12,[979,1441,1442],{"class":1041},"  log",[979,1444,1419],{"class":1009},[979,1446,1448,1451,1453,1455],{"class":981,"line":1447},13,[979,1449,1450],{"class":1041},"  config",[979,1452,1114],{"class":1009},[979,1454,1123],{"class":1041},[979,1456,1419],{"class":1009},[979,1458,1460,1463,1465,1467,1469,1471,1473,1475],{"class":981,"line":1459},14,[979,1461,1462],{"class":1005},"  getCookie",[979,1464,1010],{"class":1009},[979,1466,1021],{"class":1041},[979,1468,870],{"class":1009},[979,1470,1274],{"class":1192},[979,1472,1087],{"class":1196},[979,1474,1274],{"class":1192},[979,1476,1044],{"class":1009},[979,1478,1480],{"class":981,"line":1479},15,[979,1481,1044],{"class":1009},[848,1483,1484,1485,1487,1488,1114],{},"The function throws HTTP 403 when the IAM service flags the visitor, and HTTP 502 when the IAM service is unreachable. On success it sets the ",[867,1486,1080],{}," cookie on the response and stores the tracking result in ",[867,1489,1490],{},"event.context.trackingResult",[848,1492,1493,1494,1496],{},"For most cases, use ",[867,1495,873],{}," directly rather than calling this function: it handles cookie generation, deduplication, and the skip logic automatically.",[856,1498],{},[859,1500,1502],{"id":1501},"banip",[867,1503,1131],{},[848,1505,1506,1509,1510,1513,1514,1516,1517,1124,1519,1521],{},[867,1507,1508],{},"banIp(ip)"," executes a ",[867,1511,1512],{},"sudo ufw insert 1 deny from \u003Cip> to any"," command to block the IP at the firewall level. It is called automatically by ",[867,1515,873],{}," when ",[867,1518,1123],{},[867,1520,1127],{}," and the visitor score exceeds the threshold.",[848,1523,1524],{},"Call it directly when implementing custom ban logic:",[970,1526,1528],{"className":972,"code":1527,"language":974,"meta":975,"style":975},"await banIp(clientIp)\n",[867,1529,1530],{"__ignoreMap":975},[979,1531,1532,1534,1537,1539,1542],{"class":981,"line":982},[979,1533,1375],{"class":998},[979,1535,1536],{"class":1005}," banIp",[979,1538,1010],{"class":1009},[979,1540,1541],{"class":1041},"clientIp",[979,1543,1044],{"class":1009},[848,1545,1546,1547,1550,1551,1114],{},"The firewall rule persists across application restarts. Managing and reviewing the rules is outside the scope of this module. UFW rules can be listed with ",[867,1548,1549],{},"sudo ufw status numbered"," and removed with ",[867,1552,1553],{},"sudo ufw delete \u003Crule_number>",[856,1555],{},[859,1557,1559],{"id":1558},"bot-detection-in-the-iam-service","Bot detection in the IAM service",[848,1561,1562,1563,1565],{},"The full detection pipeline with 17 configurable checkers, scoring logic, canary cookie fingerprinting, and good-bot exemptions runs inside the IAM service via the Bot Detector integration. See ",[852,1564,33],{"href":35}," for complete coverage of the pipeline and how to configure individual checkers.",[1567,1568,1569],"style",{},"html pre.shiki code .sghk6, html code.shiki .sghk6{--shiki-light:#008000;--shiki-default:#008000;--shiki-dark:#6272A4}html pre.shiki code .sZ328, html code.shiki .sZ328{--shiki-light:#AF00DB;--shiki-default:#AF00DB;--shiki-dark:#FF79C6}html pre.shiki code .sHOzp, html code.shiki .sHOzp{--shiki-light:#795E26;--shiki-default:#795E26;--shiki-dark:#50FA7B}html pre.shiki code .sDd4n, html code.shiki .sDd4n{--shiki-light:#000000;--shiki-default:#000000;--shiki-dark:#F8F8F2}html pre.shiki code .sl46w, html code.shiki .sl46w{--shiki-light:#0000FF;--shiki-default:#0000FF;--shiki-dark:#FF79C6}html pre.shiki code .sygFZ, html code.shiki .sygFZ{--shiki-light:#001080;--shiki-light-font-style:inherit;--shiki-default:#001080;--shiki-default-font-style:inherit;--shiki-dark:#FFB86C;--shiki-dark-font-style:italic}html pre.shiki code .sjsA6, html code.shiki .sjsA6{--shiki-light:#001080;--shiki-default:#001080;--shiki-dark:#F8F8F2}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sFkSl, html code.shiki .sFkSl{--shiki-light:#A31515;--shiki-default:#A31515;--shiki-dark:#E9F284}html pre.shiki code .sFB1V, html code.shiki .sFB1V{--shiki-light:#A31515;--shiki-default:#A31515;--shiki-dark:#F1FA8C}html pre.shiki code .s3JHE, html code.shiki .s3JHE{--shiki-light:#0070C1;--shiki-default:#0070C1;--shiki-dark:#F8F8F2}html pre.shiki code .saOXh, html code.shiki .saOXh{--shiki-light:#000000;--shiki-default:#000000;--shiki-dark:#FF79C6}html pre.shiki code .s34zl, html code.shiki .s34zl{--shiki-light:#001080;--shiki-default:#001080;--shiki-dark:#FF79C6}html pre.shiki code .spgvN, html code.shiki .spgvN{--shiki-light:#098658;--shiki-default:#098658;--shiki-dark:#BD93F9}",{"title":975,"searchDepth":989,"depth":989,"links":1571},[1572,1573,1574,1575,1576,1577],{"id":861,"depth":989,"text":862},{"id":938,"depth":989,"text":869},{"id":957,"depth":989,"text":873},{"id":1153,"depth":989,"text":1156},{"id":1501,"depth":989,"text":1131},{"id":1558,"depth":989,"text":1559},"IP validation, the bot detection middleware, how fingerprints are forwarded to the IAM service check endpoint, and firewall-level banning with UFW.","md","i-lucide-scan-eye",{},null,"---\ntitle: Bot Detection\ndescription: IP validation, the bot detection middleware, how fingerprints are forwarded to the IAM service check endpoint, and firewall-level banning with UFW.\nicon: i-lucide-scan-eye\n---\n\nThe module integrates with the [Bot Detector](\u002Fdocs\u002Fbot-detection) pipeline running inside the IAM service. The gateway extracts the visitor fingerprint from each request and forwards it to the IAM service, which runs it through the full detection pipeline. Flagged visitors receive a 403 response at the gateway level. On Linux servers with UFW installed, banned IPs can be blocked at the firewall.\n\n---\n\n## Global middleware\n\nThe bot detection chain is wired as three separate global middlewares that run in order: `isIPValid`, `botDetectorMiddleware`, and `generateCsrfCookie`. Register them on your H3 app or Nitro instance as shown in the [H3 or Nitro setup](\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fh3-nitro). When using the Nuxt module with `enableMiddleware: true`, the chain is registered automatically. The bot detection call happens before the CSRF cookie is issued, so flagged visitors never receive a valid session token.\n\n::warning\nThe bot detector in this module should be enabled by default, disabling it while using the IAM service will fail session rotation and verification.\n::\n\nThe middleware skips processing for:\n\n- `HEAD` requests\n- The `\u002Fapi\u002Fhealth` path\n- Framework internal paths starting with `\u002F_nuxt` or `\u002Fapi\u002F_mdc` (only relevant under Nuxt)\n- Requests with `X-Forwarded-For: 127.0.0.1` or `::1` (loopback, trusted internal traffic)\n\n---\n\n## `isIPValid`\n\n`isIPValid` extracts the client IP address from the request headers and validates it with `net.isIP()`. This function does not make a network call. It runs as the first step of the middleware chain so that any request with an invalid or missing IP is rejected immediately with HTTP 403, before `botDetectorMiddleware` runs.\n\n---\n\n## `botDetectorMiddleware`\n\n`botDetectorMiddleware` forwards the visitor fingerprint to the IAM service `\u002Fcheck` endpoint. The IAM service runs the full Bot Detector pipeline and returns a bot score. When the score exceeds the ban threshold, the middleware throws HTTP 403.\n\n```ts\n\u002F\u002F The middleware is called automatically in the global middleware chain.\n\u002F\u002F To run it manually on a specific route:\nexport default defineEventHandler(async (event) => {\n  isIPValid(event)\n  await botDetectorMiddleware(event)\n  \u002F\u002F Proceed only if the visitor is not flagged\n})\n```\n\nOn the first request from a visitor, the middleware calls `\u002Fcheck` and sets `__Host-dr_i_n`, a signed host-only cookie that tracks the result. On subsequent requests where both `__Host-dr_i_n` and the `canary_id` cookie (issued by the IAM service) are present and the `__Host-dr_i_n` signature is valid, the middleware skips the IAM call and returns immediately. This avoids calling the full bot detection pipeline on every page view.\n\nThe `__Host-dr_i_n` cookie is HMAC-signed using `cryptoCookiesSecret` and set with `HttpOnly: true`, `SameSite: Strict`, `Secure: true`, and a 2-hour TTL. If the signature verification fails for any reason, the middleware returns HTTP 403 with code `CANARY_TEMPERING`.\n\nBot detection is also skipped for static assets such as CSS, images, and font files, and for OAuth redirect routes.\n\nWhen `enableFireWallBans` is `true` in the configuration and the visitor is flagged, `banIp` is called to add a UFW rule blocking the IP at the OS level.\n\n::caution\n`enableFireWallBans` requires a Linux environment with `ufw` installed and passwordless `sudo` configured for the Node.js process. Do not enable this on serverless or edge environments such as Vercel, Netlify, or Cloudflare Workers.\n::\n\n---\n\n## `checkForBots`\n\n`checkForBots` is a low-level helper that calls the IAM `\u002Fcheck` endpoint with a prepared signed cookie and visitor context. It is used internally by `botDetectorMiddleware` and is exported for cases where you need to run the check with explicit control over the cookie and method, for example when building a custom middleware chain.\n\n```ts\nimport { crypto } from 'node:crypto'\nimport { checkForBots, getLogger, createSignedValue } from 'auth-h3client\u002Fv2'\n\nconst log = getLogger().child({ service: 'api' })\nconst uuid = crypto.randomBytes(32).toString('hex')\nconst cookieValue = createSignedValue(uuid, 1000 * 60 * 60 * 2, 'normal')\n\nawait checkForBots(\n  { name: '__Host-dr_i_n', value: cookieValue },\n  event,\n  event.req.method,\n  log,\n  config.enableFireWallBans,\n  getCookie(event, 'canary_id')\n)\n```\n\nThe function throws HTTP 403 when the IAM service flags the visitor, and HTTP 502 when the IAM service is unreachable. On success it sets the `__Host-dr_i_n` cookie on the response and stores the tracking result in `event.context.trackingResult`.\n\nFor most cases, use `botDetectorMiddleware` directly rather than calling this function: it handles cookie generation, deduplication, and the skip logic automatically.\n\n---\n\n## `banIp`\n\n`banIp(ip)` executes a `sudo ufw insert 1 deny from \u003Cip> to any` command to block the IP at the firewall level. It is called automatically by `botDetectorMiddleware` when `enableFireWallBans` is `true` and the visitor score exceeds the threshold.\n\nCall it directly when implementing custom ban logic:\n\n```ts\nawait banIp(clientIp)\n```\n\nThe firewall rule persists across application restarts. Managing and reviewing the rules is outside the scope of this module. UFW rules can be listed with `sudo ufw status numbered` and removed with `sudo ufw delete \u003Crule_number>`.\n\n---\n\n## Bot detection in the IAM service\n\nThe full detection pipeline with 17 configurable checkers, scoring logic, canary cookie fingerprinting, and good-bot exemptions runs inside the IAM service via the Bot Detector integration. See [Bot Detection](\u002Fdocs\u002Fbot-detection) for complete coverage of the pipeline and how to configure individual checkers.\n",{"title":33,"description":1578},"--IWgyTrUd_iiYHCZf7NjGYJEuht1Kc6ezp8OlyAjDU",[1587,1588],{"title":105,"path":106,"stem":107,"children":-1},{"title":112,"path":113,"stem":114,"children":-1},{"id":843,"title":33,"body":1590,"description":1578,"extension":1579,"icon":1580,"meta":2106,"module":1582,"navigation":8,"path":109,"rawbody":1583,"seo":2107,"stem":110,"__hash__":1585},{"type":845,"value":1591,"toc":2098},[1592,1596,1598,1600,1612,1616,1618,1640,1642,1646,1654,1656,1660,1666,1730,1742,1756,1758,1766,1776,1778,1782,1790,2036,2042,2046,2048,2052,2064,2066,2082,2088,2090,2092,2096],[848,1593,850,1594,854],{},[852,1595,269],{"href":35},[856,1597],{},[859,1599,862],{"id":861},[848,1601,865,1602,870,1604,874,1606,878,1608,882,1610,886],{},[867,1603,869],{},[867,1605,873],{},[867,1607,877],{},[852,1609,881],{"href":177},[867,1611,885],{},[888,1613,1614],{},[848,1615,892],{},[848,1617,895],{},[897,1619,1620,1624,1628,1634],{},[900,1621,1622,905],{},[867,1623,904],{},[900,1625,908,1626,912],{},[867,1627,911],{},[900,1629,915,1630,919,1632,923],{},[867,1631,918],{},[867,1633,922],{},[900,1635,926,1636,919,1638,933],{},[867,1637,929],{},[867,1639,932],{},[856,1641],{},[859,1643,1644],{"id":938},[867,1645,869],{},[848,1647,1648,945,1650,949,1652,952],{},[867,1649,869],{},[867,1651,948],{},[867,1653,873],{},[856,1655],{},[859,1657,1658],{"id":957},[867,1659,873],{},[848,1661,1662,964,1664,968],{},[867,1663,873],{},[867,1665,967],{},[970,1667,1668],{"className":972,"code":973,"language":974,"meta":975,"style":975},[867,1669,1670,1674,1678,1700,1710,1722,1726],{"__ignoreMap":975},[979,1671,1672],{"class":981,"line":982},[979,1673,986],{"class":985},[979,1675,1676],{"class":981,"line":989},[979,1677,992],{"class":985},[979,1679,1680,1682,1684,1686,1688,1690,1692,1694,1696,1698],{"class":981,"line":995},[979,1681,999],{"class":998},[979,1683,1002],{"class":998},[979,1685,1006],{"class":1005},[979,1687,1010],{"class":1009},[979,1689,1014],{"class":1013},[979,1691,1017],{"class":1009},[979,1693,1021],{"class":1020},[979,1695,1024],{"class":1009},[979,1697,1027],{"class":1013},[979,1699,1030],{"class":1009},[979,1701,1702,1704,1706,1708],{"class":981,"line":1033},[979,1703,1036],{"class":1005},[979,1705,1010],{"class":1009},[979,1707,1021],{"class":1041},[979,1709,1044],{"class":1009},[979,1711,1712,1714,1716,1718,1720],{"class":981,"line":1047},[979,1713,1050],{"class":998},[979,1715,1053],{"class":1005},[979,1717,1010],{"class":1009},[979,1719,1021],{"class":1041},[979,1721,1044],{"class":1009},[979,1723,1724],{"class":981,"line":1062},[979,1725,1065],{"class":985},[979,1727,1728],{"class":981,"line":1068},[979,1729,1071],{"class":1009},[848,1731,1074,1732,1077,1734,1081,1736,1084,1738,1088,1740,1091],{},[867,1733,967],{},[867,1735,1080],{},[867,1737,1080],{},[867,1739,1087],{},[867,1741,1080],{},[848,1743,908,1744,1096,1746,1100,1748,870,1750,870,1752,1110,1754,1114],{},[867,1745,1080],{},[867,1747,1099],{},[867,1749,1103],{},[867,1751,1106],{},[867,1753,1109],{},[867,1755,1113],{},[848,1757,1117],{},[848,1759,1120,1760,1124,1762,1128,1764,1132],{},[867,1761,1123],{},[867,1763,1127],{},[867,1765,1131],{},[1134,1767,1768],{},[848,1769,1770,1140,1772,1144,1774,1148],{},[867,1771,1123],{},[867,1773,1143],{},[867,1775,1147],{},[856,1777],{},[859,1779,1780],{"id":1153},[867,1781,1156],{},[848,1783,1784,1161,1786,1164,1788,1167],{},[867,1785,1156],{},[867,1787,967],{},[867,1789,873],{},[970,1791,1792],{"className":972,"code":1170,"language":974,"meta":975,"style":975},[867,1793,1794,1812,1838,1842,1870,1902,1942,1946,1954,1978,1984,1998,2004,2014,2032],{"__ignoreMap":975},[979,1795,1796,1798,1800,1802,1804,1806,1808,1810],{"class":981,"line":982},[979,1797,1177],{"class":998},[979,1799,1180],{"class":1009},[979,1801,1183],{"class":1041},[979,1803,1186],{"class":1009},[979,1805,1189],{"class":998},[979,1807,1193],{"class":1192},[979,1809,1197],{"class":1196},[979,1811,1200],{"class":1192},[979,1813,1814,1816,1818,1820,1822,1824,1826,1828,1830,1832,1834,1836],{"class":981,"line":989},[979,1815,1177],{"class":998},[979,1817,1180],{"class":1009},[979,1819,1156],{"class":1041},[979,1821,870],{"class":1009},[979,1823,1213],{"class":1041},[979,1825,870],{"class":1009},[979,1827,1218],{"class":1041},[979,1829,1186],{"class":1009},[979,1831,1189],{"class":998},[979,1833,1193],{"class":1192},[979,1835,1227],{"class":1196},[979,1837,1200],{"class":1192},[979,1839,1840],{"class":981,"line":995},[979,1841,1234],{"emptyLinePlaceholder":8},[979,1843,1844,1846,1848,1850,1852,1854,1856,1858,1860,1862,1864,1866,1868],{"class":981,"line":1033},[979,1845,1239],{"class":1013},[979,1847,1243],{"class":1242},[979,1849,1247],{"class":1246},[979,1851,1250],{"class":1005},[979,1853,1253],{"class":1009},[979,1855,1256],{"class":1005},[979,1857,1259],{"class":1009},[979,1859,1262],{"class":1041},[979,1861,1266],{"class":1265},[979,1863,1193],{"class":1192},[979,1865,1271],{"class":1196},[979,1867,1274],{"class":1192},[979,1869,1277],{"class":1009},[979,1871,1872,1874,1876,1878,1880,1882,1884,1886,1888,1890,1892,1894,1896,1898,1900],{"class":981,"line":1047},[979,1873,1239],{"class":1013},[979,1875,1284],{"class":1242},[979,1877,1247],{"class":1246},[979,1879,1289],{"class":1041},[979,1881,1114],{"class":1009},[979,1883,1294],{"class":1005},[979,1885,1010],{"class":1009},[979,1887,1300],{"class":1299},[979,1889,1303],{"class":1009},[979,1891,1306],{"class":1005},[979,1893,1010],{"class":1009},[979,1895,1274],{"class":1192},[979,1897,1313],{"class":1196},[979,1899,1274],{"class":1192},[979,1901,1044],{"class":1009},[979,1903,1904,1906,1908,1910,1912,1914,1916,1918,1920,1922,1924,1926,1928,1930,1932,1934,1936,1938,1940],{"class":981,"line":1062},[979,1905,1239],{"class":1013},[979,1907,1324],{"class":1242},[979,1909,1247],{"class":1246},[979,1911,1329],{"class":1005},[979,1913,1010],{"class":1009},[979,1915,1334],{"class":1041},[979,1917,870],{"class":1009},[979,1919,1339],{"class":1299},[979,1921,1342],{"class":1246},[979,1923,1345],{"class":1299},[979,1925,1342],{"class":1246},[979,1927,1345],{"class":1299},[979,1929,1342],{"class":1246},[979,1931,1354],{"class":1299},[979,1933,870],{"class":1009},[979,1935,1274],{"class":1192},[979,1937,1361],{"class":1196},[979,1939,1274],{"class":1192},[979,1941,1044],{"class":1009},[979,1943,1944],{"class":981,"line":1068},[979,1945,1234],{"emptyLinePlaceholder":8},[979,1947,1948,1950,1952],{"class":981,"line":1372},[979,1949,1375],{"class":998},[979,1951,1378],{"class":1005},[979,1953,1381],{"class":1009},[979,1955,1956,1958,1960,1962,1964,1966,1968,1970,1972,1974,1976],{"class":981,"line":1384},[979,1957,1387],{"class":1009},[979,1959,1390],{"class":1041},[979,1961,1266],{"class":1265},[979,1963,1193],{"class":1192},[979,1965,1080],{"class":1196},[979,1967,1274],{"class":1192},[979,1969,870],{"class":1009},[979,1971,1403],{"class":1041},[979,1973,1266],{"class":1265},[979,1975,1324],{"class":1041},[979,1977,1410],{"class":1009},[979,1979,1980,1982],{"class":981,"line":1413},[979,1981,1416],{"class":1041},[979,1983,1419],{"class":1009},[979,1985,1986,1988,1990,1992,1994,1996],{"class":981,"line":1422},[979,1987,1416],{"class":1041},[979,1989,1114],{"class":1009},[979,1991,1429],{"class":1041},[979,1993,1114],{"class":1009},[979,1995,1434],{"class":1041},[979,1997,1419],{"class":1009},[979,1999,2000,2002],{"class":981,"line":1439},[979,2001,1442],{"class":1041},[979,2003,1419],{"class":1009},[979,2005,2006,2008,2010,2012],{"class":981,"line":1447},[979,2007,1450],{"class":1041},[979,2009,1114],{"class":1009},[979,2011,1123],{"class":1041},[979,2013,1419],{"class":1009},[979,2015,2016,2018,2020,2022,2024,2026,2028,2030],{"class":981,"line":1459},[979,2017,1462],{"class":1005},[979,2019,1010],{"class":1009},[979,2021,1021],{"class":1041},[979,2023,870],{"class":1009},[979,2025,1274],{"class":1192},[979,2027,1087],{"class":1196},[979,2029,1274],{"class":1192},[979,2031,1044],{"class":1009},[979,2033,2034],{"class":981,"line":1479},[979,2035,1044],{"class":1009},[848,2037,1484,2038,1487,2040,1114],{},[867,2039,1080],{},[867,2041,1490],{},[848,2043,1493,2044,1496],{},[867,2045,873],{},[856,2047],{},[859,2049,2050],{"id":1501},[867,2051,1131],{},[848,2053,2054,1509,2056,1513,2058,1516,2060,1124,2062,1521],{},[867,2055,1508],{},[867,2057,1512],{},[867,2059,873],{},[867,2061,1123],{},[867,2063,1127],{},[848,2065,1524],{},[970,2067,2068],{"className":972,"code":1527,"language":974,"meta":975,"style":975},[867,2069,2070],{"__ignoreMap":975},[979,2071,2072,2074,2076,2078,2080],{"class":981,"line":982},[979,2073,1375],{"class":998},[979,2075,1536],{"class":1005},[979,2077,1010],{"class":1009},[979,2079,1541],{"class":1041},[979,2081,1044],{"class":1009},[848,2083,1546,2084,1550,2086,1114],{},[867,2085,1549],{},[867,2087,1553],{},[856,2089],{},[859,2091,1559],{"id":1558},[848,2093,1562,2094,1565],{},[852,2095,33],{"href":35},[1567,2097,1569],{},{"title":975,"searchDepth":989,"depth":989,"links":2099},[2100,2101,2102,2103,2104,2105],{"id":861,"depth":989,"text":862},{"id":938,"depth":989,"text":869},{"id":957,"depth":989,"text":873},{"id":1153,"depth":989,"text":1156},{"id":1501,"depth":989,"text":1131},{"id":1558,"depth":989,"text":1559},{},{"title":33,"description":1578},1780436291261]