{"id":353496,"date":"2026-08-26T20:11:43","date_gmt":"2026-08-26T20:11:43","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/nv-oos-graphify\/"},"modified":"2026-09-13T10:40:29","modified_gmt":"2026-09-13T10:40:29","slug":"nvoos-content-graph","status":"publish","type":"plugin","link":"https:\/\/ary.wordpress.org\/plugins\/nvoos-content-graph\/","author":17440330,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.8","stable_tag":"1.0.8","tested":"7.1.1","requires":"6.5","requires_php":"8.1","requires_plugins":null,"header_name":"NV oOS Content Graph","header_author":"NV Digital Solutions","header_description":"Visual knowledge graph for WordPress. Maps your content into an interactive, navigable graph. Zero API keys required.","assets_banners_color":"06102b","last_updated":"2026-09-13 10:40:29","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/github.com\/nvdigitalsolutions\/nvoos-content-graph","header_author_uri":"https:\/\/nvdigitalsolutions.com","rating":0,"author_block_rating":0,"active_installs":0,"downloads":382,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.3":{"tag":"1.0.3","author":"vsamtani","date":"2026-08-26 20:22:10","revision":3667765},"1.0.7":{"tag":"1.0.7","author":"vsamtani","date":"2026-09-13 07:58:34","revision":3693447},"1.0.8":{"tag":"1.0.8","author":"vsamtani","date":"2026-09-13 10:40:29","revision":3693559}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3667805,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3667805,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3667764,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3667764,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{"blueprint.json":{"filename":"blueprint.json","revision":3701758,"resolution":false,"location":"assets","locale":"","contents":"{\"$schema\":\"https:\\\/\\\/playground.wordpress.net\\\/blueprint-schema.json\",\"landingPage\":\"\\\/wp-admin\\\/admin.php?page=nvoos-content-graph\",\"preferredVersions\":{\"php\":\"8.3\",\"wp\":\"latest\"},\"phpExtensionBundles\":[\"kitchen-sink\"],\"features\":{\"networking\":true},\"steps\":[{\"step\":\"login\",\"username\":\"admin\",\"password\":\"password\"},{\"step\":\"setSiteOptions\",\"options\":{\"blogname\":\"Project Asteria \\u2014 Content Graph Demo\",\"blogdescription\":\"A fictional sci-fi universe mapped into a knowledge graph by NV oOS Content Graph.\"}},{\"step\":\"runPHP\",\"code\":\"<?php require_once '\\\/wordpress\\\/wp-load.php';\\n\\\/\\\/ Playground blueprint dev tooling \\u2014 this snippet is embedded into a\\n\\\/\\\/ blueprint's runPHP step by bin\\\/generate-content-graph-blueprint.php\\n\\\/\\\/ (which strips this opening tag). The guard satisfies Plugin Check's\\n\\\/\\\/ direct-access rule when the dev folder is scanned; inside the embedded\\n\\\/\\\/ context ABSPATH is always defined, so the guard passes through.\\nif ( ! defined( 'ABSPATH' ) ) {\\n\\texit;\\n}\\n\\n\\\/**\\n * Project Asteria \\u2014 demo seed content for the NV oOS Content Graph\\n * WordPress Playground blueprint.\\n *\\n * This file is EMBEDDED into the blueprint's runPHP step by\\n * bin\\\/generate-content-graph-blueprint.php, which strips the opening\\n * <?php tag. It must therefore stay a self-contained snippet:\\n *\\n *   - No namespace, no Composer dependencies, no closing ?> tag.\\n *   - WordPress functions only (it runs right after wp-load).\\n *   - Idempotent: guarded by the nvoos_cg_demo_seeded option.\\n *\\n * The universe: 26 posts + 5 pages, 3 authors + The Editor, 5 categories,\\n * 10 tags. Bodies use {{slug}} tokens that are rendered as internal links,\\n * which the plugin's StructuralExtractor turns into LINKS_TO graph edges.\\n * Three posts are true orphans (author 0, no terms, no links) so the\\n * Content Gap Analysis finds degree-0 nodes.\\n *\\n * @package NvoosContentGraph\\n *\\\/\\n\\n\\\/\\\/ \\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\n\\\/\\\/ Rendering helpers\\n\\\/\\\/ \\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\n\\nfunction nvoos_cg_demo_link_map( array $posts, array $pages ): array {\\n\\t$titles = array();\\n\\tforeach ( $posts as $p ) {\\n\\t\\t$titles[ $p['slug'] ] = $p['title'];\\n\\t}\\n\\tforeach ( $pages as $p ) {\\n\\t\\t$titles[ $p['slug'] ] = $p['title'];\\n\\t}\\n\\treturn $titles;\\n}\\n\\nfunction nvoos_cg_demo_render_tokens( string $text, array $titles ): string {\\n\\treturn preg_replace_callback(\\n\\t\\t'\\\/\\\\{\\\\{([a-z0-9-]+)\\\\}\\\\}\\\/',\\n\\t\\tstatic function ( array $m ) use ( $titles ): string {\\n\\t\\t\\tif ( ! isset( $titles[ $m[1] ] ) ) {\\n\\t\\t\\t\\treturn '';\\n\\t\\t\\t}\\n\\t\\t\\treturn '<a href=\\\"\\\/' . $m[1] . '\\\/\\\">' . esc_html( $titles[ $m[1] ] ) . '<\\\/a>';\\n\\t\\t},\\n\\t\\t$text\\n\\t);\\n}\\n\\nfunction nvoos_cg_demo_render_body( array $paragraphs, array $titles ): string {\\n\\t$out = '';\\n\\tforeach ( $paragraphs as $para ) {\\n\\t\\t$out .= '<p>' . nvoos_cg_demo_render_tokens( (string) $para, $titles ) . '<\\\/p>' . \\\"\\\\n\\\";\\n\\t}\\n\\treturn $out;\\n}\\n\\nfunction nvoos_cg_demo_render_list( array $intro, array $slugs, array $titles ): string {\\n\\t$out = nvoos_cg_demo_render_body( $intro, $titles );\\n\\t$out .= '<ul>' . \\\"\\\\n\\\";\\n\\tforeach ( $slugs as $slug ) {\\n\\t\\tif ( ! isset( $titles[ $slug ] ) ) {\\n\\t\\t\\tcontinue;\\n\\t\\t}\\n\\t\\t$out .= '<li><a href=\\\"\\\/' . $slug . '\\\/\\\">' . esc_html( $titles[ $slug ] ) . '<\\\/a><\\\/li>' . \\\"\\\\n\\\";\\n\\t}\\n\\t$out .= '<\\\/ul>' . \\\"\\\\n\\\";\\n\\treturn $out;\\n}\\n\\n\\\/\\\/ \\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\n\\\/\\\/ Seeder\\n\\\/\\\/ \\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\n\\n\\\/**\\n * Seed the Project Asteria demo. Idempotent.\\n *\\n * @return void\\n *\\\/\\nfunction nvoos_cg_demo_seed(): void {\\n\\tif ( get_option( 'nvoos_cg_demo_seeded' ) ) {\\n\\t\\treturn;\\n\\t}\\n\\n\\t\\\/\\\/ 1. Pretty permalinks \\u2014 required for LINKS_TO edge resolution at\\n\\t\\\/\\\/    build time (url_to_postid needs the rewrite rules).\\n\\tglobal $wp_rewrite;\\n\\tif ( '\\\/%postname%\\\/' !== get_option( 'permalink_structure' ) ) {\\n\\t\\tif ( $wp_rewrite instanceof WP_Rewrite ) {\\n\\t\\t\\t$wp_rewrite->set_permalink_structure( '\\\/%postname%\\\/' );\\n\\t\\t} else {\\n\\t\\t\\tupdate_option( 'permalink_structure', '\\\/%postname%\\\/' );\\n\\t\\t}\\n\\t\\tflush_rewrite_rules( false );\\n\\t}\\n\\n\\t\\\/\\\/ 2. Quiet the per-post incremental rebuild while we seed ~30 posts.\\n\\t\\\/\\\/    One full build runs afterwards from the second blueprint step.\\n\\tupdate_option( 'nvoos_content_graph_settings', array( 'auto_rebuild' => 0 ) );\\n\\n\\t\\\/\\\/ 3. Remove starter content so the graph is purely Asteria.\\n\\t$hello = get_page_by_path( 'hello-world', OBJECT, 'post' );\\n\\tif ( $hello instanceof WP_Post ) {\\n\\t\\twp_delete_post( $hello->ID, true );\\n\\t}\\n\\t$sample = get_page_by_path( 'sample-page', OBJECT, 'page' );\\n\\tif ( $sample instanceof WP_Post ) {\\n\\t\\twp_delete_post( $sample->ID, true );\\n\\t}\\n\\n\\t\\\/\\\/ 4. Authors \\u2014 in-universe voices.\\n\\t$authors = array(\\n\\t\\t'ilsa-venn'  => array( 'Ilsa Venn', 'Field reporter and blockade-runner turned captain of the press cutter Byline.', 'ilsa@asteria.example' ),\\n\\t\\t'oma-desh'   => array( 'Oma Desh', 'Sector Archivist of the Deep Archive Collective; forty years at the Mnemo-Core.', 'oma@asteria.example' ),\\n\\t\\t'jax-merrow' => array( 'Jax Merrow', \\\"Rim correspondent, cantina economist, and the sector's most unreliable reliable narrator.\\\", 'jax@asteria.example' ),\\n\\t);\\n\\t$author_ids = array();\\n\\tforeach ( $authors as $slug => $info ) {\\n\\t\\t$existing = get_user_by( 'login', $slug );\\n\\t\\tif ( $existing instanceof WP_User ) {\\n\\t\\t\\t$author_ids[ $slug ] = (int) $existing->ID;\\n\\t\\t\\tcontinue;\\n\\t\\t}\\n\\t\\t$uid = wp_insert_user(\\n\\t\\t\\tarray(\\n\\t\\t\\t\\t'user_login'   => $slug,\\n\\t\\t\\t\\t'user_pass'    => wp_generate_password( 24, true ),\\n\\t\\t\\t\\t'user_email'   => $info[2],\\n\\t\\t\\t\\t'display_name' => $info[0],\\n\\t\\t\\t\\t'nickname'     => $info[0],\\n\\t\\t\\t\\t'description'  => $info[1],\\n\\t\\t\\t\\t'role'         => 'author',\\n\\t\\t\\t)\\n\\t\\t);\\n\\t\\t$author_ids[ $slug ] = is_wp_error( $uid ) ? 1 : (int) $uid;\\n\\t}\\n\\t\\\/\\\/ The site admin becomes The Editor \\u2014 the fourth byline (user node #1).\\n\\twp_update_user( array( 'ID' => 1, 'display_name' => 'The Editor', 'nickname' => 'The Editor' ) );\\n\\t$author_ids['the-editor'] = 1;\\n\\n\\t\\\/\\\/ 5. Categories and tags.\\n\\t$categories = array(\\n\\t\\t'factions'   => array( 'Factions', 'The powers that shape the Asteria Sector.' ),\\n\\t\\t'planets'    => array( 'Planets', 'Worlds, moons, and the stations strung between them.' ),\\n\\t\\t'characters' => array( 'Characters', 'The people who make the news \\u2014 or are it.' ),\\n\\t\\t'technology' => array( 'Technology', 'Machines that bend space, memory, and common sense.' ),\\n\\t\\t'timeline'   => array( 'Timeline', 'Events every archive agrees actually happened.' ),\\n\\t);\\n\\t$cat_ids = array();\\n\\tforeach ( $categories as $slug => $data ) {\\n\\t\\t$found = term_exists( $slug, 'category' );\\n\\t\\tif ( $found ) {\\n\\t\\t\\t$cat_ids[ $slug ] = is_array( $found ) ? (int) $found['term_id'] : (int) $found;\\n\\t\\t\\tcontinue;\\n\\t\\t}\\n\\t\\t$term = wp_insert_term( $data[0], 'category', array( 'slug' => $slug, 'description' => $data[1] ) );\\n\\t\\t$cat_ids[ $slug ] = is_wp_error( $term ) ? 0 : (int) $term['term_id'];\\n\\t}\\n\\n\\t$tags = array(\\n\\t\\t'trade-routes' => 'Trade Routes',\\n\\t\\t'ai'           => 'AI',\\n\\t\\t'politics'     => 'Politics',\\n\\t\\t'salvage'      => 'Salvage',\\n\\t\\t'war'          => 'War',\\n\\t\\t'science'      => 'Science',\\n\\t\\t'culture'      => 'Culture',\\n\\t\\t'crime'        => 'Crime',\\n\\t\\t'exploration'  => 'Exploration',\\n\\t\\t'lore'         => 'Lore',\\n\\t);\\n\\tforeach ( $tags as $slug => $name ) {\\n\\t\\tif ( ! term_exists( $slug, 'post_tag' ) ) {\\n\\t\\t\\twp_insert_term( $name, 'post_tag', array( 'slug' => $slug ) );\\n\\t\\t}\\n\\t}\\n\\n\\t\\\/\\\/ 6. Posts \\u2014 every {{slug}} token becomes an internal link (LINKS_TO edge).\\n\\t\\\/\\\/    The three entries flagged orphan have no author, no terms, and no\\n\\t\\\/\\\/    links: they are degree-0 nodes for the Content Gap Analysis.\\n\\t$posts = array(\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'The Vanguard Concord',\\n\\t\\t\\t'slug'    => 'vanguard-concord',\\n\\t\\t\\t'cat'     => 'factions',\\n\\t\\t\\t'tags'    => array( 'politics', 'war', 'lore' ),\\n\\t\\t\\t'author'  => 'ilsa-venn',\\n\\t\\t\\t'excerpt' => 'The military alliance that governs the core worlds \\u2014 and pretends to govern the rest.',\\n\\t\\t\\t'body'    => array(\\n\\t\\t\\t\\t\\\"The Vanguard Concord is the military alliance that has governed the core worlds since the {{accord-of-glass}}. Its fleets patrol the inner lanes, its courts arbitrate every serious dispute, and its word is law from {{kythera-prime}} to the quarantine line.\\\",\\n\\t\\t\\t\\t\\\"Beyond the core, Concord authority is more claim than fact. The {{blockade-years}} hardened its admirals and drained its treasuries, while the {{meridian-syndicate}} grew rich in the cracks and the {{rust-nebula-outriders}} grew bold in the wrecks.\\\",\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'The Meridian Syndicate',\\n\\t\\t\\t'slug'    => 'meridian-syndicate',\\n\\t\\t\\t'cat'     => 'factions',\\n\\t\\t\\t'tags'    => array( 'trade-routes', 'crime' ),\\n\\t\\t\\t'author'  => 'jax-merrow',\\n\\t\\t\\t'excerpt' => \\\"No cargo moves through the sector without the Syndicate taking a cut.\\\",\\n\\t\\t\\t'body'    => array(\\n\\t\\t\\t\\t\\\"No cargo moves through the Asteria Sector without the Meridian Syndicate taking a cut. Chartered as a neutral shipping guild after the {{accord-of-glass}}, it now owns half the docks on {{station-nine}} and a fleet of bonded couriers that outflies the {{vanguard-concord}}.\\\",\\n\\t\\t\\t\\t\\\"The Syndicate's ledgers are legendarily opaque. {{rook}} has run Syndicate cargo for years and still cannot say who signs his pay orders \\u2014 though he suspects the {{mnemo-core}} keeps better records than any living bookkeeper.\\\",\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'The Deep Archive Collective',\\n\\t\\t\\t'slug'    => 'deep-archive-collective',\\n\\t\\t\\t'cat'     => 'factions',\\n\\t\\t\\t'tags'    => array( 'ai', 'lore', 'science' ),\\n\\t\\t\\t'author'  => 'oma-desh',\\n\\t\\t\\t'excerpt' => \\\"The order that preserves the sector's memory \\u2014 and argues about who may read it.\\\",\\n\\t\\t\\t'body'    => array(\\n\\t\\t\\t\\t\\\"The Deep Archive Collective preserves the sector's memory. Its archivists train from childhood to operate the {{mnemo-core}}, and its seed vaults and survey logs predate the {{first-fold-transit}}.\\\",\\n\\t\\t\\t\\t\\\"The {{archive-schism}} split the order into Quietists and Intercessors, a wound that has not closed in a generation. {{oma-desh}} belongs to neither faction, which is precisely why both trust her.\\\",\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'Rust Nebula Outriders',\\n\\t\\t\\t'slug'    => 'rust-nebula-outriders',\\n\\t\\t\\t'cat'     => 'factions',\\n\\t\\t\\t'tags'    => array( 'salvage', 'crime' ),\\n\\t\\t\\t'author'  => 'jax-merrow',\\n\\t\\t\\t'excerpt' => 'Salvage crews of the wreck fields \\u2014 charters expired, crews conspicuously not.',\\n\\t\\t\\t'body'    => array(\\n\\t\\t\\t\\t\\\"The Outriders salvage the wreckage of the {{sundering-kythera}} \\u2014 and anything else that drifts into the Rust Nebula. Their charters from the {{vanguard-concord}} expired years ago; their crews, conspicuously, did not.\\\",\\n\\t\\t\\t\\t\\\"{{voidglass}} torn from derelict hulls is their chief export, sold through brokers on {{station-nine}}. The {{blockade-years}} made scavengers of half the sector and folk heroes of the other half.\\\",\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'Kythera Prime',\\n\\t\\t\\t'slug'    => 'kythera-prime',\\n\\t\\t\\t'cat'     => 'planets',\\n\\t\\t\\t'tags'    => array( 'politics', 'war' ),\\n\\t\\t\\t'author'  => 'ilsa-venn',\\n\\t\\t\\t'excerpt' => 'The capital world \\u2014 ring scarred, blockade grid humming, courts in session.',\\n\\t\\t\\t'body'    => array(\\n\\t\\t\\t\\t\\\"Kythera Prime is the seat of the {{vanguard-concord}} and the most populous world in the sector. Its orbital ring still bears the scars of the {{sundering-kythera}}, kept unrepaired by decree as a monument and a warning.\\\",\\n\\t\\t\\t\\t\\\"Beneath the blockade grid, the capital hums with {{beacon-network}} relays and court intrigue. {{ilsa-venn}} was born in the lower ring and still files every dispatch from a press office two levels below the Admiralty.\\\",\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'Emberfall',\\n\\t\\t\\t'slug'    => 'emberfall',\\n\\t\\t\\t'cat'     => 'planets',\\n\\t\\t\\t'tags'    => array( 'science', 'salvage' ),\\n\\t\\t\\t'author'  => 'jax-merrow',\\n\\t\\t\\t'excerpt' => 'A tidally locked mining world with seams of voidglass and a polar listening vault.',\\n\\t\\t\\t'body'    => array(\\n\\t\\t\\t\\t\\\"Emberfall is a tidally locked mining world famous for two things: the {{voidglass}} seams beneath its crust and the {{gravity-orchards}} that feed half the sector's luxury tables.\\\",\\n\\t\\t\\t\\t\\\"In the polar shadow, far from the smelter glow, the {{deep-archive-collective}} maintains a listening vault. Prospectors joke that the monks hear everything \\u2014 including ore prices before the {{meridian-syndicate}} does.\\\",\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'Station Nine, the Wreck',\\n\\t\\t\\t'slug'    => 'station-nine',\\n\\t\\t\\t'cat'     => 'planets',\\n\\t\\t\\t'tags'    => array( 'trade-routes', 'crime', 'culture' ),\\n\\t\\t\\t'author'  => 'jax-merrow',\\n\\t\\t\\t'excerpt' => 'A decommissioned Concord carrier welded to an asteroid \\u2014 the busiest neutral port in the sector.',\\n\\t\\t\\t'body'    => array(\\n\\t\\t\\t\\t\\\"Station Nine \\u2014 the Wreck \\u2014 is a decommissioned Concord carrier welded to an asteroid, and the busiest neutral port in the sector. Its {{market-rings}} never close, and neither do most of its arguments.\\\",\\n\\t\\t\\t\\t\\\"Every faction keeps a flag here and none keeps the law. The {{rust-nebula-outriders}} fence salvage in the lower decks, the {{meridian-syndicate}} runs the docks, and {{jax-merrow}} has owed the cantina keepers money since the {{blockade-years}}.\\\",\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'The Gravity Orchards of Emberfall',\\n\\t\\t\\t'slug'    => 'gravity-orchards',\\n\\t\\t\\t'cat'     => 'planets',\\n\\t\\t\\t'tags'    => array( 'culture', 'science' ),\\n\\t\\t\\t'author'  => 'ilsa-venn',\\n\\t\\t\\t'excerpt' => \\\"Variable-gravity fruit trellises: the sector's most taxed luxury crop.\\\",\\n\\t\\t\\t'body'    => array(\\n\\t\\t\\t\\t\\\"In the Emberfall highlands, the gravity orchards grow fruit in variable-gravity trellises \\u2014 a luxury crop that survived the {{sundering-kythera}} when most agriculture did not.\\\",\\n\\t\\t\\t\\t\\\"Growers still trade seedlings with the {{deep-archive-collective}}, whose vaults predate the {{first-fold-transit}}. The Concord taxes every crate twice: once leaving {{emberfall}}, once arriving anywhere else.\\\",\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'The Market Rings of Station Nine',\\n\\t\\t\\t'slug'    => 'market-rings',\\n\\t\\t\\t'cat'     => 'planets',\\n\\t\\t\\t'tags'    => array( 'trade-routes', 'culture' ),\\n\\t\\t\\t'author'  => 'jax-merrow',\\n\\t\\t\\t'excerpt' => 'Twelve levels of stalls, temples, and dubious title deeds.',\\n\\t\\t\\t'body'    => array(\\n\\t\\t\\t\\t\\\"The market rings of {{station-nine}} are twelve levels of stalls, temples, and dubious title deeds. If it has ever been sold in the sector, it has been sold here first.\\\",\\n\\t\\t\\t\\t\\\"The {{meridian-syndicate}} claims the dockside levels, the {{rust-nebula-outriders}} own the salvage pits, and nobody claims the middle rings \\u2014 which is where the interesting trade happens: {{voidglass}} by the gram, secrets by the word.\\\",\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'Captain Ilsa Venn',\\n\\t\\t\\t'slug'    => 'ilsa-venn',\\n\\t\\t\\t'cat'     => 'characters',\\n\\t\\t\\t'tags'    => array( 'war', 'lore' ),\\n\\t\\t\\t'author'  => 'the-editor',\\n\\t\\t\\t'excerpt' => 'The most widely reprinted byline in the sector, quoted in courts and cantinas alike.',\\n\\t\\t\\t'body'    => array(\\n\\t\\t\\t\\t\\\"Ilsa Venn covered the {{sundering-kythera}} as a cadet stringer and never stopped. Her dispatches from {{kythera-prime}} are the most widely reprinted words in the sector, quoted in courts and cantinas alike.\\\",\\n\\t\\t\\t\\t\\\"She captains a press cutter named Byline and holds the rare distinction of having been boarded by the {{rust-nebula-outriders}} \\u2014 and buying them off with an exclusive. Her running feud with {{jax-merrow}} over expense-report ethics is the oldest joke in the {{market-rings}}.\\\",\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'Archivist Oma Desh',\\n\\t\\t\\t'slug'    => 'oma-desh',\\n\\t\\t\\t'cat'     => 'characters',\\n\\t\\t\\t'tags'    => array( 'ai', 'lore' ),\\n\\t\\t\\t'author'  => 'the-editor',\\n\\t\\t\\t'excerpt' => \\\"The order's neutral face \\u2014 her testimony is accepted as archival fact.\\\",\\n\\t\\t\\t'body'    => array(\\n\\t\\t\\t\\t\\\"Archivist Oma Desh has spent forty years tending the {{mnemo-core}} for the {{deep-archive-collective}}. She can recite the {{accord-of-glass}} from memory, including the footnotes nobody ratified.\\\",\\n\\t\\t\\t\\t\\\"Since the {{archive-schism}}, she has served as the order's neutral face on {{kythera-prime}}, and the Concord courts accept her testimony as archival fact \\u2014 a courtesy they extend to no other living witness.\\\",\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'Jax Merrow',\\n\\t\\t\\t'slug'    => 'jax-merrow',\\n\\t\\t\\t'cat'     => 'characters',\\n\\t\\t\\t'tags'    => array( 'crime', 'culture' ),\\n\\t\\t\\t'author'  => 'ilsa-venn',\\n\\t\\t\\t'excerpt' => \\\"The Rim's most unreliable reliable correspondent.\\\",\\n\\t\\t\\t'body'    => array(\\n\\t\\t\\t\\t\\\"Jax Merrow is the Rim's most unreliable reliable correspondent. He files from cantinas, loading bays, and once \\u2014 famously \\u2014 from inside a Syndicate customs locker on {{station-nine}}.\\\",\\n\\t\\t\\t\\t\\\"His guides to the {{market-rings}} are definitive; his expense reports are fiction, and the {{the-codex}} refuses to archive them. {{rook}} claims Jax owes him a ship, which Jax disputes on the grounds that Rook stole it back.\\\",\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'Rook',\\n\\t\\t\\t'slug'    => 'rook',\\n\\t\\t\\t'cat'     => 'characters',\\n\\t\\t\\t'tags'    => array( 'crime', 'trade-routes' ),\\n\\t\\t\\t'author'  => 'jax-merrow',\\n\\t\\t\\t'excerpt' => 'Smuggler, salvage diver, and occasional blockade runner. No flight plans on file.',\\n\\t\\t\\t'body'    => array(\\n\\t\\t\\t\\t\\\"Rook is a smuggler, salvage diver, and occasional blockade runner who works the lanes between {{station-nine}} and the Rust Nebula. He has never once filed a flight plan the {{vanguard-concord}} could read.\\\",\\n\\t\\t\\t\\t\\\"During the {{blockade-years}}, he ran medical freight for the {{meridian-syndicate}} at rates even the Syndicate called indecent. The {{rust-nebula-outriders}} consider him one of their own \\u2014 a claim he denies in writing, annually.\\\",\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'Dr. Sera Fen',\\n\\t\\t\\t'slug'    => 'sera-fen',\\n\\t\\t\\t'cat'     => 'characters',\\n\\t\\t\\t'tags'    => array( 'science', 'lore' ),\\n\\t\\t\\t'author'  => 'oma-desh',\\n\\t\\t\\t'excerpt' => 'Last living student of the fold-drive team; publishes from an abandoned relay.',\\n\\t\\t\\t'body'    => array(\\n\\t\\t\\t\\t\\\"Dr. Sera Fen is the last living student of the team that built the {{fold-drive}}. She now works alone in a converted {{beacon-network}} relay at the edge of the sector, publishing papers that arrive by courier.\\\",\\n\\t\\t\\t\\t\\\"Her analysis of the {{sundering-kythera}} \\u2014 that the blockade was always more politics than physics \\u2014 made her unwelcome on {{kythera-prime}} and famous everywhere else. The {{deep-archive-collective}} prints her work unedited.\\\",\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'The Fold Drive',\\n\\t\\t\\t'slug'    => 'fold-drive',\\n\\t\\t\\t'cat'     => 'technology',\\n\\t\\t\\t'tags'    => array( 'science', 'trade-routes' ),\\n\\t\\t\\t'author'  => 'oma-desh',\\n\\t\\t\\t'excerpt' => 'Distance is a suggestion. The resonance corridors disagree on the details.',\\n\\t\\t\\t'body'    => array(\\n\\t\\t\\t\\t\\\"The fold drive collapses distance by folding local space along resonance corridors first charted during the {{first-fold-transit}}. Every major route in the sector still follows those original corridors.\\\",\\n\\t\\t\\t\\t\\\"After the {{sundering-kythera}}, the {{vanguard-concord}} restricted fold-drive manufacture to approved yards \\u2014 which is why half the {{rust-nebula-outriders}} fleet still flies pre-war drives held together by prayer and {{voidglass}}.\\\",\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'The Mnemo-Core',\\n\\t\\t\\t'slug'    => 'mnemo-core',\\n\\t\\t\\t'cat'     => 'technology',\\n\\t\\t\\t'tags'    => array( 'ai', 'lore' ),\\n\\t\\t\\t'author'  => 'oma-desh',\\n\\t\\t\\t'excerpt' => \\\"The sector's largest memory lattice. It does not think. It remembers.\\\",\\n\\t\\t\\t'body'    => array(\\n\\t\\t\\t\\t\\\"The Mnemo-Core is the sector's largest memory lattice \\u2014 a crystalline storage architecture grown, not built, over three centuries by the {{deep-archive-collective}}.\\\",\\n\\t\\t\\t\\t\\\"It does not think; the Collective is adamant on this point. But it remembers with a fidelity the {{meridian-syndicate}} would pay any price to audit. Access requests from {{kythera-prime}} are answered, when they are answered, in person by {{oma-desh}}.\\\",\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'Voidglass',\\n\\t\\t\\t'slug'    => 'voidglass',\\n\\t\\t\\t'cat'     => 'technology',\\n\\t\\t\\t'tags'    => array( 'science', 'trade-routes', 'salvage' ),\\n\\t\\t\\t'author'  => 'jax-merrow',\\n\\t\\t\\t'excerpt' => 'Where fold-space cools hull metal too quickly. Prices set every tenth-day.',\\n\\t\\t\\t'body'    => array(\\n\\t\\t\\t\\t\\\"Voidglass forms where fold-space cools hull metal too quickly: a brittle, black, faintly humming crystal. It is the only material known to damp a {{fold-drive}}'s resonance wake.\\\",\\n\\t\\t\\t\\t\\\"The {{rust-nebula-outriders}} mine it from the wreck fields of the {{sundering-kythera}}, and the {{market-rings}} of {{station-nine}} set its price every tenth-day.\\\",\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'The Concord Beacon Network',\\n\\t\\t\\t'slug'    => 'beacon-network',\\n\\t\\t\\t'cat'     => 'technology',\\n\\t\\t\\t'tags'    => array( 'politics', 'war' ),\\n\\t\\t\\t'author'  => 'ilsa-venn',\\n\\t\\t\\t'excerpt' => \\\"Navigation buoys, court broadcasts, and \\u2014 allegedly \\u2014 listening posts everywhere.\\\",\\n\\t\\t\\t'body'    => array(\\n\\t\\t\\t\\t\\\"The Beacon Network is the {{vanguard-concord}}'s relay web: navigation buoys, court broadcasts, and \\u2014 allegedly \\u2014 listening posts in every major system, all reporting to {{kythera-prime}}.\\\",\\n\\t\\t\\t\\t\\\"During the {{blockade-years}} the network became the sector's nervous system. {{sera-fen}}'s relay sits on an abandoned branch, which is why her broadcasts still reach the Rim when Concord ones do not.\\\",\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'The Sundering of Kythera Prime',\\n\\t\\t\\t'slug'    => 'sundering-kythera',\\n\\t\\t\\t'cat'     => 'timeline',\\n\\t\\t\\t'tags'    => array( 'war', 'politics' ),\\n\\t\\t\\t'author'  => 'oma-desh',\\n\\t\\t\\t'excerpt' => 'A tariff dispute that ended with the orbital ring in pieces. Histories disagree on every date except the last one.',\\n\\t\\t\\t'body'    => array(\\n\\t\\t\\t\\t\\\"The Sundering of Kythera Prime began with a tariff dispute and ended with the orbital ring of {{kythera-prime}} in pieces. Official histories disagree about every date except the last one.\\\",\\n\\t\\t\\t\\t\\\"The {{vanguard-concord}} calls it a defensive action; the {{rust-nebula-outriders}} call it a career opportunity. Twenty years on, the wreck fields still feed both economies \\u2014 see {{voidglass}}.\\\",\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'The Accord of Glass',\\n\\t\\t\\t'slug'    => 'accord-of-glass',\\n\\t\\t\\t'cat'     => 'timeline',\\n\\t\\t\\t'tags'    => array( 'politics', 'lore' ),\\n\\t\\t\\t'author'  => 'ilsa-venn',\\n\\t\\t\\t'excerpt' => 'The treaty that ended the shooting without ending the argument.',\\n\\t\\t\\t'body'    => array(\\n\\t\\t\\t\\t\\\"The Accord of Glass ended the shooting without ending the argument. Signed in a pressurized dome on {{kythera-prime}}, it recognized the {{meridian-syndicate}}'s neutrality and froze the {{vanguard-concord}}'s borders.\\\",\\n\\t\\t\\t\\t\\\"{{oma-desh}} has catalogued seventeen surviving drafts. The {{blockade-years}} formally began, most historians agree, the moment the last draft's ink dried.\\\",\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'The First Fold Transit',\\n\\t\\t\\t'slug'    => 'first-fold-transit',\\n\\t\\t\\t'cat'     => 'timeline',\\n\\t\\t\\t'tags'    => array( 'science', 'lore', 'exploration' ),\\n\\t\\t\\t'author'  => 'oma-desh',\\n\\t\\t\\t'excerpt' => 'Nine crew, eleven minutes. The prototype survived; three of the crew did not.',\\n\\t\\t\\t'body'    => array(\\n\\t\\t\\t\\t\\\"The First Fold Transit carried a crew of nine from {{kythera-prime}} to the edge of the Rust Nebula in eleven minutes. The {{fold-drive}} prototype survived; three of the crew did not.\\\",\\n\\t\\t\\t\\t\\\"The {{deep-archive-collective}} holds the original flight recorder in the {{mnemo-core}}. Every licensed pilot in the sector has heard its audio \\u2014 or claims to have.\\\",\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'The Deep Archive Schism',\\n\\t\\t\\t'slug'    => 'archive-schism',\\n\\t\\t\\t'cat'     => 'timeline',\\n\\t\\t\\t'tags'    => array( 'ai', 'lore' ),\\n\\t\\t\\t'author'  => 'oma-desh',\\n\\t\\t\\t'excerpt' => 'One question split the order: may the Mnemo-Core answer, or only remember?',\\n\\t\\t\\t'body'    => array(\\n\\t\\t\\t\\t\\\"The Archive Schism split the {{deep-archive-collective}} over a single question: whether the {{mnemo-core}} should ever be allowed to answer questions, rather than merely remember.\\\",\\n\\t\\t\\t\\t\\\"The Quietists won the vote and the Intercessors won the argument, and {{oma-desh}} has been translating between them ever since. Both sides cite the {{first-fold-transit}} recordings in support.\\\",\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'The Blockade Years',\\n\\t\\t\\t'slug'    => 'blockade-years',\\n\\t\\t\\t'cat'     => 'timeline',\\n\\t\\t\\t'tags'    => array( 'war', 'trade-routes' ),\\n\\t\\t\\t'author'  => 'ilsa-venn',\\n\\t\\t\\t'excerpt' => \\\"Two decades of tariff war that reshaped the sector's trade lanes \\u2014 and its morality.\\\",\\n\\t\\t\\t'body'    => array(\\n\\t\\t\\t\\t\\\"The Blockade Years \\u2014 two decades of tariff war that followed the {{accord-of-glass}} \\u2014 reshaped the sector's trade lanes and, less visibly, its morality.\\\",\\n\\t\\t\\t\\t\\\"{{station-nine}} prospered as a neutral port, the {{meridian-syndicate}} prospered as a neutral carrier, and the {{vanguard-concord}} learned the hard way that blockades are easier to declare than to end.\\\",\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\t\\\/\\\/ \\u2500\\u2500 Orphans: degree-0 nodes for the Content Gap Analysis \\u2500\\u2500\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'Dossier: The Silent Moon',\\n\\t\\t\\t'slug'    => 'silent-moon',\\n\\t\\t\\t'cat'     => 'planets',\\n\\t\\t\\t'tags'    => array( 'lore', 'exploration' ),\\n\\t\\t\\t'author'  => 0,\\n\\t\\t\\t'orphan'  => true,\\n\\t\\t\\t'excerpt' => 'It orbits nothing. It reflects no light. The dossier remains open.',\\n\\t\\t\\t'body'    => array(\\n\\t\\t\\t\\t\\\"The Silent Moon orbits nothing, which is the first thing every surveyor notices and the last thing any of them can explain. It holds a stable position at the sector's barycenter and reflects no light at all.\\\",\\n\\t\\t\\t\\t'Six expeditions have landed. Six have returned with identical, uninformative logs. The dossier remains open, and the filing fee for new survey permits keeps rising.',\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'Field Notes: Rim-Side Cantinas',\\n\\t\\t\\t'slug'    => 'rim-cantinas',\\n\\t\\t\\t'cat'     => 'planets',\\n\\t\\t\\t'tags'    => array( 'culture' ),\\n\\t\\t\\t'author'  => 0,\\n\\t\\t\\t'orphan'  => true,\\n\\t\\t\\t'excerpt' => 'Scrip and stories. A good story drinks free.',\\n\\t\\t\\t'body'    => array(\\n\\t\\t\\t\\t'The cantinas of the Rim run on two currencies: scrip and stories. A pilot who tells a good one drinks free; a pilot who tells a Concord one drinks alone.',\\n\\t\\t\\t\\t'Every cantina has a house rule named after a regular. The rule named after this correspondent is unprintable, which is why it is also the most popular.',\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'Signal Intercept 77-B',\\n\\t\\t\\t'slug'    => 'signal-intercept-77b',\\n\\t\\t\\t'cat'     => 'timeline',\\n\\t\\t\\t'tags'    => array( 'lore', 'ai' ),\\n\\t\\t\\t'author'  => 0,\\n\\t\\t\\t'orphan'  => true,\\n\\t\\t\\t'excerpt' => 'A phrase in a dialect that does not exist, at intervals that never quite match.',\\n\\t\\t\\t'body'    => array(\\n\\t\\t\\t\\t'Signal Intercept 77-B was captured twelve years ago on a frequency reserved for funeral rites. It repeats a single phrase in a dialect that does not exist, at intervals that never quite match.',\\n\\t\\t\\t\\t'The original recording is stored in a sealed archive vault. The seal has been replaced four times. No one at the monitoring station will discuss why.',\\n\\t\\t\\t),\\n\\t\\t),\\n\\t);\\n\\n\\t\\\/\\\/ 7. Pages.\\n\\t$pages = array(\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'Project Asteria',\\n\\t\\t\\t'slug'    => 'asteria',\\n\\t\\t\\t'author'  => 'the-editor',\\n\\t\\t\\t'excerpt' => 'A fictional universe, mapped as a knowledge graph.',\\n\\t\\t\\t'raw'     => '<p>Project Asteria is a fictional universe mapped into a living knowledge graph by <strong>NV oOS Content Graph<\\\/strong>. Every planet, faction, character, technology, and timeline entry is a node; every link, category, tag, and byline is an edge.<\\\/p>' . \\\"\\\\n\\\"\\n\\t\\t\\t\\t. '<p>Drag the graph below. Zoom. Search. Click a node for details. Then open the admin <a href=\\\"\\\/wp-admin\\\/admin.php?page=nvoos-content-graph\\\">Graph Explorer<\\\/a> for the full toolkit: theming, community colors, gap analysis, and six export formats.<\\\/p>' . \\\"\\\\n\\\"\\n\\t\\t\\t\\t. '<p>[nvoos_graph]<\\\/p>' . \\\"\\\\n\\\"\\n\\t\\t\\t\\t. '<p>New here? Start with the {{field-manual}} or browse the {{the-codex}}.<\\\/p>',\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'The Asteria Codex',\\n\\t\\t\\t'slug'    => 'the-codex',\\n\\t\\t\\t'author'  => 'oma-desh',\\n\\t\\t\\t'excerpt' => \\\"The sector's definitive index \\u2014 every entry below is a node in the knowledge graph.\\\",\\n\\t\\t\\t'intro'   => array(\\n\\t\\t\\t\\t\\\"The Asteria Codex is the sector's definitive index, maintained by the {{deep-archive-collective}} and cross-checked against the {{mnemo-core}}. Three files remain unindexed. The archivists are aware. The archivists do not discuss it.\\\",\\n\\t\\t\\t),\\n\\t\\t\\t'list'    => array(\\n\\t\\t\\t\\t'vanguard-concord', 'meridian-syndicate', 'deep-archive-collective', 'rust-nebula-outriders',\\n\\t\\t\\t\\t'kythera-prime', 'emberfall', 'station-nine', 'gravity-orchards', 'market-rings',\\n\\t\\t\\t\\t'ilsa-venn', 'oma-desh', 'jax-merrow', 'rook', 'sera-fen',\\n\\t\\t\\t\\t'fold-drive', 'mnemo-core', 'voidglass', 'beacon-network',\\n\\t\\t\\t\\t'sundering-kythera', 'accord-of-glass', 'first-fold-transit', 'archive-schism', 'blockade-years',\\n\\t\\t\\t\\t'sector-map', 'field-manual', 'asteria',\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'Sector Map',\\n\\t\\t\\t'slug'    => 'sector-map',\\n\\t\\t\\t'author'  => 'ilsa-venn',\\n\\t\\t\\t'excerpt' => \\\"A navigator's survey of the worlds and the powers that claim them.\\\",\\n\\t\\t\\t'intro'   => array(\\n\\t\\t\\t\\t\\\"A navigator's survey of the Asteria Sector: the worlds, the powers, and the wreckage between them. For the full index, see the {{the-codex}}.\\\",\\n\\t\\t\\t),\\n\\t\\t\\t'list'    => array(\\n\\t\\t\\t\\t'kythera-prime', 'emberfall', 'station-nine', 'gravity-orchards', 'market-rings',\\n\\t\\t\\t\\t'vanguard-concord', 'meridian-syndicate', 'deep-archive-collective', 'rust-nebula-outriders',\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'Field Manual for New Arrivals',\\n\\t\\t\\t'slug'    => 'field-manual',\\n\\t\\t\\t'author'  => 'jax-merrow',\\n\\t\\t\\t'excerpt' => \\\"Jax Merrow's unofficial \\u2014 and mostly accurate \\u2014 guide to the sector.\\\",\\n\\t\\t\\t'intro'   => array(\\n\\t\\t\\t\\t\\\"Jax Merrow's unofficial \\u2014 and mostly accurate \\u2014 field manual for the Asteria Sector. Read the entries in any order; the graph will show you how they connect.\\\",\\n\\t\\t\\t),\\n\\t\\t\\t'list'    => array(\\n\\t\\t\\t\\t'station-nine', 'market-rings', 'blockade-years', 'accord-of-glass', 'sundering-kythera',\\n\\t\\t\\t\\t'fold-drive', 'voidglass', 'ilsa-venn', 'rook', 'mnemo-core',\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\tarray(\\n\\t\\t\\t'title'   => 'About This Demo',\\n\\t\\t\\t'slug'    => 'about-the-demo',\\n\\t\\t\\t'author'  => 'the-editor',\\n\\t\\t\\t'excerpt' => 'What is this place, and how do you win?',\\n\\t\\t\\t'raw'     => '<p>This entire site \\u2014 WordPress, the plugin, and every word of the {{the-codex}} \\u2014 is running in your browser via <strong>WordPress Playground<\\\/strong>. Nothing was installed; nothing will be saved. Reload the link and a fresh universe boots in seconds.<\\\/p>' . \\\"\\\\n\\\"\\n\\t\\t\\t\\t. '<p>The graph was built by <strong>NV oOS Content Graph<\\\/strong>: no API keys, no external services, just this content turned into nodes and edges. Five challenges:<\\\/p>' . \\\"\\\\n\\\"\\n\\t\\t\\t\\t. '<ol>'\\n\\t\\t\\t\\t. '<li>Open the admin <a href=\\\"\\\/wp-admin\\\/admin.php?page=nvoos-content-graph\\\">Graph Explorer<\\\/a> and search for <em>Kythera<\\\/em>.<\\\/li>'\\n\\t\\t\\t\\t. '<li>Switch the color mode to <em>Community<\\\/em> \\u2014 the factions should separate.<\\\/li>'\\n\\t\\t\\t\\t. '<li>Find the three isolated nodes. (Hint: Settings \\u2192 Content Gap Analysis.)<\\\/li>'\\n\\t\\t\\t\\t. '<li>Run the God Nodes tool and see which entry links to everything.<\\\/li>'\\n\\t\\t\\t\\t. '<li>Export the graph as a PNG \\u2014 then visit the <a href=\\\"\\\/asteria\\\/\\\">front page<\\\/a> to see the {{field-manual}}\\\\'s recommended embed.<\\\/li>'\\n\\t\\t\\t\\t. '<\\\/ol>' . \\\"\\\\n\\\"\\n\\t\\t\\t\\t. '<p>Want this on your own site? <a href=\\\"https:\\\/\\\/wordpress.org\\\/plugins\\\/nvoos-content-graph\\\/\\\">Get NV oOS Content Graph<\\\/a> from the WordPress plugin directory.<\\\/p>',\\n\\t\\t),\\n\\t);\\n\\n\\t$titles = nvoos_cg_demo_link_map( $posts, $pages );\\n\\n\\t\\\/\\\/ 8. Insert posts.\\n\\tforeach ( $posts as $p ) {\\n\\t\\tif ( get_page_by_path( $p['slug'], OBJECT, 'post' ) ) {\\n\\t\\t\\tcontinue;\\n\\t\\t}\\n\\t\\t$post_id = wp_insert_post(\\n\\t\\t\\tarray(\\n\\t\\t\\t\\t'post_title'   => $p['title'],\\n\\t\\t\\t\\t'post_name'    => $p['slug'],\\n\\t\\t\\t\\t'post_content' => nvoos_cg_demo_render_body( $p['body'], $titles ),\\n\\t\\t\\t\\t'post_excerpt' => $p['excerpt'],\\n\\t\\t\\t\\t'post_status'  => 'publish',\\n\\t\\t\\t\\t'post_author'  => isset( $author_ids[ $p['author'] ] ) ? (int) $author_ids[ $p['author'] ] : 0,\\n\\t\\t\\t\\t'post_type'    => 'post',\\n\\t\\t\\t),\\n\\t\\t\\ttrue\\n\\t\\t);\\n\\t\\tif ( is_wp_error( $post_id ) ) {\\n\\t\\t\\tcontinue;\\n\\t\\t}\\n\\t\\t$post_id = (int) $post_id;\\n\\n\\t\\tif ( ! empty( $p['orphan'] ) ) {\\n\\t\\t\\t\\\/\\\/ True degree-0 node: no author, no terms, no links.\\n\\t\\t\\twp_delete_object_term_relationships( $post_id, array( 'category', 'post_tag' ) );\\n\\t\\t\\tcontinue;\\n\\t\\t}\\n\\n\\t\\tif ( ! empty( $cat_ids[ $p['cat'] ] ) ) {\\n\\t\\t\\twp_set_post_categories( $post_id, array( (int) $cat_ids[ $p['cat'] ] ) );\\n\\t\\t}\\n\\t\\t$tag_names = array();\\n\\t\\tforeach ( $p['tags'] as $tag_slug ) {\\n\\t\\t\\tif ( isset( $tags[ $tag_slug ] ) ) {\\n\\t\\t\\t\\t$tag_names[] = $tags[ $tag_slug ];\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\tif ( $tag_names ) {\\n\\t\\t\\twp_set_post_terms( $post_id, $tag_names, 'post_tag' );\\n\\t\\t}\\n\\t}\\n\\n\\t\\\/\\\/ 9. Insert pages.\\n\\tforeach ( $pages as $p ) {\\n\\t\\tif ( get_page_by_path( $p['slug'], OBJECT, 'page' ) ) {\\n\\t\\t\\tcontinue;\\n\\t\\t}\\n\\t\\tif ( isset( $p['raw'] ) ) {\\n\\t\\t\\t$content = nvoos_cg_demo_render_tokens( $p['raw'], $titles );\\n\\t\\t} elseif ( isset( $p['list'] ) ) {\\n\\t\\t\\t$content = nvoos_cg_demo_render_list( $p['intro'], $p['list'], $titles );\\n\\t\\t} else {\\n\\t\\t\\t$content = nvoos_cg_demo_render_body( $p['body'], $titles );\\n\\t\\t}\\n\\t\\twp_insert_post(\\n\\t\\t\\tarray(\\n\\t\\t\\t\\t'post_title'   => $p['title'],\\n\\t\\t\\t\\t'post_name'    => $p['slug'],\\n\\t\\t\\t\\t'post_content' => $content,\\n\\t\\t\\t\\t'post_excerpt' => $p['excerpt'],\\n\\t\\t\\t\\t'post_status'  => 'publish',\\n\\t\\t\\t\\t'post_author'  => isset( $author_ids[ $p['author'] ] ) ? (int) $author_ids[ $p['author'] ] : 1,\\n\\t\\t\\t\\t'post_type'    => 'page',\\n\\t\\t\\t),\\n\\t\\t\\ttrue\\n\\t\\t);\\n\\t}\\n\\n\\tupdate_option( 'nvoos_cg_demo_seeded', 1 );\\n}\\nnvoos_cg_demo_seed();\"},{\"step\":\"runPHP\",\"code\":\"<?php require_once '\\\/wordpress\\\/wp-load.php';\\n$settings = get_option( 'nvoos_content_graph_settings', array() );\\nif ( ! is_array( $settings ) ) {\\n\\t$settings = array();\\n}\\n\\\/\\\/ Re-enable live graph updates now that the bulk seed is done.\\n$settings['auto_rebuild'] = 1;\\nupdate_option( 'nvoos_content_graph_settings', $settings );\\n\\n\\\/\\\/ Make the Asteria page the front page so \\\/ shows the [nvoos_graph] embed.\\n$home = get_page_by_path( 'asteria', OBJECT, 'page' );\\nif ( $home instanceof WP_Post ) {\\n\\tupdate_option( 'show_on_front', 'page' );\\n\\tupdate_option( 'page_on_front', (int) $home->ID );\\n}\\n\\n\\\/\\\/ Deterministic full build via the plugin's public hook (the activation\\n\\\/\\\/ one-shot cron is non-deterministic inside the Playground runtime).\\ndo_action( 'nvoos_content_graph\\\/initial_build' );\"},{\"step\":\"installPlugin\",\"pluginData\":{\"resource\":\"wordpress.org\\\/plugins\",\"slug\":\"nvoos-content-graph\"},\"options\":{\"activate\":true}}]}"}},"all_blocks":{"nvoos-content-graph\/graph":{"name":"nvoos-content-graph\/graph","title":"Graph"}},"tagged_versions":["1.0.3","1.0.7","1.0.8"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3667764,"resolution":"1","location":"assets","locale":"","width":1280,"height":830},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3667764,"resolution":"2","location":"assets","locale":"","width":1238,"height":902},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3667764,"resolution":"3","location":"assets","locale":"","width":1238,"height":835},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3667764,"resolution":"4","location":"assets","locale":"","width":1238,"height":1706},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3667764,"resolution":"5","location":"assets","locale":"","width":1440,"height":1448},"screenshot-6.png":{"filename":"screenshot-6.png","revision":3667764,"resolution":"6","location":"assets","locale":"","width":1238,"height":676}},"screenshots":{"1":"Knowledge Graph \u2014 main explorer view","2":"Settings \u2014 build schedule, auto-rebuild, and display options","3":"Remote Sources \u2014 connect external data (Wikidata, REST APIs, RSS)","4":"Sources \u2014 choose which post types and content types are indexed","5":"Frontend embed \u2014 the [nvoos_graph] shortcode on any page","6":"Graph Explorer \u2014 interactive Cytoscape.js visualization with search and node details"}},"plugin_section":[],"plugin_tags":[43908,252560,277721,12087,11590],"plugin_category":[],"plugin_contributors":[277722],"plugin_business_model":[],"class_list":["post-353496","plugin","type-plugin","status-publish","hentry","plugin_tags-content-strategy","plugin_tags-content-visualization","plugin_tags-cytoscape","plugin_tags-knowledge-graph","plugin_tags-semantic-web","plugin_contributors-vsamtani","plugin_committers-vsamtani"],"banners":{"banner":"https:\/\/ps.w.org\/nvoos-content-graph\/assets\/banner-772x250.png?rev=3667764","banner_2x":"https:\/\/ps.w.org\/nvoos-content-graph\/assets\/banner-1544x500.png?rev=3667764","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/nvoos-content-graph\/assets\/icon-128x128.png?rev=3667805","icon_2x":"https:\/\/ps.w.org\/nvoos-content-graph\/assets\/icon-256x256.png?rev=3667805","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/nvoos-content-graph\/assets\/screenshot-1.png?rev=3667764","caption":"Knowledge Graph \u2014 main explorer view"},{"src":"https:\/\/ps.w.org\/nvoos-content-graph\/assets\/screenshot-2.png?rev=3667764","caption":"Settings \u2014 build schedule, auto-rebuild, and display options"},{"src":"https:\/\/ps.w.org\/nvoos-content-graph\/assets\/screenshot-3.png?rev=3667764","caption":"Remote Sources \u2014 connect external data (Wikidata, REST APIs, RSS)"},{"src":"https:\/\/ps.w.org\/nvoos-content-graph\/assets\/screenshot-4.png?rev=3667764","caption":"Sources \u2014 choose which post types and content types are indexed"},{"src":"https:\/\/ps.w.org\/nvoos-content-graph\/assets\/screenshot-5.png?rev=3667764","caption":"Frontend embed \u2014 the [nvoos_graph] shortcode on any page"},{"src":"https:\/\/ps.w.org\/nvoos-content-graph\/assets\/screenshot-6.png?rev=3667764","caption":"Graph Explorer \u2014 interactive Cytoscape.js visualization with search and node details"}],"raw_content":"<!--section=description-->\n<p>NV oOS Content Graph transforms your WordPress content into a visual knowledge graph \u2014 organized, searchable, and interactive. Every post, page, category, tag, and author becomes a node; every relationship becomes an edge.<\/p>\n\n<p><strong>No API keys. No AI required.<\/strong> The core graph engine runs entirely on your WordPress server using your existing content. Optional remote sources (like Wikidata) are opt-in \u2014 see External services below.<\/p>\n\n<h3>What You Get<\/h3>\n\n<h4>One-Click Graph Builder<\/h4>\n\n<p>Click \"Build Graph\" and ~10-30 seconds later, your entire site becomes a visual graph. Supports incremental rebuilds and scheduled cron updates.<\/p>\n\n<h4>Interactive Graph Explorer<\/h4>\n\n<p>Explore your content visually using Cytoscape.js. Search for nodes by label, click for details, zoom and pan. Color-coded by content type (posts, pages, terms, users).<\/p>\n\n<h4>Visual Theming &amp; Styling<\/h4>\n\n<p>Style the graph to match your brand from the new Appearance tab: dark, light, auto, and WordPress-admin themes; per-type colors and icons (colorblind-safe defaults with automatic WCAG 2.2 contrast correction); color-by-type\/community\/degree modes; an interactive legend; edge style presets; layout presets; a minimap; keyboard navigation; and theme-aware PNG export. See <code>docs\/visual-theming.md<\/code>.<\/p>\n\n<h4>Content Gap Analysis<\/h4>\n\n<p>Discover orphan content (no internal links), thin topic clusters, and missing link opportunities. Generate actionable content strategy recommendations.<\/p>\n\n<h4>Six Export Formats<\/h4>\n\n<p>Download your graph as JSON (NetworkX), GraphML (Gephi\/yEd), CSV, Neo4j Cypher, Obsidian vault, or standalone HTML page.<\/p>\n\n<h4>Schema.org JSON-LD<\/h4>\n\n<p>Automatic structured data injection for SEO \u2014 taxonomy terms as <code>about<\/code> and internal links as <code>relatedLink<\/code>.<\/p>\n\n<h4>Related Content Widget<\/h4>\n\n<p>Appends graph-neighbor posts to your content based on knowledge graph proximity.<\/p>\n\n<h4>REST API<\/h4>\n\n<p>Full programmatic access with 18 endpoints. Read endpoints require the <code>read<\/code> capability (all logged-in users) or a valid guest token (guest tokens are provided by the NV oOS base plugin when installed); write endpoints require <code>manage_options<\/code>.<\/p>\n\n<h4>Extensible Tool System<\/h4>\n\n<p>14 built-in tools for graph operations: query, search, traverse, analyze, export. Addon plugins can register their own tools.<\/p>\n\n<h3>Addon Ecosystem (all optional)<\/h3>\n\n<ul>\n<li><strong>nvoos-content-graph-ai<\/strong> \u2014 AI chat assistant with 13 AI providers, AI tools, embeddings, RAG, and agent memory<\/li>\n<li><strong>nvoos-content-graph-ai-platform<\/strong> \u2014 agents, skills, slash-commands, professions, A2A, ACP, and federation<\/li>\n<\/ul>\n\n<h3>Privacy Notice<\/h3>\n\n<p>This plugin does not collect, store, or transmit any personal data by default. The core graph engine runs entirely on your WordPress server using your existing content.<\/p>\n\n<p><strong>Remote Sources (opt-in only):<\/strong> When you explicitly configure a remote source driver (e.g. Wikidata, REST API, RSS feed), the plugin sends HTTP requests to the URLs you provide. No data is sent off-site without your explicit setup. Remote source credentials (API keys, tokens, passwords) are stored in the database encrypted with AES-256-GCM via the OpenSSL PHP extension, falling back to base64 encoding with an admin warning when OpenSSL is unavailable.<\/p>\n\n<p><strong>Optional AI Addons:<\/strong> The companion plugin <code>nvoos-content-graph-ai<\/code> (not included in this plugin) sends content to third-party AI providers (OpenAI, Google Gemini, etc.) when configured. Refer to that addon's documentation for its privacy policies.<\/p>\n\n<h3>External services<\/h3>\n\n<p>This plugin does not require any external service for its core functionality. All graph data is computed and stored on your own WordPress server.<\/p>\n\n<p><strong>Wikidata (wikidata.org)<\/strong><\/p>\n\n<p>The optional \"Resolve External Entity\" tool and the Wikidata remote-source driver query the Wikidata API (<code>https:\/\/www.wikidata.org\/w\/api.php<\/code>) \u2014 only when you explicitly request an entity lookup by QID (e.g. Q42) or configure a Wikidata source.<\/p>\n\n<ul>\n<li><strong>What is sent:<\/strong> the QID or entity identifier you provide, plus standard HTTP request metadata (your server's IP address, user agent).<\/li>\n<li><strong>When:<\/strong> only on your explicit request; never automatically or in the background.<\/li>\n<li><strong>What it is used for:<\/strong> fetching the entity's label, description, and sitelinks so it can be ingested as a graph node.<\/li>\n<li><strong>Service provider:<\/strong> Wikimedia Foundation \u2014 Terms of Use: https:\/\/foundation.wikimedia.org\/wiki\/Policy:Terms_of_Use \u2014 Privacy Policy: https:\/\/foundation.wikimedia.org\/wiki\/Policy:Privacy_policy<\/li>\n<\/ul>\n\n<p><strong>User-configured remote sources (opt-in only)<\/strong><\/p>\n\n<p>When you configure a remote source driver (REST API, RSS\/Sitemap feed, SPARQL endpoint, webhook receiver, etc.) in Settings, the plugin sends HTTP requests to the URLs you provide. What is sent depends entirely on the endpoint you configure. These requests happen only when you manually trigger a sync, schedule one, or receive a webhook. Remote source credentials (API keys, tokens, passwords) are stored in the database encrypted with AES-256-GCM via the OpenSSL PHP extension.<\/p>\n\n<p><strong>Stripe payments (opt-in only)<\/strong><\/p>\n\n<p>The \"Get NV oOS Complete\" buttons on the plugin's settings page open an optional checkout for the NV oOS Complete plugin bundle \u2014 the full NV oOS plugin (base + Pro) installed as a separate plugin. Card and payment details are entered directly on Stripe's servers (<code>js.stripe.com<\/code> iframe); the plugin never stores or transmits card data. Stripe.js is loaded only when the purchase modal is opened \u2014 merely visiting the settings page contacts no third party. The checkout is created and verified by the vendor's own server, operated by NV Digital Solutions on behalf of NV Digital Unlocked LLC (the seller of record); this plugin only sends the product name, your site URL, the Stripe payment ID, the purchasing administrator's email address, the buyer's declared country, and a timestamp recording your agreement to the Terms of Service to that service. For buyers in the EU, a billing address (street, city, optional postal code) is collected in the modal, attached to the payment for VAT records, and shown to the vendor on the license. A local purchase record (license key, payment ID, price paid, the purchasing administrator's email address, country, and the consent timestamp) is stored after the vendor confirms the payment. Payment is entirely optional \u2014 the core plugin is fully functional without it.<\/p>\n\n<ul>\n<li><strong>Service provider:<\/strong> Stripe, Inc. \u2014 Privacy Policy: https:\/\/stripe.com\/privacy<\/li>\n<\/ul>\n\n<p><strong>Installing the NV oOS Complete bundle (manual install is the primary path)<\/strong><\/p>\n\n<p>After a successful purchase you can download the NV oOS Complete ZIP and install it manually via <strong>Plugins \u2192 Add New Plugin \u2192 Upload Plugin<\/strong> \u2014 this is the recommended, fully transparent path. The plugin also offers an optional automatic installation (a convenience that downloads the ZIP and runs WordPress' built-in installer for you). Either way, the ZIP comes from a signed, short-lived URL provided by the vendor's checkout service (which serves the package from the project's GitHub release page, <code>github.com<\/code>). No data is sent to GitHub.<\/p>\n\n<h3>Third-Party Libraries<\/h3>\n\n<p>This plugin bundles the following open-source libraries:<\/p>\n\n<ul>\n<li><strong>Cytoscape.js<\/strong> v3.28.1 \u2014 MIT License \u2014 https:\/\/github.com\/cytoscape\/cytoscape.js<\/li>\n<li><strong>cytoscape-fcose<\/strong> v2.2.0 \u2014 MIT License \u2014 https:\/\/github.com\/iVis-at-Bilkent\/cytoscape.js-fcose<\/li>\n<li><strong>layout-base<\/strong> v2.0.1 \u2014 MIT License \u2014 https:\/\/github.com\/iVis-at-Bilkent\/layout-base<\/li>\n<li><strong>cose-base<\/strong> v2.2.0 \u2014 MIT License \u2014 https:\/\/github.com\/iVis-at-Bilkent\/cose-base<\/li>\n<\/ul>\n\n<p>All libraries are served locally from <code>assets\/vendor\/<\/code> and never loaded from third-party CDNs. Each library's license text ships alongside it (<code>assets\/vendor\/&lt;name&gt;\/LICENSE<\/code>).<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>nvoos-content-graph<\/code> folder to <code>\/wp-content\/plugins\/<\/code><\/li>\n<li>Activate the plugin through the 'Plugins' menu<\/li>\n<li>Go to <strong>Knowledge Graph \u2192 Settings<\/strong><\/li>\n<li>Click \"Build Graph\"<\/li>\n<\/ol>\n\n<p>That's it. Your content is now a knowledge graph.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"do%20i%20need%20an%20api%20key%3F\"><h3>Do I need an API key?<\/h3><\/dt>\n<dd><p>No. The core graph engine works with zero external dependencies. AI features require their respective addon plugins and API keys.<\/p><\/dd>\n<dt id=\"how%20long%20does%20a%20build%20take%3F\"><h3>How long does a build take?<\/h3><\/dt>\n<dd><p>~10-30 seconds for a typical WordPress site (100-500 posts). Large sites (10,000+ posts) may take 1-2 minutes.<\/p><\/dd>\n<dt id=\"can%20i%20build%20incrementally%3F\"><h3>Can I build incrementally?<\/h3><\/dt>\n<dd><p>Yes. Enable \"Incremental Builds\" in settings to only process content changed since the last build.<\/p><\/dd>\n<dt id=\"is%20this%20compatible%20with%20my%20theme%3F\"><h3>Is this compatible with my theme?<\/h3><\/dt>\n<dd><p>Yes. The graph explorer, shortcode, related content widget, and schema.org injection work with any theme. The shortcode <code>[nvoos_graph]<\/code> embeds wherever you place it.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20custom%20post%20types%3F\"><h3>Does it work with custom post types?<\/h3><\/dt>\n<dd><p>Yes. Any public post type (including JetEngine CPTs) is automatically detected. You can configure which post types to index in Settings.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20jetengine%20custom%20content%20types%20%28ccts%29%3F\"><h3>Does it work with JetEngine Custom Content Types (CCTs)?<\/h3><\/dt>\n<dd><p>Yes. JetEngine CCTs are detected and indexed by default, and the Settings \u2192 Sources tab lists every registered CCT with include\/exclude checkboxes (including CCTs registered by the NV oOS base+Pro plugin). Uncheck a CCT to exclude it from the next graph build.<\/p><\/dd>\n<dt id=\"does%20the%20plugin%20connect%20to%20external%20services%3F\"><h3>Does the plugin connect to external services?<\/h3><\/dt>\n<dd><p>The core graph engine runs entirely on your server. The optional \"Resolve External Entity\" tool queries Wikidata (wikidata.org) when you explicitly ask it to look up a QID. Remote source drivers connect to user-configured endpoints (REST APIs, RSS feeds, SPARQL, etc.) only when you set them up in Settings. See the External services section below for full details.<\/p><\/dd>\n<dt id=\"do%20i%20have%20to%20pay%20for%20the%20nv%20oos%20complete%20bundle%3F\"><h3>Do I have to pay for the NV oOS Complete bundle?<\/h3><\/dt>\n<dd><p>No. This plugin is complete and fully functional for free. The NV oOS Complete bundle (the full NV oOS plugin, base + Pro) is an optional, separately installed paid product, sold off-directory by NV Digital Unlocked LLC under license from NV Digital Solutions. Purchases are covered by a 30-day money-back guarantee; see the vendor's Terms of Service and Refund Policy linked in the checkout.<\/p><\/dd>\n<dt id=\"does%20it%20work%20on%20multisite%3F\"><h3>Does it work on multisite?<\/h3><\/dt>\n<dd><p>Yes. The plugin supports WordPress multisite with per-site configuration.<\/p><\/dd>\n<dt id=\"what%20happens%20if%20i%20deactivate%3F\"><h3>What happens if I deactivate?<\/h3><\/dt>\n<dd><p>Cron schedules are cleared. Your data stays intact \u2014 reactivate at any time.<\/p><\/dd>\n<dt id=\"what%20happens%20if%20i%20uninstall%3F\"><h3>What happens if I uninstall?<\/h3><\/dt>\n<dd><p>All custom tables and options are removed (see <code>uninstall.php<\/code>). Export your graph first if you want to keep it.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.0.8 \u2014 2026-09-13<\/h4>\n\n<ul>\n<li>Fixed Stripe checkout failing for non-EU buyers: the Payment Element no longer requires a billing-address country that the modal only collects from EU buyers<\/li>\n<li>Already-licensed sites can no longer start a new payment: the purchase modal shows the existing license instead of a chargeable Stripe form<\/li>\n<\/ul>\n\n<h4>1.0.7 \u2014 2026-09-12<\/h4>\n\n<ul>\n<li>Checkout consent checkbox (Terms of Service + 30-day refund policy) and buyer-email collection with Stripe receipt delivery<\/li>\n<li>Buyer country and conditional EU billing address (VAT records) collected in the purchase modal<\/li>\n<li>Manual ZIP download offered after purchase alongside the automatic installer; manual install documented as the primary path<\/li>\n<li>Roadmap link in the purchase modal; release-notes link and support email on the purchase success screen<\/li>\n<li>Updated privacy disclosures (buyer email, country, EU billing address, and Terms consent timestamp sent to the checkout service)<\/li>\n<li>Purchase modal price now syncs from the vendor's configured price (fallback default $34.99)<\/li>\n<li>NV Digital Unlocked LLC named as the seller of record in checkout copy and disclosures<\/li>\n<li>\"Introductory price \u2014 prices are subject to change\" note added to the purchase modal<\/li>\n<\/ul>\n\n<h4>1.0.6 \u2014 2026-09-08<\/h4>\n\n<ul>\n<li>Checkout now delivers the NV oOS Complete plugin bundle (base + Pro as a separate plugin) instead of the companion AI addon<\/li>\n<li>The installer refuses to create a second copy of NV oOS when the base plugin is already installed on the site<\/li>\n<li>Updated privacy disclosures for the checkout flow<\/li>\n<\/ul>\n\n<h4>1.0.5 \u2014 2026-09-08<\/h4>\n\n<ul>\n<li>Agent Memory Bridge: memories stored by the NV oOS base+Pro plugin (<code>wp_mcp_ai_memory_stored<\/code>) are now projected into the knowledge graph as <code>memory:*<\/code> nodes with agent\/wing\/room edges<\/li>\n<li>Graph-ranked memory retrieval seam for the NV oOS <code>wake_up_context<\/code> tool (<code>wp_mcp_ai_wake_up_context_graph_retriever<\/code> filter)<\/li>\n<li>New <code>Db::tablesInstalled()<\/code> schema probe; PHPUnit coverage for the bridge and its schema-absent degradation<\/li>\n<\/ul>\n\n<h4>1.0.4 \u2014 2026-09-05<\/h4>\n\n<ul>\n<li>New Appearance tab: themes (dark\/light\/auto\/admin), per-type color and icon overrides, WCAG contrast report, and one-click style presets<\/li>\n<li>Icon glyphs and legend panel in the graph explorer; color-by type\/community\/degree\/monochrome modes<\/li>\n<li>Relationship-aware edge styling (color families, arrowheads, tapered, haystack density mode) and edge labels<\/li>\n<li>Minimap, zoom controls, layout presets, keyboard navigation, reduced-motion support, view persistence, and theme-aware PNG export<\/li>\n<li>New <code>GET \/edges<\/code> REST endpoint; front-end shortcode\/block visual attributes (<code>theme<\/code>, <code>color_by<\/code>, <code>show_legend<\/code>, <code>show_icons<\/code>, <code>show_edges<\/code>, <code>edge_style<\/code>)<\/li>\n<li>Stripe checkout for the AI addon (payments via the vendor checkout API; no Stripe keys ship in the plugin; Stripe.js loads only when the purchase modal opens)<\/li>\n<\/ul>\n\n<h4>1.0.3 \u2014 2026-08-20<\/h4>\n\n<ul>\n<li>Encrypt remote-source credentials (AES-256-GCM) before storing them<\/li>\n<li>Fix <code>[nvoos_graph]<\/code> shortcode and block embed (invalid inline script)<\/li>\n<li>Wire the Scheduled Rebuild setting to WP-Cron (new \"Never\" option)<\/li>\n<li>Fix the admin Test button and REST \/test endpoint (now use per-source credentials)<\/li>\n<li>Reject unknown drivers and sanitize config in both source-creation paths<\/li>\n<li>Re-validate redirects against the SSRF guard<\/li>\n<li>Preserve external_id, source_slug, confidence, and expires_at on node updates<\/li>\n<li>Remote Sources modal now renders schema field types correctly<\/li>\n<li>Remove the unregistered Graph Explorer admin page (embedded in Settings)<\/li>\n<li>Ship the Composer autoloader intact in distribution builds<\/li>\n<li>Restrict tool-level auto-ingest to administrators<\/li>\n<li>Add WordPress.org screenshot assets (.wordpress-org\/assets)<\/li>\n<\/ul>\n\n<h4>1.0.2 \u2014 2026-08-18<\/h4>\n\n<ul>\n<li>Renamed from \"NV oOS Graphify\" to \"NV oOS Content Graph\" (new slug <code>nvoos-content-graph<\/code>)<\/li>\n<li>Hardened Schema.org JSON-LD output against script-tag breakout<\/li>\n<li>Restricted REST <code>\/resolve<\/code> auto-ingest to administrators<\/li>\n<li>Replaced inline admin JavaScript with enqueued asset<\/li>\n<li>Added external-services disclosure (Wikidata terms and privacy policy)<\/li>\n<li>Field-map validation is now self-contained (no legacy addon dependency)<\/li>\n<li>Embeddings reindexing bridges to the AI addon's embedding service<\/li>\n<\/ul>\n\n<h4>1.0.0 \u2014 2026-06-05<\/h4>\n\n<ul>\n<li>Initial standalone release<\/li>\n<li>PSR-4 architecture: <code>NvoosContentGraph\\<\/code> namespace<\/li>\n<li>5 custom database tables with dbDelta() migrations<\/li>\n<li>14 built-in tools implementing <code>NvoosContentGraph\\Contracts\\Tool<\/code><\/li>\n<li>14 REST API endpoints at <code>\/wp-json\/nvoos-content-graph\/v1\/<\/code><\/li>\n<li>Cytoscape.js graph explorer (admin + frontend)<\/li>\n<li>Tabbed settings page with per-tab sanitisation<\/li>\n<li>6 export formats (JSON, GraphML, CSV, Neo4j, Obsidian, HTML)<\/li>\n<li>Schema.org JSON-LD injection for SEO<\/li>\n<li>Related content widget based on graph proximity<\/li>\n<li>Louvain community detection + content gap analysis<\/li>\n<li><code>[nvoos_graph]<\/code> shortcode + Gutenberg block<\/li>\n<li>JetEngine Custom Content Type (CCT) support<\/li>\n<li>WordPress multisite compatible<\/li>\n<li>PHP 8.1+, WordPress 6.5+, GPL-3.0-or-later<\/li>\n<\/ul>","raw_excerpt":"Map your WordPress content into an interactive knowledge graph. See relationships between posts, terms, and authors. No API keys required.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/ary.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/353496","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ary.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/ary.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/ary.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=353496"}],"author":[{"embeddable":true,"href":"https:\/\/ary.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/vsamtani"}],"wp:attachment":[{"href":"https:\/\/ary.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=353496"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/ary.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=353496"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/ary.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=353496"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/ary.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=353496"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/ary.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=353496"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/ary.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=353496"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}