[{"data":1,"prerenderedAt":8089},["ShallowReactive",2],{"navigation":3,"/advanced-and-expert-topics/plugin-architectures-for-django-apps":1016,"/advanced-and-expert-topics/plugin-architectures-for-django-apps-surround":8084},[4,54,89,123,165,211,253,331,389,439,462,488,514,540,578,624,650,672,702,736,774,800,850,856,862,868,874,928],{"title":5,"path":6,"stem":7,"children":8},"Introduction and Foundations","/introduction-and-foundations","01.introduction-and-foundations/01.index",[9,10,14,18,22,26,30,34,38,42,46,50],{"title":5,"path":6,"stem":7},{"title":11,"path":12,"stem":13},"What is Django","/introduction-and-foundations/what-is-django","01.introduction-and-foundations/02.what-is-django",{"title":15,"path":16,"stem":17},"Key Concepts and Philosophy","/introduction-and-foundations/key-concepts-and-philosophy","01.introduction-and-foundations/03.key-concepts-and-philosophy",{"title":19,"path":20,"stem":21},"MVC vs MVT: Understanding Django's Architecture","/introduction-and-foundations/mvc-vs-mvt","01.introduction-and-foundations/04.mvc-vs-mvt",{"title":23,"path":24,"stem":25},"Project Structure Overview","/introduction-and-foundations/project-structure-overview","01.introduction-and-foundations/05.project-structure-overview",{"title":27,"path":28,"stem":29},"Installing Django","/introduction-and-foundations/installing-django","01.introduction-and-foundations/06.installing-django",{"title":31,"path":32,"stem":33},"Creating Your First Django Project","/introduction-and-foundations/creating-first-project","01.introduction-and-foundations/07.creating-first-project",{"title":35,"path":36,"stem":37},"Creating Your First Django App","/introduction-and-foundations/creating-first-app","01.introduction-and-foundations/08.creating-first-app",{"title":39,"path":40,"stem":41},"Your First Django \"Hello World\"","/introduction-and-foundations/hello-world","01.introduction-and-foundations/09.hello-world",{"title":43,"path":44,"stem":45},"Django Quick Start Guide","/introduction-and-foundations/quick-start-guide","01.introduction-and-foundations/10.quick-start-guide",{"title":47,"path":48,"stem":49},"How Django Handles Requests","/introduction-and-foundations/how-django-handles-requests","01.introduction-and-foundations/11.how-django-handles-requests",{"title":51,"path":52,"stem":53},"Django Settings","/introduction-and-foundations/django-settings","01.introduction-and-foundations/12.django-settings",{"title":55,"path":56,"stem":57,"children":58},"The Development Environment","/development-environment","02.development-environment/1.index",[59,61,65,69,73,77,81,85],{"title":60,"path":56,"stem":57},"Development Environment",{"title":62,"path":63,"stem":64},"Recommended Tooling for Django Development","/development-environment/recommended-tooling","02.development-environment/2.recommended-tooling",{"title":66,"path":67,"stem":68},"Virtual Environments","/development-environment/virtual-environments","02.development-environment/3.virtual-environments",{"title":70,"path":71,"stem":72},"Django Admin and Management Commands","/development-environment/admin-and-management-commands","02.development-environment/4.admin-and-management-commands",{"title":74,"path":75,"stem":76},"Django Project Settings","/development-environment/project-settings","02.development-environment/5.project-settings",{"title":78,"path":79,"stem":80},"Managing Django Environments: Local, Staging, and Production","/development-environment/environments-local-staging-production","02.development-environment/6.environments-local-staging-production",{"title":82,"path":83,"stem":84},"Running Django Development Server","/development-environment/running-development-server","02.development-environment/7.running-development-server",{"title":86,"path":87,"stem":88},"Working with Django Shell","/development-environment/working-with-shell","02.development-environment/8.working-with-shell",{"title":90,"path":91,"stem":92,"children":93},"Templates and Presentation Layer","/templates-and-presentation","03.templates-and-presentation/1.index",[94,95,99,103,107,111,115,119],{"title":90,"path":91,"stem":92},{"title":96,"path":97,"stem":98},"Introduction to Django Templates","/templates-and-presentation/introduction-to-templates","03.templates-and-presentation/2.introduction-to-templates",{"title":100,"path":101,"stem":102},"The Django Template Language","/templates-and-presentation/django-template-language","03.templates-and-presentation/3.django-template-language",{"title":104,"path":105,"stem":106},"Template Inheritance","/templates-and-presentation/template-inheritance","03.templates-and-presentation/4.template-inheritance",{"title":108,"path":109,"stem":110},"Built-in Template Tags and Filters","/templates-and-presentation/built-in-template-tags-and-filters","03.templates-and-presentation/5.built-in-template-tags-and-filters",{"title":112,"path":113,"stem":114},"Including Static Files","/templates-and-presentation/including-static-files","03.templates-and-presentation/6.including-static-files",{"title":116,"path":117,"stem":118},"Working with Media Files","/templates-and-presentation/working-with-media-files","03.templates-and-presentation/7.working-with-media-files",{"title":120,"path":121,"stem":122},"Using Alternative Template Engines","/templates-and-presentation/using-alternative-template-engines","03.templates-and-presentation/8.using-alternative-template-engines",{"title":124,"path":125,"stem":126,"children":127},"URLs and Views","/urls-and-views","04.urls-and-views/01.index",[128,129,133,137,141,145,149,153,157,161],{"title":124,"path":125,"stem":126},{"title":130,"path":131,"stem":132},"The URL Dispatcher","/urls-and-views/the-url-dispatcher","04.urls-and-views/02.the-url-dispatcher",{"title":134,"path":135,"stem":136},"Writing Function-Based Views","/urls-and-views/writing-function-based-views","04.urls-and-views/03.writing-function-based-views",{"title":138,"path":139,"stem":140},"View Decorators","/urls-and-views/view-decorators","04.urls-and-views/04.view-decorators",{"title":142,"path":143,"stem":144},"Rendering Responses","/urls-and-views/rendering-responses","04.urls-and-views/05.rendering-responses",{"title":146,"path":147,"stem":148},"Redirects","/urls-and-views/redirects","04.urls-and-views/06.redirects",{"title":150,"path":151,"stem":152},"Handling HTTP Methods","/urls-and-views/handling-http-methods","04.urls-and-views/07.handling-http-methods",{"title":154,"path":155,"stem":156},"Conditional View Processing","/urls-and-views/conditional-view-processing","04.urls-and-views/08.conditional-view-processing",{"title":158,"path":159,"stem":160},"File Uploads","/urls-and-views/file-uploads","04.urls-and-views/09.file-uploads",{"title":162,"path":163,"stem":164},"Using Django Shortcut Functions","/urls-and-views/using-django-shortcut-functions","04.urls-and-views/10.using-django-shortcut-functions",{"title":166,"path":167,"stem":168,"children":169},"Class Based Views","/class-based-views","05.class-based-views/01.index",[170,171,175,179,183,187,191,195,199,203,207],{"title":166,"path":167,"stem":168},{"title":172,"path":173,"stem":174},"Introduction to Class-Based Views","/class-based-views/introduction-to-class-based-views","05.class-based-views/02.introduction-to-class-based-views",{"title":176,"path":177,"stem":178},"Common Base Classes","/class-based-views/common-base-classes","05.class-based-views/03.common-base-classes",{"title":180,"path":181,"stem":182},"Built-in Generic Views","/class-based-views/built-in-generic-views","05.class-based-views/04.built-in-generic-views",{"title":184,"path":185,"stem":186},"Views for CRUD Operations","/class-based-views/views-for-crud-operations","05.class-based-views/05.views-for-crud-operations",{"title":188,"path":189,"stem":190},"Handling Forms with Class-Based Views","/class-based-views/handling-forms-with-class-based-views","05.class-based-views/06.handling-forms-with-class-based-views",{"title":192,"path":193,"stem":194},"Using Mixins","/class-based-views/using-mixins","05.class-based-views/07.using-mixins",{"title":196,"path":197,"stem":198},"URL Configuration with Class-Based Views","/class-based-views/url-configuration-with-class-based-views","05.class-based-views/08.url-configuration-with-class-based-views",{"title":200,"path":201,"stem":202},"Subclassing Generic Views","/class-based-views/subclassing-generic-views","05.class-based-views/09.subclassing-generic-views",{"title":204,"path":205,"stem":206},"Asynchronous Class-Based Views","/class-based-views/asynchronous-class-based-views","05.class-based-views/10.asynchronous-class-based-views",{"title":208,"path":209,"stem":210},"Pagination","/class-based-views/pagination","05.class-based-views/11.pagination",{"title":212,"path":213,"stem":214,"children":215},"Forms and User Input","/forms-and-user-input","06.forms-and-user-input/01.index",[216,217,221,225,229,233,237,241,245,249],{"title":212,"path":213,"stem":214},{"title":218,"path":219,"stem":220},"Understanding HTML Forms","/forms-and-user-input/understanding-html-forms","06.forms-and-user-input/02.understanding-html-forms",{"title":222,"path":223,"stem":224},"Django's Role in Form Handling","/forms-and-user-input/djangos-role-in-form-handling","06.forms-and-user-input/03.djangos-role-in-form-handling",{"title":226,"path":227,"stem":228},"Creating Forms with Forms API","/forms-and-user-input/creating-forms-with-forms-api","06.forms-and-user-input/04.creating-forms-with-forms-api",{"title":230,"path":231,"stem":232},"Form Validation","/forms-and-user-input/form-validation","06.forms-and-user-input/05.form-validation",{"title":234,"path":235,"stem":236},"Built-in Fields and Widgets","/forms-and-user-input/built-in-fields-and-widgets","06.forms-and-user-input/06.built-in-fields-and-widgets",{"title":238,"path":239,"stem":240},"Form Rendering in Templates","/forms-and-user-input/form-rendering-in-templates","06.forms-and-user-input/07.form-rendering-in-templates",{"title":242,"path":243,"stem":244},"Model Forms","/forms-and-user-input/model-forms","06.forms-and-user-input/08.model-forms",{"title":246,"path":247,"stem":248},"Advanced Form Techniques","/forms-and-user-input/advanced-form-techniques","06.forms-and-user-input/09.advanced-form-techniques",{"title":250,"path":251,"stem":252},"Security Considerations for Forms","/forms-and-user-input/security-considerations-for-forms","06.forms-and-user-input/10.security-considerations-for-forms",{"title":254,"path":255,"stem":256,"children":257},"Models and Databases","/models-and-databases","07.models-and-databases/01.index",[258,259,263,267,271,275,279,283,287,291,295,299,303,307,311,315,319,323,327],{"title":254,"path":255,"stem":256},{"title":260,"path":261,"stem":262},"Understanding Django Models","/models-and-databases/understanding-django-models","07.models-and-databases/02.understanding-django-models",{"title":264,"path":265,"stem":266},"Defining Fields","/models-and-databases/defining-fields","07.models-and-databases/03.defining-fields",{"title":268,"path":269,"stem":270},"Relationships and Foreign Keys","/models-and-databases/relationships-and-foreign-keys","07.models-and-databases/04.relationships-and-foreign-keys",{"title":272,"path":273,"stem":274},"Examples of Relationship Patterns","/models-and-databases/examples-of-relationship-patterns","07.models-and-databases/05.examples-of-relationship-patterns",{"title":276,"path":277,"stem":278},"Making Queries","/models-and-databases/making-queries","07.models-and-databases/06.making-queries",{"title":280,"path":281,"stem":282},"Filtering, Ordering, and Slicing","/models-and-databases/filtering-ordering-slicing","07.models-and-databases/07.filtering-ordering-slicing",{"title":284,"path":285,"stem":286},"Managers and QuerySets","/models-and-databases/managers-and-querysets","07.models-and-databases/08.managers-and-querysets",{"title":288,"path":289,"stem":290},"Aggregation","/models-and-databases/aggregation","07.models-and-databases/09.aggregation",{"title":292,"path":293,"stem":294},"Search","/models-and-databases/search","07.models-and-databases/10.search",{"title":296,"path":297,"stem":298},"Raw SQL Queries","/models-and-databases/raw-sql-queries","07.models-and-databases/11.raw-sql-queries",{"title":300,"path":301,"stem":302},"Transactions","/models-and-databases/transactions","07.models-and-databases/12.transactions",{"title":304,"path":305,"stem":306},"Multiple Databases","/models-and-databases/multiple-databases","07.models-and-databases/13.multiple-databases",{"title":308,"path":309,"stem":310},"Tablespaces","/models-and-databases/tablespaces","07.models-and-databases/14.tablespaces",{"title":312,"path":313,"stem":314},"Composite Primary Keys","/models-and-databases/composite-primary-keys","07.models-and-databases/15.composite-primary-keys",{"title":316,"path":317,"stem":318},"Database Instrumentation","/models-and-databases/database-instrumentation","07.models-and-databases/16.database-instrumentation",{"title":320,"path":321,"stem":322},"Database Optimization","/models-and-databases/database-optimization","07.models-and-databases/17.database-optimization",{"title":324,"path":325,"stem":326},"Fixtures","/models-and-databases/fixtures","07.models-and-databases/18.fixtures",{"title":328,"path":329,"stem":330},"Signals","/models-and-databases/signals","07.models-and-databases/19.signals",{"title":332,"path":333,"stem":334,"children":335},"Migrations","/migrations","08.migrations/01.index",[336,337,341,345,349,353,357,361,365,369,373,377,381,385],{"title":332,"path":333,"stem":334},{"title":338,"path":339,"stem":340},"How Migrations Work","/migrations/how-migrations-work","08.migrations/02.how-migrations-work",{"title":342,"path":343,"stem":344},"Management Commands","/migrations/management-commands","08.migrations/03.management-commands",{"title":346,"path":347,"stem":348},"Dependencies and Workflow","/migrations/dependencies-and-workflow","08.migrations/04.dependencies-and-workflow",{"title":350,"path":351,"stem":352},"Transaction Handling","/migrations/transaction-handling","08.migrations/05.transaction-handling",{"title":354,"path":355,"stem":356},"Adding Migrations to Apps","/migrations/adding-migrations-to-apps","08.migrations/06.adding-migrations-to-apps",{"title":358,"path":359,"stem":360},"Reversing Migrations","/migrations/reversing-migrations","08.migrations/07.reversing-migrations",{"title":362,"path":363,"stem":364},"Historical Models","/migrations/historical-models","08.migrations/08.historical-models",{"title":366,"path":367,"stem":368},"Considerations When Removing Fields","/migrations/considerations-when-removing-fields","08.migrations/09.considerations-when-removing-fields",{"title":370,"path":371,"stem":372},"Data Migrations","/migrations/data-migrations","08.migrations/10.data-migrations",{"title":374,"path":375,"stem":376},"Squashing Migrations","/migrations/squashing-migrations","08.migrations/11.squashing-migrations",{"title":378,"path":379,"stem":380},"Serializing Values","/migrations/serializing-values","08.migrations/12.serializing-values",{"title":382,"path":383,"stem":384},"Supporting Multiple Django Versions","/migrations/supporting-multiple-django-versions","08.migrations/13.supporting-multiple-django-versions",{"title":386,"path":387,"stem":388},"Django Serialization Framework","/migrations/django-serialization-framework","08.migrations/14.django-serialization-framework",{"title":390,"path":391,"stem":392,"children":393},"Authentication and Authorization","/authentication-and-authorization","09.authentication-and-authorization/01.index",[394,395,399,403,407,411,415,419,423,427,431,435],{"title":390,"path":391,"stem":392},{"title":396,"path":397,"stem":398},"Overview of Django's Authentication System","/authentication-and-authorization/overview-of-django-authentication-system","09.authentication-and-authorization/02.overview-of-django-authentication-system",{"title":400,"path":401,"stem":402},"Users and Groups","/authentication-and-authorization/users-and-groups","09.authentication-and-authorization/03.users-and-groups",{"title":404,"path":405,"stem":406},"Permissions","/authentication-and-authorization/permissions","09.authentication-and-authorization/04.permissions",{"title":408,"path":409,"stem":410},"Password Management","/authentication-and-authorization/password-management","09.authentication-and-authorization/05.password-management",{"title":412,"path":413,"stem":414},"Authentication Views","/authentication-and-authorization/authentication-views","09.authentication-and-authorization/06.authentication-views",{"title":416,"path":417,"stem":418},"Login and Logout","/authentication-and-authorization/login-and-logout","09.authentication-and-authorization/07.login-and-logout",{"title":420,"path":421,"stem":422},"Custom User Models","/authentication-and-authorization/custom-user-models","09.authentication-and-authorization/08.custom-user-models",{"title":424,"path":425,"stem":426},"Middleware for Authentication","/authentication-and-authorization/middleware-for-authentication","09.authentication-and-authorization/09.middleware-for-authentication",{"title":428,"path":429,"stem":430},"Authorization in Views and Templates","/authentication-and-authorization/authorization-in-views-and-templates","09.authentication-and-authorization/10.authorization-in-views-and-templates",{"title":432,"path":433,"stem":434},"Integrating Social Authentication","/authentication-and-authorization/integrating-social-authentication","09.authentication-and-authorization/11.integrating-social-authentication",{"title":436,"path":437,"stem":438},"Security Best Practices","/authentication-and-authorization/security-best-practices","09.authentication-and-authorization/12.security-best-practices",{"title":440,"path":441,"stem":442,"children":443},"Sessions, Cookies, and State","/sessions-cookies-state","10.sessions-cookies-state/01.index",[444,446,450,454,458],{"title":445,"path":441,"stem":442},"Sessions, Cookies, and State Management",{"title":447,"path":448,"stem":449},"Introduction to Sessions","/sessions-cookies-state/introduction-to-sessions","10.sessions-cookies-state/02.introduction-to-sessions",{"title":451,"path":452,"stem":453},"Working with Cookies","/sessions-cookies-state/working-with-cookies","10.sessions-cookies-state/03.working-with-cookies",{"title":455,"path":456,"stem":457},"Server-Side Session Storage Options","/sessions-cookies-state/server-side-session-storage-options","10.sessions-cookies-state/04.server-side-session-storage-options",{"title":459,"path":460,"stem":461},"Session Security","/sessions-cookies-state/session-security","10.sessions-cookies-state/05.session-security",{"title":463,"path":464,"stem":465,"children":466},"Working with Files","/working-with-files","11.working-with-files/01.index",[467,468,472,476,480,484],{"title":463,"path":464,"stem":465},{"title":469,"path":470,"stem":471},"Files in Models","/working-with-files/files-in-models","11.working-with-files/02.files-in-models",{"title":473,"path":474,"stem":475},"The File Object","/working-with-files/the-file-object","11.working-with-files/03.the-file-object",{"title":477,"path":478,"stem":479},"Storage Backends","/working-with-files/storage-backends","11.working-with-files/04.storage-backends",{"title":481,"path":482,"stem":483},"Using Cloud Storage Providers","/working-with-files/using-cloud-storage-providers","11.working-with-files/05.using-cloud-storage-providers",{"title":485,"path":486,"stem":487},"Managing Media in Production","/working-with-files/managing-media-in-production","11.working-with-files/06.managing-media-in-production",{"title":489,"path":490,"stem":491,"children":492},"Admin Site","/admin-site","12.admin-site/01.index",[493,494,498,502,506,510],{"title":489,"path":490,"stem":491},{"title":495,"path":496,"stem":497},"Enabling the Admin","/admin-site/enabling-the-admin","12.admin-site/02.enabling-the-admin",{"title":499,"path":500,"stem":501},"Registering Models","/admin-site/registering-models","12.admin-site/03.registering-models",{"title":503,"path":504,"stem":505},"Customizing Admin Display","/admin-site/customizing-admin-display","12.admin-site/04.customizing-admin-display",{"title":507,"path":508,"stem":509},"Admin Actions","/admin-site/admin-actions","12.admin-site/05.admin-actions",{"title":511,"path":512,"stem":513},"Admin Security Best Practices","/admin-site/admin-security-best-practices","12.admin-site/06.admin-security-best-practices",{"title":515,"path":516,"stem":517,"children":518},"Middleware","/middleware","13.middleware/01.index",[519,520,524,528,532,536],{"title":515,"path":516,"stem":517},{"title":521,"path":522,"stem":523},"Middleware Overview","/middleware/middleware-overview","13.middleware/02.middleware-overview",{"title":525,"path":526,"stem":527},"Built-in Middleware","/middleware/built-in-middleware","13.middleware/03.built-in-middleware",{"title":529,"path":530,"stem":531},"Creating Custom Middleware","/middleware/creating-custom-middleware","13.middleware/04.creating-custom-middleware",{"title":533,"path":534,"stem":535},"Middleware Ordering","/middleware/middleware-ordering","13.middleware/05.middleware-ordering",{"title":537,"path":538,"stem":539},"Performance and Debugging","/middleware/performance-and-debugging","13.middleware/06.performance-and-debugging",{"title":541,"path":542,"stem":543,"children":544},"Security","/security","14.security/01.index",[545,546,550,554,558,562,566,570,574],{"title":541,"path":542,"stem":543},{"title":547,"path":548,"stem":549},"Django Security Philosophy","/security/django-security-philosophy","14.security/02.django-security-philosophy",{"title":551,"path":552,"stem":553},"Cross Site Request Forgery","/security/cross-site-request-forgery","14.security/03.cross-site-request-forgery",{"title":555,"path":556,"stem":557},"Cross Site Scripting","/security/cross-site-scripting","14.security/04.cross-site-scripting",{"title":559,"path":560,"stem":561},"SQL Injection Protection","/security/sql-injection-protection","14.security/05.sql-injection-protection",{"title":563,"path":564,"stem":565},"Clickjacking Protection","/security/clickjacking-protection","14.security/06.clickjacking-protection",{"title":567,"path":568,"stem":569},"HTTPS Setup and HSTS","/security/https-setup-and-hsts","14.security/07.https-setup-and-hsts",{"title":571,"path":572,"stem":573},"Password Storage and Cryptography","/security/password-storage-and-cryptography","14.security/08.password-storage-and-cryptography",{"title":575,"path":576,"stem":577},"Secure Deployment Checklist","/security/secure-deployment-checklist","14.security/09.secure-deployment-checklist",{"title":579,"path":580,"stem":581,"children":582},"Testing","/testing","15.testing/01.index",[583,584,588,592,596,600,604,608,612,616,620],{"title":579,"path":580,"stem":581},{"title":585,"path":586,"stem":587},"Introduction to Django Testing","/testing/introduction-to-django-testing","15.testing/02.introduction-to-django-testing",{"title":589,"path":590,"stem":591},"Writing and Running Tests","/testing/writing-and-running-tests","15.testing/03.writing-and-running-tests",{"title":593,"path":594,"stem":595},"Test Tools","/testing/test-tools","15.testing/04.test-tools",{"title":597,"path":598,"stem":599},"Testing Models","/testing/testing-models","15.testing/05.testing-models",{"title":601,"path":602,"stem":603},"Testing Views","/testing/testing-views","15.testing/06.testing-views",{"title":605,"path":606,"stem":607},"Testing Forms","/testing/testing-forms","15.testing/07.testing-forms",{"title":609,"path":610,"stem":611},"Testing Templates","/testing/testing-templates","15.testing/08.testing-templates",{"title":613,"path":614,"stem":615},"Testing Authentication","/testing/testing-authentication","15.testing/09.testing-authentication",{"title":617,"path":618,"stem":619},"Advanced Testing Topics","/testing/advanced-testing-topics","15.testing/10.advanced-testing-topics",{"title":621,"path":622,"stem":623},"Performance Testing","/testing/performance-testing","15.testing/11.performance-testing",{"title":625,"path":626,"stem":627,"children":628},"Static Assets and Frontend Integration","/static-assets-and-frontend-integration","16.static-assets-and-frontend-integration/01.index",[629,630,634,638,642,646],{"title":625,"path":626,"stem":627},{"title":631,"path":632,"stem":633},"Working with Static Files","/static-assets-and-frontend-integration/working-with-static-files","16.static-assets-and-frontend-integration/02.working-with-static-files",{"title":635,"path":636,"stem":637},"Integrating CSS and JavaScript","/static-assets-and-frontend-integration/integrating-css-and-javascript","16.static-assets-and-frontend-integration/03.integrating-css-and-javascript",{"title":639,"path":640,"stem":641},"Using Build Tools like Vite or Webpack","/static-assets-and-frontend-integration/using-build-tools-like-vite-or-webpack","16.static-assets-and-frontend-integration/04.using-build-tools-like-vite-or-webpack",{"title":643,"path":644,"stem":645},"Using React or Vue with Django","/static-assets-and-frontend-integration/using-react-or-vue-with-django","16.static-assets-and-frontend-integration/05.using-react-or-vue-with-django",{"title":647,"path":648,"stem":649},"Managing CORS","/static-assets-and-frontend-integration/managing-cors","16.static-assets-and-frontend-integration/06.managing-cors",{"title":651,"path":652,"stem":653,"children":654},"Internationalization and Localization","/internationalization-and-localization","17.internationalization-and-localization/01.index",[655,656,660,664,668],{"title":651,"path":652,"stem":653},{"title":657,"path":658,"stem":659},"Enabling Translation","/internationalization-and-localization/enabling-translation","17.internationalization-and-localization/02.enabling-translation",{"title":661,"path":662,"stem":663},"Translating Text in Code and Templates","/internationalization-and-localization/translating-text-in-code-and-templates","17.internationalization-and-localization/03.translating-text-in-code-and-templates",{"title":665,"path":666,"stem":667},"Timezone Support","/internationalization-and-localization/timezone-support","17.internationalization-and-localization/04.timezone-support",{"title":669,"path":670,"stem":671},"Locale Middleware","/internationalization-and-localization/locale-middleware","17.internationalization-and-localization/05.locale-middleware",{"title":673,"path":674,"stem":675,"children":676},"Caching","/caching","18.caching/01.index",[677,678,682,686,690,694,698],{"title":673,"path":674,"stem":675},{"title":679,"path":680,"stem":681},"Introduction to Caching","/caching/introduction-to-caching","18.caching/02.introduction-to-caching",{"title":683,"path":684,"stem":685},"Cache Backends","/caching/cache-backends","18.caching/03.cache-backends",{"title":687,"path":688,"stem":689},"Per View Caching","/caching/per-view-caching","18.caching/04.per-view-caching",{"title":691,"path":692,"stem":693},"Low Level Cache API","/caching/low-level-cache-api","18.caching/05.low-level-cache-api",{"title":695,"path":696,"stem":697},"Template Fragment Caching","/caching/template-fragment-caching","18.caching/06.template-fragment-caching",{"title":699,"path":700,"stem":701},"Deployment Level Caching Patterns","/caching/deployment-level-caching-patterns","18.caching/07.deployment-level-caching-patterns",{"title":703,"path":704,"stem":705,"children":706},"Asynchronous Django","/asynchronous-django","19.asynchronous-django/01.index",[707,708,712,716,720,724,728,732],{"title":703,"path":704,"stem":705},{"title":709,"path":710,"stem":711},"Introduction to ASGI","/asynchronous-django/introduction-to-asgi","19.asynchronous-django/02.introduction-to-asgi",{"title":713,"path":714,"stem":715},"Async Views","/asynchronous-django/async-views","19.asynchronous-django/03.async-views",{"title":717,"path":718,"stem":719},"Async ORM Status","/asynchronous-django/async-orm-status","19.asynchronous-django/04.async-orm-status",{"title":721,"path":722,"stem":723},"WebSockets with Channels","/asynchronous-django/websockets-with-channels","19.asynchronous-django/05.websockets-with-channels",{"title":725,"path":726,"stem":727},"Background Tasks with Celery or RQ","/asynchronous-django/background-tasks-with-celery-or-rq","19.asynchronous-django/06.background-tasks-with-celery-or-rq",{"title":729,"path":730,"stem":731},"Asynchronous Support","/asynchronous-django/asynchronous-support","19.asynchronous-django/07.asynchronous-support",{"title":733,"path":734,"stem":735},"Django's Tasks Framework","/asynchronous-django/django-tasks-framework","19.asynchronous-django/08.django-tasks-framework",{"title":737,"path":738,"stem":739,"children":740},"Deployment","/deployment","20.deployment/01.index",[741,742,746,750,754,758,762,766,770],{"title":737,"path":738,"stem":739},{"title":743,"path":744,"stem":745},"Preparing for Production","/deployment/preparing-for-production","20.deployment/02.preparing-for-production",{"title":747,"path":748,"stem":749},"Using WSGI and ASGI Servers","/deployment/using-wsgi-and-asgi-servers","20.deployment/03.using-wsgi-and-asgi-servers",{"title":751,"path":752,"stem":753},"Deploying on Linux Servers","/deployment/deploying-on-linux-servers","20.deployment/04.deploying-on-linux-servers",{"title":755,"path":756,"stem":757},"Using Docker","/deployment/using-docker","20.deployment/05.using-docker",{"title":759,"path":760,"stem":761},"Cloud Deployment Guides","/deployment/cloud-deployment-guides","20.deployment/06.cloud-deployment-guides",{"title":763,"path":764,"stem":765},"Scaling and Load Balancing","/deployment/scaling-and-load-balancing","20.deployment/07.scaling-and-load-balancing",{"title":767,"path":768,"stem":769},"Monitoring and Logging","/deployment/monitoring-and-logging","20.deployment/08.monitoring-and-logging",{"title":771,"path":772,"stem":773},"Backup Strategies","/deployment/backup-strategies","20.deployment/09.backup-strategies",{"title":775,"path":776,"stem":777,"children":778},"Performance and Optimization","/performance-and-optimization","21.performance-and-optimization/01.index",[779,780,784,788,792,796],{"title":775,"path":776,"stem":777},{"title":781,"path":782,"stem":783},"Query Optimization","/performance-and-optimization/query-optimization","21.performance-and-optimization/02.query-optimization",{"title":785,"path":786,"stem":787},"Template Rendering Optimization","/performance-and-optimization/template-rendering-optimization","21.performance-and-optimization/03.template-rendering-optimization",{"title":789,"path":790,"stem":791},"Using Select Related and Prefetch Related","/performance-and-optimization/using-select-related-and-prefetch-related","21.performance-and-optimization/04.using-select-related-and-prefetch-related",{"title":793,"path":794,"stem":795},"Caching Strategies","/performance-and-optimization/caching-strategies","21.performance-and-optimization/05.caching-strategies",{"title":797,"path":798,"stem":799},"Profiling Django Apps","/performance-and-optimization/profiling-django-apps","21.performance-and-optimization/06.profiling-django-apps",{"title":801,"path":802,"stem":803,"children":804},"Advanced and Expert Topics","/advanced-and-expert-topics","22.advanced-and-expert-topics/01.index",[805,806,810,814,818,822,826,830,834,838,842,846],{"title":801,"path":802,"stem":803},{"title":807,"path":808,"stem":809},"System Architecture Patterns","/advanced-and-expert-topics/system-architecture-patterns","22.advanced-and-expert-topics/02.system-architecture-patterns",{"title":811,"path":812,"stem":813},"Domain Driven Design with Django","/advanced-and-expert-topics/domain-driven-design-with-django","22.advanced-and-expert-topics/03.domain-driven-design-with-django",{"title":815,"path":816,"stem":817},"Building Large Scale Django Projects","/advanced-and-expert-topics/building-large-scale-django-projects","22.advanced-and-expert-topics/04.building-large-scale-django-projects",{"title":819,"path":820,"stem":821},"Plugin Architectures for Django Apps","/advanced-and-expert-topics/plugin-architectures-for-django-apps","22.advanced-and-expert-topics/05.plugin-architectures-for-django-apps",{"title":823,"path":824,"stem":825},"Extending Django's Core","/advanced-and-expert-topics/extending-djangos-core","22.advanced-and-expert-topics/06.extending-djangos-core",{"title":827,"path":828,"stem":829},"Custom ORM Expressions","/advanced-and-expert-topics/custom-orm-expressions","22.advanced-and-expert-topics/07.custom-orm-expressions",{"title":831,"path":832,"stem":833},"Custom Management Commands","/advanced-and-expert-topics/custom-management-commands","22.advanced-and-expert-topics/08.custom-management-commands",{"title":835,"path":836,"stem":837},"Working with Signals","/advanced-and-expert-topics/working-with-signals","22.advanced-and-expert-topics/09.working-with-signals",{"title":839,"path":840,"stem":841},"Building Reusable Django Packages","/advanced-and-expert-topics/building-reusable-django-packages","22.advanced-and-expert-topics/10.building-reusable-django-packages",{"title":843,"path":844,"stem":845},"Integrating Microservices","/advanced-and-expert-topics/integrating-microservices","22.advanced-and-expert-topics/11.integrating-microservices",{"title":847,"path":848,"stem":849},"Advanced Security Hardening","/advanced-and-expert-topics/advanced-security-hardening","22.advanced-and-expert-topics/12.advanced-security-hardening",{"title":851,"path":852,"stem":853,"children":854},"Logging in Django","/logging-in-django","23.logging-in-django/01.index",[855],{"title":851,"path":852,"stem":853},{"title":857,"path":858,"stem":859,"children":860},"FAQ and Troubleshooting","/faq-and-troubleshooting","24.faq-and-troubleshooting/01.index",[861],{"title":857,"path":858,"stem":859},{"title":863,"path":864,"stem":865,"children":866},"External Packages and Ecosystem","/external-packages-and-ecosystem","25.external-packages-and-ecosystem/01.index",[867],{"title":863,"path":864,"stem":865},{"title":869,"path":870,"stem":871,"children":872},"Django Internals and Contributing","/django-internals-and-contributing","26.django-internals-and-contributing/01.index",[873],{"title":869,"path":870,"stem":871},{"title":875,"path":876,"stem":877,"children":878},"Microservices with Django","/microservices-with-django","27.microservices-with-django/01.index",[879,880,884,888,892,896,900,904,908,912,916,920,924],{"title":875,"path":876,"stem":877},{"title":881,"path":882,"stem":883},"What Is a Microservice?","/microservices-with-django/what-is-a-microservice","27.microservices-with-django/02.what-is-a-microservice",{"title":885,"path":886,"stem":887},"Introducing the Django Microservices Architecture","/microservices-with-django/django-microservices-architecture","27.microservices-with-django/03.django-microservices-architecture",{"title":889,"path":890,"stem":891},"Setting Up the Development and Runtime Environment","/microservices-with-django/development-environment","27.microservices-with-django/04.development-environment",{"title":893,"path":894,"stem":895},"Cloud-native Data Processing with MongoDB","/microservices-with-django/cloud-native-data-processing","27.microservices-with-django/05.cloud-native-data-processing",{"title":897,"path":898,"stem":899},"Creating RESTful APIs for Microservices","/microservices-with-django/restful-apis","27.microservices-with-django/06.restful-apis",{"title":901,"path":902,"stem":903},"Orchestrating Microservices with Celery and RabbitMQ","/microservices-with-django/orchestrating-celery-rabbitmq","27.microservices-with-django/07.orchestrating-celery-rabbitmq",{"title":905,"path":906,"stem":907},"Testing Microservices","/microservices-with-django/testing-microservices","27.microservices-with-django/08.testing-microservices",{"title":909,"path":910,"stem":911},"Deploying Microservices","/microservices-with-django/deploying-microservices","27.microservices-with-django/09.deploying-microservices",{"title":913,"path":914,"stem":915},"Securing Microservices","/microservices-with-django/securing-microservices","27.microservices-with-django/10.securing-microservices",{"title":917,"path":918,"stem":919},"Improving Microservices Performance with Caching","/microservices-with-django/performance-caching","27.microservices-with-django/11.performance-caching",{"title":921,"path":922,"stem":923},"Best Practices","/microservices-with-django/best-practices","27.microservices-with-django/12.best-practices",{"title":925,"path":926,"stem":927},"Transforming a Monolithic Web App into a Microservice version","/microservices-with-django/monolith-to-microservices","27.microservices-with-django/13.monolith-to-microservices",{"title":929,"path":930,"stem":931,"children":932},"Releases","/releases","releases",[933,936,940,944,948,952,956,960,964,968,972,976,980,984,988,992,996,1000,1004,1008,1012],{"title":934,"path":930,"stem":935},"Django Releases","releases/index",{"title":937,"path":938,"stem":939},"Django 5.1.10 release notes","/releases/5.1.10","releases/5.1.10",{"title":941,"path":942,"stem":943},"Django 5.1.11 release notes","/releases/5.1.11","releases/5.1.11",{"title":945,"path":946,"stem":947},"Django 5.1.12 release notes","/releases/5.1.12","releases/5.1.12",{"title":949,"path":950,"stem":951},"Django 5.1.13 release notes","/releases/5.1.13","releases/5.1.13",{"title":953,"path":954,"stem":955},"Django 5.1.14 release notes","/releases/5.1.14","releases/5.1.14",{"title":957,"path":958,"stem":959},"Django 5.1.15 release notes","/releases/5.1.15","releases/5.1.15",{"title":961,"path":962,"stem":963},"Django 5.2 release notes","/releases/5.2","releases/5.2",{"title":965,"path":966,"stem":967},"Django 5.2.1 release notes","/releases/5.2.1","releases/5.2.1",{"title":969,"path":970,"stem":971},"Django 5.2.10 release notes","/releases/5.2.10","releases/5.2.10",{"title":973,"path":974,"stem":975},"Django 5.2.2 release notes","/releases/5.2.2","releases/5.2.2",{"title":977,"path":978,"stem":979},"Django 5.2.3 release notes","/releases/5.2.3","releases/5.2.3",{"title":981,"path":982,"stem":983},"Django 5.2.4 release notes","/releases/5.2.4","releases/5.2.4",{"title":985,"path":986,"stem":987},"Django 5.2.5 release notes","/releases/5.2.5","releases/5.2.5",{"title":989,"path":990,"stem":991},"Django 5.2.6 release notes","/releases/5.2.6","releases/5.2.6",{"title":993,"path":994,"stem":995},"Django 5.2.7 release notes","/releases/5.2.7","releases/5.2.7",{"title":997,"path":998,"stem":999},"Django 5.2.8 release notes","/releases/5.2.8","releases/5.2.8",{"title":1001,"path":1002,"stem":1003},"Django 5.2.9 release notes","/releases/5.2.9","releases/5.2.9",{"title":1005,"path":1006,"stem":1007},"Django 6.0 release notes","/releases/6.0","releases/6.0",{"title":1009,"path":1010,"stem":1011},"Django 6.0.1 release notes","/releases/6.0.1","releases/6.0.1",{"title":1013,"path":1014,"stem":1015},"Django 6.1 release notes - UNDER DEVELOPMENT","/releases/6.1","releases/6.1",{"id":1017,"title":819,"body":1018,"description":1028,"extension":8079,"links":8080,"meta":8081,"navigation":1190,"path":820,"seo":8082,"stem":821,"__hash__":8083},"docs/22.advanced-and-expert-topics/05.plugin-architectures-for-django-apps.md",{"type":1019,"value":1020,"toc":8067},"minimark",[1021,1025,1029,1034,1037,1042,1048,1061,1066,1077,1082,1093,1097,4433,4437,4441,6593,6597,6601,8057,8060,8063],[1022,1023,819],"h1",{"id":1024},"plugin-architectures-for-django-apps",[1026,1027,1028],"p",{},"Plugin architectures enable Django applications to be extended dynamically without modifying core code. This approach creates flexible, maintainable systems where functionality can be added, removed, or modified through plugins, making applications highly customizable and extensible.",[1030,1031,1033],"h2",{"id":1032},"understanding-plugin-architecture","Understanding Plugin Architecture",[1026,1035,1036],{},"Plugin architecture separates core functionality from optional features, allowing third-party developers to extend applications without touching the main codebase. This pattern is essential for building platforms, frameworks, and applications that need to support diverse use cases.",[1038,1039,1041],"h3",{"id":1040},"core-concepts","Core Concepts",[1026,1043,1044],{},[1045,1046,1047],"strong",{},"Plugin Interface",[1049,1050,1051,1055,1058],"ul",{},[1052,1053,1054],"li",{},"Defines contracts that plugins must implement",[1052,1056,1057],{},"Provides stable APIs for plugin development",[1052,1059,1060],{},"Ensures compatibility between core and plugins",[1026,1062,1063],{},[1045,1064,1065],{},"Plugin Registry",[1049,1067,1068,1071,1074],{},[1052,1069,1070],{},"Manages plugin discovery and loading",[1052,1072,1073],{},"Handles plugin lifecycle (load, enable, disable)",[1052,1075,1076],{},"Provides plugin metadata and configuration",[1026,1078,1079],{},[1045,1080,1081],{},"Hook System",[1049,1083,1084,1087,1090],{},[1052,1085,1086],{},"Defines extension points in core application",[1052,1088,1089],{},"Allows plugins to modify behavior at specific points",[1052,1091,1092],{},"Enables event-driven plugin interactions",[1038,1094,1096],{"id":1095},"basic-plugin-system-implementation","Basic Plugin System Implementation",[1098,1099,1104],"pre",{"className":1100,"code":1101,"language":1102,"meta":1103,"style":1103},"language-python shiki shiki-themes material-theme-lighter vitesse-light vitesse-dark","# Core plugin infrastructure\nfrom abc import ABC, abstractmethod\nfrom typing import Dict, List, Any, Optional\nimport importlib\nimport inspect\n\nclass PluginInterface(ABC):\n    \"\"\"Base interface for all plugins\"\"\"\n    \n    @property\n    @abstractmethod\n    def name(self) -> str:\n        \"\"\"Plugin name\"\"\"\n        pass\n    \n    @property\n    @abstractmethod\n    def version(self) -> str:\n        \"\"\"Plugin version\"\"\"\n        pass\n    \n    @property\n    def description(self) -> str:\n        \"\"\"Plugin description\"\"\"\n        return \"\"\n    \n    @property\n    def dependencies(self) -> List[str]:\n        \"\"\"List of required plugin dependencies\"\"\"\n        return []\n    \n    @abstractmethod\n    def initialize(self, config: Dict[str, Any]) -> None:\n        \"\"\"Initialize plugin with configuration\"\"\"\n        pass\n    \n    @abstractmethod\n    def cleanup(self) -> None:\n        \"\"\"Cleanup plugin resources\"\"\"\n        pass\n\nclass PluginRegistry:\n    \"\"\"Registry for managing plugins\"\"\"\n    \n    def __init__(self):\n        self.plugins: Dict[str, PluginInterface] = {}\n        self.enabled_plugins: Dict[str, PluginInterface] = {}\n        self.hooks: Dict[str, List[callable]] = {}\n    \n    def register_plugin(self, plugin: PluginInterface) -> None:\n        \"\"\"Register a plugin\"\"\"\n        if plugin.name in self.plugins:\n            raise ValueError(f\"Plugin {plugin.name} already registered\")\n        \n        # Check dependencies\n        for dep in plugin.dependencies:\n            if dep not in self.plugins:\n                raise ValueError(f\"Plugin {plugin.name} requires {dep}\")\n        \n        self.plugins[plugin.name] = plugin\n    \n    def enable_plugin(self, plugin_name: str, config: Dict[str, Any] = None) -> None:\n        \"\"\"Enable a plugin\"\"\"\n        if plugin_name not in self.plugins:\n            raise ValueError(f\"Plugin {plugin_name} not found\")\n        \n        if plugin_name in self.enabled_plugins:\n            return  # Already enabled\n        \n        plugin = self.plugins[plugin_name]\n        \n        # Enable dependencies first\n        for dep in plugin.dependencies:\n            self.enable_plugin(dep)\n        \n        # Initialize plugin\n        plugin.initialize(config or {})\n        self.enabled_plugins[plugin_name] = plugin\n        \n        # Register plugin hooks\n        self._register_plugin_hooks(plugin)\n    \n    def disable_plugin(self, plugin_name: str) -> None:\n        \"\"\"Disable a plugin\"\"\"\n        if plugin_name not in self.enabled_plugins:\n            return  # Already disabled\n        \n        plugin = self.enabled_plugins[plugin_name]\n        \n        # Check if other plugins depend on this one\n        for other_plugin in self.enabled_plugins.values():\n            if plugin_name in other_plugin.dependencies:\n                raise ValueError(f\"Cannot disable {plugin_name}: required by {other_plugin.name}\")\n        \n        # Cleanup plugin\n        plugin.cleanup()\n        \n        # Unregister hooks\n        self._unregister_plugin_hooks(plugin)\n        \n        del self.enabled_plugins[plugin_name]\n    \n    def get_enabled_plugins(self) -> List[PluginInterface]:\n        \"\"\"Get list of enabled plugins\"\"\"\n        return list(self.enabled_plugins.values())\n    \n    def register_hook(self, hook_name: str, callback: callable) -> None:\n        \"\"\"Register a hook callback\"\"\"\n        if hook_name not in self.hooks:\n            self.hooks[hook_name] = []\n        self.hooks[hook_name].append(callback)\n    \n    def call_hook(self, hook_name: str, *args, **kwargs) -> List[Any]:\n        \"\"\"Call all callbacks for a hook\"\"\"\n        results = []\n        if hook_name in self.hooks:\n            for callback in self.hooks[hook_name]:\n                try:\n                    result = callback(*args, **kwargs)\n                    results.append(result)\n                except Exception as e:\n                    # Log error but continue with other hooks\n                    print(f\"Hook {hook_name} callback failed: {e}\")\n        return results\n    \n    def _register_plugin_hooks(self, plugin: PluginInterface) -> None:\n        \"\"\"Register hooks defined by plugin\"\"\"\n        for method_name in dir(plugin):\n            method = getattr(plugin, method_name)\n            if hasattr(method, '_hook_name'):\n                self.register_hook(method._hook_name, method)\n    \n    def _unregister_plugin_hooks(self, plugin: PluginInterface) -> None:\n        \"\"\"Unregister hooks defined by plugin\"\"\"\n        for hook_name, callbacks in self.hooks.items():\n            self.hooks[hook_name] = [\n                cb for cb in callbacks \n                if not (hasattr(cb, '__self__') and cb.__self__ == plugin)\n            ]\n\n# Hook decorator\ndef hook(hook_name: str):\n    \"\"\"Decorator to mark methods as hook handlers\"\"\"\n    def decorator(func):\n        func._hook_name = hook_name\n        return func\n    return decorator\n\n# Global plugin registry\nplugin_registry = PluginRegistry()\n\n# Example plugin implementation\nclass EmailNotificationPlugin(PluginInterface):\n    \"\"\"Plugin for email notifications\"\"\"\n    \n    @property\n    def name(self) -> str:\n        return \"email_notifications\"\n    \n    @property\n    def version(self) -> str:\n        return \"1.0.0\"\n    \n    @property\n    def description(self) -> str:\n        return \"Sends email notifications for various events\"\n    \n    def initialize(self, config: Dict[str, Any]) -> None:\n        \"\"\"Initialize email configuration\"\"\"\n        self.smtp_host = config.get('smtp_host', 'localhost')\n        self.smtp_port = config.get('smtp_port', 587)\n        self.username = config.get('username')\n        self.password = config.get('password')\n        print(f\"Email plugin initialized with SMTP {self.smtp_host}:{self.smtp_port}\")\n    \n    def cleanup(self) -> None:\n        \"\"\"Cleanup email resources\"\"\"\n        print(\"Email plugin cleaned up\")\n    \n    @hook('user_registered')\n    def send_welcome_email(self, user):\n        \"\"\"Send welcome email when user registers\"\"\"\n        print(f\"Sending welcome email to {user.email}\")\n        # Email sending logic here\n    \n    @hook('order_confirmed')\n    def send_order_confirmation(self, order):\n        \"\"\"Send order confirmation email\"\"\"\n        print(f\"Sending order confirmation for order {order.id}\")\n        # Email sending logic here\n\nclass SlackNotificationPlugin(PluginInterface):\n    \"\"\"Plugin for Slack notifications\"\"\"\n    \n    @property\n    def name(self) -> str:\n        return \"slack_notifications\"\n    \n    @property\n    def version(self) -> str:\n        return \"1.0.0\"\n    \n    @property\n    def description(self) -> str:\n        return \"Sends notifications to Slack channels\"\n    \n    def initialize(self, config: Dict[str, Any]) -> None:\n        \"\"\"Initialize Slack configuration\"\"\"\n        self.webhook_url = config.get('webhook_url')\n        self.channel = config.get('channel', '#general')\n        print(f\"Slack plugin initialized for channel {self.channel}\")\n    \n    def cleanup(self) -> None:\n        \"\"\"Cleanup Slack resources\"\"\"\n        print(\"Slack plugin cleaned up\")\n    \n    @hook('order_confirmed')\n    def notify_order_confirmed(self, order):\n        \"\"\"Notify Slack when order is confirmed\"\"\"\n        print(f\"Notifying Slack about order {order.id}\")\n        # Slack notification logic here\n    \n    @hook('system_error')\n    def notify_system_error(self, error):\n        \"\"\"Notify Slack about system errors\"\"\"\n        print(f\"Notifying Slack about error: {error}\")\n        # Slack notification logic here\n","python","",[1105,1106,1107,1116,1141,1169,1177,1185,1192,1212,1226,1232,1242,1251,1278,1289,1295,1300,1307,1314,1334,1344,1349,1354,1361,1381,1391,1401,1406,1413,1440,1450,1458,1463,1470,1512,1522,1527,1532,1539,1559,1569,1574,1579,1589,1599,1604,1619,1653,1681,1715,1720,1749,1759,1785,1824,1830,1836,1857,1878,1917,1922,1946,1951,2002,2012,2032,2057,2062,2079,2088,2093,2115,2120,2126,2143,2160,2165,2171,2193,2212,2217,2223,2239,2244,2272,2282,2301,2309,2314,2333,2338,2344,2368,2386,2424,2429,2435,2448,2453,2459,2475,2480,2498,2503,2528,2538,2561,2566,2605,2615,2635,2655,2681,2686,2735,2745,2755,2772,2795,2803,2828,2845,2862,2868,2901,2909,2914,2942,2952,2971,2993,3019,3045,3050,3078,3088,3115,3135,3152,3201,3207,3212,3218,3237,3247,3262,3277,3285,3294,3299,3305,3317,3322,3328,3343,3353,3358,3365,3384,3398,3403,3410,3429,3441,3446,3453,3472,3484,3489,3524,3534,3572,3606,3634,3662,3701,3706,3725,3735,3751,3756,3775,3794,3804,3832,3838,3843,3861,3880,3890,3918,3923,3928,3942,3952,3957,3964,3983,3995,4000,4007,4026,4037,4042,4049,4068,4080,4085,4120,4130,4158,4195,4221,4226,4245,4255,4271,4276,4293,4311,4321,4347,4353,4358,4376,4395,4405,4428],"code",{"__ignoreMap":1103},[1108,1109,1112],"span",{"class":1110,"line":1111},"line",1,[1108,1113,1115],{"class":1114},"s9Tkl","# Core plugin infrastructure\n",[1108,1117,1119,1123,1127,1130,1134,1138],{"class":1110,"line":1118},2,[1108,1120,1122],{"class":1121},"siDh9","from",[1108,1124,1126],{"class":1125},"sftqT"," abc ",[1108,1128,1129],{"class":1121},"import",[1108,1131,1133],{"class":1132},"se3Ec"," ABC",[1108,1135,1137],{"class":1136},"soVBu",",",[1108,1139,1140],{"class":1125}," abstractmethod\n",[1108,1142,1144,1146,1149,1151,1154,1156,1159,1161,1164,1166],{"class":1110,"line":1143},3,[1108,1145,1122],{"class":1121},[1108,1147,1148],{"class":1125}," typing ",[1108,1150,1129],{"class":1121},[1108,1152,1153],{"class":1125}," Dict",[1108,1155,1137],{"class":1136},[1108,1157,1158],{"class":1125}," List",[1108,1160,1137],{"class":1136},[1108,1162,1163],{"class":1125}," Any",[1108,1165,1137],{"class":1136},[1108,1167,1168],{"class":1125}," Optional\n",[1108,1170,1172,1174],{"class":1110,"line":1171},4,[1108,1173,1129],{"class":1121},[1108,1175,1176],{"class":1125}," importlib\n",[1108,1178,1180,1182],{"class":1110,"line":1179},5,[1108,1181,1129],{"class":1121},[1108,1183,1184],{"class":1125}," inspect\n",[1108,1186,1188],{"class":1110,"line":1187},6,[1108,1189,1191],{"emptyLinePlaceholder":1190},true,"\n",[1108,1193,1195,1199,1203,1206,1209],{"class":1110,"line":1194},7,[1108,1196,1198],{"class":1197},"s5Kfy","class",[1108,1200,1202],{"class":1201},"sD-vU"," PluginInterface",[1108,1204,1205],{"class":1136},"(",[1108,1207,1208],{"class":1132},"ABC",[1108,1210,1211],{"class":1136},"):\n",[1108,1213,1215,1219,1223],{"class":1110,"line":1214},8,[1108,1216,1218],{"class":1217},"sm7ve","    \"\"\"",[1108,1220,1222],{"class":1221},"sVyVU","Base interface for all plugins",[1108,1224,1225],{"class":1217},"\"\"\"\n",[1108,1227,1229],{"class":1110,"line":1228},9,[1108,1230,1231],{"class":1125},"    \n",[1108,1233,1235,1238],{"class":1110,"line":1234},10,[1108,1236,1237],{"class":1136},"    @",[1108,1239,1241],{"class":1240},"sa2tF","property\n",[1108,1243,1245,1247],{"class":1110,"line":1244},11,[1108,1246,1237],{"class":1136},[1108,1248,1250],{"class":1249},"sljsM","abstractmethod\n",[1108,1252,1254,1257,1260,1262,1266,1269,1272,1275],{"class":1110,"line":1253},12,[1108,1255,1256],{"class":1197},"    def",[1108,1258,1259],{"class":1249}," name",[1108,1261,1205],{"class":1136},[1108,1263,1265],{"class":1264},"sRjD_","self",[1108,1267,1268],{"class":1136},")",[1108,1270,1271],{"class":1136}," ->",[1108,1273,1274],{"class":1240}," str",[1108,1276,1277],{"class":1136},":\n",[1108,1279,1281,1284,1287],{"class":1110,"line":1280},13,[1108,1282,1283],{"class":1217},"        \"\"\"",[1108,1285,1286],{"class":1221},"Plugin name",[1108,1288,1225],{"class":1217},[1108,1290,1292],{"class":1110,"line":1291},14,[1108,1293,1294],{"class":1121},"        pass\n",[1108,1296,1298],{"class":1110,"line":1297},15,[1108,1299,1231],{"class":1125},[1108,1301,1303,1305],{"class":1110,"line":1302},16,[1108,1304,1237],{"class":1136},[1108,1306,1241],{"class":1240},[1108,1308,1310,1312],{"class":1110,"line":1309},17,[1108,1311,1237],{"class":1136},[1108,1313,1250],{"class":1249},[1108,1315,1317,1319,1322,1324,1326,1328,1330,1332],{"class":1110,"line":1316},18,[1108,1318,1256],{"class":1197},[1108,1320,1321],{"class":1249}," version",[1108,1323,1205],{"class":1136},[1108,1325,1265],{"class":1264},[1108,1327,1268],{"class":1136},[1108,1329,1271],{"class":1136},[1108,1331,1274],{"class":1240},[1108,1333,1277],{"class":1136},[1108,1335,1337,1339,1342],{"class":1110,"line":1336},19,[1108,1338,1283],{"class":1217},[1108,1340,1341],{"class":1221},"Plugin version",[1108,1343,1225],{"class":1217},[1108,1345,1347],{"class":1110,"line":1346},20,[1108,1348,1294],{"class":1121},[1108,1350,1352],{"class":1110,"line":1351},21,[1108,1353,1231],{"class":1125},[1108,1355,1357,1359],{"class":1110,"line":1356},22,[1108,1358,1237],{"class":1136},[1108,1360,1241],{"class":1240},[1108,1362,1364,1366,1369,1371,1373,1375,1377,1379],{"class":1110,"line":1363},23,[1108,1365,1256],{"class":1197},[1108,1367,1368],{"class":1249}," description",[1108,1370,1205],{"class":1136},[1108,1372,1265],{"class":1264},[1108,1374,1268],{"class":1136},[1108,1376,1271],{"class":1136},[1108,1378,1274],{"class":1240},[1108,1380,1277],{"class":1136},[1108,1382,1384,1386,1389],{"class":1110,"line":1383},24,[1108,1385,1283],{"class":1217},[1108,1387,1388],{"class":1221},"Plugin description",[1108,1390,1225],{"class":1217},[1108,1392,1394,1397],{"class":1110,"line":1393},25,[1108,1395,1396],{"class":1121},"        return",[1108,1398,1400],{"class":1399},"sbYkP"," \"\"\n",[1108,1402,1404],{"class":1110,"line":1403},26,[1108,1405,1231],{"class":1125},[1108,1407,1409,1411],{"class":1110,"line":1408},27,[1108,1410,1237],{"class":1136},[1108,1412,1241],{"class":1240},[1108,1414,1416,1418,1421,1423,1425,1427,1429,1431,1434,1437],{"class":1110,"line":1415},28,[1108,1417,1256],{"class":1197},[1108,1419,1420],{"class":1249}," dependencies",[1108,1422,1205],{"class":1136},[1108,1424,1265],{"class":1264},[1108,1426,1268],{"class":1136},[1108,1428,1271],{"class":1136},[1108,1430,1158],{"class":1125},[1108,1432,1433],{"class":1136},"[",[1108,1435,1436],{"class":1240},"str",[1108,1438,1439],{"class":1136},"]:\n",[1108,1441,1443,1445,1448],{"class":1110,"line":1442},29,[1108,1444,1283],{"class":1217},[1108,1446,1447],{"class":1221},"List of required plugin dependencies",[1108,1449,1225],{"class":1217},[1108,1451,1453,1455],{"class":1110,"line":1452},30,[1108,1454,1396],{"class":1121},[1108,1456,1457],{"class":1136}," []\n",[1108,1459,1461],{"class":1110,"line":1460},31,[1108,1462,1231],{"class":1125},[1108,1464,1466,1468],{"class":1110,"line":1465},32,[1108,1467,1237],{"class":1136},[1108,1469,1250],{"class":1249},[1108,1471,1473,1475,1478,1480,1482,1484,1488,1491,1493,1495,1497,1499,1501,1504,1506,1510],{"class":1110,"line":1472},33,[1108,1474,1256],{"class":1197},[1108,1476,1477],{"class":1249}," initialize",[1108,1479,1205],{"class":1136},[1108,1481,1265],{"class":1264},[1108,1483,1137],{"class":1136},[1108,1485,1487],{"class":1486},"sCyAa"," config",[1108,1489,1490],{"class":1136},":",[1108,1492,1153],{"class":1125},[1108,1494,1433],{"class":1136},[1108,1496,1436],{"class":1240},[1108,1498,1137],{"class":1136},[1108,1500,1163],{"class":1125},[1108,1502,1503],{"class":1136},"])",[1108,1505,1271],{"class":1136},[1108,1507,1509],{"class":1508},"s8XtY"," None",[1108,1511,1277],{"class":1136},[1108,1513,1515,1517,1520],{"class":1110,"line":1514},34,[1108,1516,1283],{"class":1217},[1108,1518,1519],{"class":1221},"Initialize plugin with configuration",[1108,1521,1225],{"class":1217},[1108,1523,1525],{"class":1110,"line":1524},35,[1108,1526,1294],{"class":1121},[1108,1528,1530],{"class":1110,"line":1529},36,[1108,1531,1231],{"class":1125},[1108,1533,1535,1537],{"class":1110,"line":1534},37,[1108,1536,1237],{"class":1136},[1108,1538,1250],{"class":1249},[1108,1540,1542,1544,1547,1549,1551,1553,1555,1557],{"class":1110,"line":1541},38,[1108,1543,1256],{"class":1197},[1108,1545,1546],{"class":1249}," cleanup",[1108,1548,1205],{"class":1136},[1108,1550,1265],{"class":1264},[1108,1552,1268],{"class":1136},[1108,1554,1271],{"class":1136},[1108,1556,1509],{"class":1508},[1108,1558,1277],{"class":1136},[1108,1560,1562,1564,1567],{"class":1110,"line":1561},39,[1108,1563,1283],{"class":1217},[1108,1565,1566],{"class":1221},"Cleanup plugin resources",[1108,1568,1225],{"class":1217},[1108,1570,1572],{"class":1110,"line":1571},40,[1108,1573,1294],{"class":1121},[1108,1575,1577],{"class":1110,"line":1576},41,[1108,1578,1191],{"emptyLinePlaceholder":1190},[1108,1580,1582,1584,1587],{"class":1110,"line":1581},42,[1108,1583,1198],{"class":1197},[1108,1585,1586],{"class":1201}," PluginRegistry",[1108,1588,1277],{"class":1136},[1108,1590,1592,1594,1597],{"class":1110,"line":1591},43,[1108,1593,1218],{"class":1217},[1108,1595,1596],{"class":1221},"Registry for managing plugins",[1108,1598,1225],{"class":1217},[1108,1600,1602],{"class":1110,"line":1601},44,[1108,1603,1231],{"class":1125},[1108,1605,1607,1609,1613,1615,1617],{"class":1110,"line":1606},45,[1108,1608,1256],{"class":1197},[1108,1610,1612],{"class":1611},"sJdAF"," __init__",[1108,1614,1205],{"class":1136},[1108,1616,1265],{"class":1264},[1108,1618,1211],{"class":1136},[1108,1620,1622,1625,1628,1632,1634,1636,1638,1640,1642,1644,1647,1650],{"class":1110,"line":1621},46,[1108,1623,1624],{"class":1132},"        self",[1108,1626,1627],{"class":1136},".",[1108,1629,1631],{"class":1630},"sBPpx","plugins",[1108,1633,1490],{"class":1136},[1108,1635,1153],{"class":1125},[1108,1637,1433],{"class":1136},[1108,1639,1436],{"class":1240},[1108,1641,1137],{"class":1136},[1108,1643,1202],{"class":1125},[1108,1645,1646],{"class":1136},"]",[1108,1648,1649],{"class":1136}," =",[1108,1651,1652],{"class":1136}," {}\n",[1108,1654,1656,1658,1660,1663,1665,1667,1669,1671,1673,1675,1677,1679],{"class":1110,"line":1655},47,[1108,1657,1624],{"class":1132},[1108,1659,1627],{"class":1136},[1108,1661,1662],{"class":1630},"enabled_plugins",[1108,1664,1490],{"class":1136},[1108,1666,1153],{"class":1125},[1108,1668,1433],{"class":1136},[1108,1670,1436],{"class":1240},[1108,1672,1137],{"class":1136},[1108,1674,1202],{"class":1125},[1108,1676,1646],{"class":1136},[1108,1678,1649],{"class":1136},[1108,1680,1652],{"class":1136},[1108,1682,1684,1686,1688,1691,1693,1695,1697,1699,1701,1703,1705,1708,1711,1713],{"class":1110,"line":1683},48,[1108,1685,1624],{"class":1132},[1108,1687,1627],{"class":1136},[1108,1689,1690],{"class":1630},"hooks",[1108,1692,1490],{"class":1136},[1108,1694,1153],{"class":1125},[1108,1696,1433],{"class":1136},[1108,1698,1436],{"class":1240},[1108,1700,1137],{"class":1136},[1108,1702,1158],{"class":1125},[1108,1704,1433],{"class":1136},[1108,1706,1707],{"class":1611},"callable",[1108,1709,1710],{"class":1136},"]]",[1108,1712,1649],{"class":1136},[1108,1714,1652],{"class":1136},[1108,1716,1718],{"class":1110,"line":1717},49,[1108,1719,1231],{"class":1125},[1108,1721,1723,1725,1728,1730,1732,1734,1737,1739,1741,1743,1745,1747],{"class":1110,"line":1722},50,[1108,1724,1256],{"class":1197},[1108,1726,1727],{"class":1249}," register_plugin",[1108,1729,1205],{"class":1136},[1108,1731,1265],{"class":1264},[1108,1733,1137],{"class":1136},[1108,1735,1736],{"class":1486}," plugin",[1108,1738,1490],{"class":1136},[1108,1740,1202],{"class":1125},[1108,1742,1268],{"class":1136},[1108,1744,1271],{"class":1136},[1108,1746,1509],{"class":1508},[1108,1748,1277],{"class":1136},[1108,1750,1752,1754,1757],{"class":1110,"line":1751},51,[1108,1753,1283],{"class":1217},[1108,1755,1756],{"class":1221},"Register a plugin",[1108,1758,1225],{"class":1217},[1108,1760,1762,1765,1767,1769,1772,1776,1779,1781,1783],{"class":1110,"line":1761},52,[1108,1763,1764],{"class":1121},"        if",[1108,1766,1736],{"class":1125},[1108,1768,1627],{"class":1136},[1108,1770,1771],{"class":1630},"name",[1108,1773,1775],{"class":1774},"sVsLi"," in",[1108,1777,1778],{"class":1132}," self",[1108,1780,1627],{"class":1136},[1108,1782,1631],{"class":1630},[1108,1784,1277],{"class":1136},[1108,1786,1788,1791,1794,1796,1799,1803,1807,1811,1813,1815,1818,1821],{"class":1110,"line":1787},53,[1108,1789,1790],{"class":1121},"            raise",[1108,1792,1793],{"class":1240}," ValueError",[1108,1795,1205],{"class":1136},[1108,1797,1798],{"class":1197},"f",[1108,1800,1802],{"class":1801},"sTbE_","\"Plugin ",[1108,1804,1806],{"class":1805},"s3h35","{",[1108,1808,1810],{"class":1809},"siWMO","plugin",[1108,1812,1627],{"class":1136},[1108,1814,1771],{"class":1630},[1108,1816,1817],{"class":1805},"}",[1108,1819,1820],{"class":1801}," already registered\"",[1108,1822,1823],{"class":1136},")\n",[1108,1825,1827],{"class":1110,"line":1826},54,[1108,1828,1829],{"class":1125},"        \n",[1108,1831,1833],{"class":1110,"line":1832},55,[1108,1834,1835],{"class":1114},"        # Check dependencies\n",[1108,1837,1839,1842,1845,1848,1850,1852,1855],{"class":1110,"line":1838},56,[1108,1840,1841],{"class":1121},"        for",[1108,1843,1844],{"class":1125}," dep ",[1108,1846,1847],{"class":1121},"in",[1108,1849,1736],{"class":1125},[1108,1851,1627],{"class":1136},[1108,1853,1854],{"class":1630},"dependencies",[1108,1856,1277],{"class":1136},[1108,1858,1860,1863,1865,1868,1870,1872,1874,1876],{"class":1110,"line":1859},57,[1108,1861,1862],{"class":1121},"            if",[1108,1864,1844],{"class":1125},[1108,1866,1867],{"class":1774},"not",[1108,1869,1775],{"class":1774},[1108,1871,1778],{"class":1132},[1108,1873,1627],{"class":1136},[1108,1875,1631],{"class":1630},[1108,1877,1277],{"class":1136},[1108,1879,1881,1884,1886,1888,1890,1892,1894,1896,1898,1900,1902,1905,1907,1910,1912,1915],{"class":1110,"line":1880},58,[1108,1882,1883],{"class":1121},"                raise",[1108,1885,1793],{"class":1240},[1108,1887,1205],{"class":1136},[1108,1889,1798],{"class":1197},[1108,1891,1802],{"class":1801},[1108,1893,1806],{"class":1805},[1108,1895,1810],{"class":1809},[1108,1897,1627],{"class":1136},[1108,1899,1771],{"class":1630},[1108,1901,1817],{"class":1805},[1108,1903,1904],{"class":1801}," requires ",[1108,1906,1806],{"class":1805},[1108,1908,1909],{"class":1809},"dep",[1108,1911,1817],{"class":1805},[1108,1913,1914],{"class":1801},"\"",[1108,1916,1823],{"class":1136},[1108,1918,1920],{"class":1110,"line":1919},59,[1108,1921,1829],{"class":1125},[1108,1923,1925,1927,1929,1931,1933,1935,1937,1939,1941,1943],{"class":1110,"line":1924},60,[1108,1926,1624],{"class":1132},[1108,1928,1627],{"class":1136},[1108,1930,1631],{"class":1630},[1108,1932,1433],{"class":1136},[1108,1934,1810],{"class":1630},[1108,1936,1627],{"class":1136},[1108,1938,1771],{"class":1630},[1108,1940,1646],{"class":1136},[1108,1942,1649],{"class":1136},[1108,1944,1945],{"class":1125}," plugin\n",[1108,1947,1949],{"class":1110,"line":1948},61,[1108,1950,1231],{"class":1125},[1108,1952,1954,1956,1959,1961,1963,1965,1968,1970,1972,1974,1976,1978,1980,1982,1984,1986,1988,1990,1992,1994,1996,1998,2000],{"class":1110,"line":1953},62,[1108,1955,1256],{"class":1197},[1108,1957,1958],{"class":1249}," enable_plugin",[1108,1960,1205],{"class":1136},[1108,1962,1265],{"class":1264},[1108,1964,1137],{"class":1136},[1108,1966,1967],{"class":1486}," plugin_name",[1108,1969,1490],{"class":1136},[1108,1971,1274],{"class":1240},[1108,1973,1137],{"class":1136},[1108,1975,1487],{"class":1486},[1108,1977,1490],{"class":1136},[1108,1979,1153],{"class":1125},[1108,1981,1433],{"class":1136},[1108,1983,1436],{"class":1240},[1108,1985,1137],{"class":1136},[1108,1987,1163],{"class":1125},[1108,1989,1646],{"class":1136},[1108,1991,1649],{"class":1136},[1108,1993,1509],{"class":1508},[1108,1995,1268],{"class":1136},[1108,1997,1271],{"class":1136},[1108,1999,1509],{"class":1508},[1108,2001,1277],{"class":1136},[1108,2003,2005,2007,2010],{"class":1110,"line":2004},63,[1108,2006,1283],{"class":1217},[1108,2008,2009],{"class":1221},"Enable a plugin",[1108,2011,1225],{"class":1217},[1108,2013,2015,2017,2020,2022,2024,2026,2028,2030],{"class":1110,"line":2014},64,[1108,2016,1764],{"class":1121},[1108,2018,2019],{"class":1125}," plugin_name ",[1108,2021,1867],{"class":1774},[1108,2023,1775],{"class":1774},[1108,2025,1778],{"class":1132},[1108,2027,1627],{"class":1136},[1108,2029,1631],{"class":1630},[1108,2031,1277],{"class":1136},[1108,2033,2035,2037,2039,2041,2043,2045,2047,2050,2052,2055],{"class":1110,"line":2034},65,[1108,2036,1790],{"class":1121},[1108,2038,1793],{"class":1240},[1108,2040,1205],{"class":1136},[1108,2042,1798],{"class":1197},[1108,2044,1802],{"class":1801},[1108,2046,1806],{"class":1805},[1108,2048,2049],{"class":1809},"plugin_name",[1108,2051,1817],{"class":1805},[1108,2053,2054],{"class":1801}," not found\"",[1108,2056,1823],{"class":1136},[1108,2058,2060],{"class":1110,"line":2059},66,[1108,2061,1829],{"class":1125},[1108,2063,2065,2067,2069,2071,2073,2075,2077],{"class":1110,"line":2064},67,[1108,2066,1764],{"class":1121},[1108,2068,2019],{"class":1125},[1108,2070,1847],{"class":1774},[1108,2072,1778],{"class":1132},[1108,2074,1627],{"class":1136},[1108,2076,1662],{"class":1630},[1108,2078,1277],{"class":1136},[1108,2080,2082,2085],{"class":1110,"line":2081},68,[1108,2083,2084],{"class":1121},"            return",[1108,2086,2087],{"class":1114},"  # Already enabled\n",[1108,2089,2091],{"class":1110,"line":2090},69,[1108,2092,1829],{"class":1125},[1108,2094,2096,2099,2102,2104,2106,2108,2110,2112],{"class":1110,"line":2095},70,[1108,2097,2098],{"class":1125},"        plugin ",[1108,2100,2101],{"class":1136},"=",[1108,2103,1778],{"class":1132},[1108,2105,1627],{"class":1136},[1108,2107,1631],{"class":1630},[1108,2109,1433],{"class":1136},[1108,2111,2049],{"class":1630},[1108,2113,2114],{"class":1136},"]\n",[1108,2116,2118],{"class":1110,"line":2117},71,[1108,2119,1829],{"class":1125},[1108,2121,2123],{"class":1110,"line":2122},72,[1108,2124,2125],{"class":1114},"        # Enable dependencies first\n",[1108,2127,2129,2131,2133,2135,2137,2139,2141],{"class":1110,"line":2128},73,[1108,2130,1841],{"class":1121},[1108,2132,1844],{"class":1125},[1108,2134,1847],{"class":1121},[1108,2136,1736],{"class":1125},[1108,2138,1627],{"class":1136},[1108,2140,1854],{"class":1630},[1108,2142,1277],{"class":1136},[1108,2144,2146,2149,2151,2154,2156,2158],{"class":1110,"line":2145},74,[1108,2147,2148],{"class":1132},"            self",[1108,2150,1627],{"class":1136},[1108,2152,2153],{"class":1809},"enable_plugin",[1108,2155,1205],{"class":1136},[1108,2157,1909],{"class":1809},[1108,2159,1823],{"class":1136},[1108,2161,2163],{"class":1110,"line":2162},75,[1108,2164,1829],{"class":1125},[1108,2166,2168],{"class":1110,"line":2167},76,[1108,2169,2170],{"class":1114},"        # Initialize plugin\n",[1108,2172,2174,2177,2179,2182,2184,2187,2190],{"class":1110,"line":2173},77,[1108,2175,2176],{"class":1125},"        plugin",[1108,2178,1627],{"class":1136},[1108,2180,2181],{"class":1809},"initialize",[1108,2183,1205],{"class":1136},[1108,2185,2186],{"class":1809},"config ",[1108,2188,2189],{"class":1121},"or",[1108,2191,2192],{"class":1136}," {})\n",[1108,2194,2196,2198,2200,2202,2204,2206,2208,2210],{"class":1110,"line":2195},78,[1108,2197,1624],{"class":1132},[1108,2199,1627],{"class":1136},[1108,2201,1662],{"class":1630},[1108,2203,1433],{"class":1136},[1108,2205,2049],{"class":1630},[1108,2207,1646],{"class":1136},[1108,2209,1649],{"class":1136},[1108,2211,1945],{"class":1125},[1108,2213,2215],{"class":1110,"line":2214},79,[1108,2216,1829],{"class":1125},[1108,2218,2220],{"class":1110,"line":2219},80,[1108,2221,2222],{"class":1114},"        # Register plugin hooks\n",[1108,2224,2226,2228,2230,2233,2235,2237],{"class":1110,"line":2225},81,[1108,2227,1624],{"class":1132},[1108,2229,1627],{"class":1136},[1108,2231,2232],{"class":1809},"_register_plugin_hooks",[1108,2234,1205],{"class":1136},[1108,2236,1810],{"class":1809},[1108,2238,1823],{"class":1136},[1108,2240,2242],{"class":1110,"line":2241},82,[1108,2243,1231],{"class":1125},[1108,2245,2247,2249,2252,2254,2256,2258,2260,2262,2264,2266,2268,2270],{"class":1110,"line":2246},83,[1108,2248,1256],{"class":1197},[1108,2250,2251],{"class":1249}," disable_plugin",[1108,2253,1205],{"class":1136},[1108,2255,1265],{"class":1264},[1108,2257,1137],{"class":1136},[1108,2259,1967],{"class":1486},[1108,2261,1490],{"class":1136},[1108,2263,1274],{"class":1240},[1108,2265,1268],{"class":1136},[1108,2267,1271],{"class":1136},[1108,2269,1509],{"class":1508},[1108,2271,1277],{"class":1136},[1108,2273,2275,2277,2280],{"class":1110,"line":2274},84,[1108,2276,1283],{"class":1217},[1108,2278,2279],{"class":1221},"Disable a plugin",[1108,2281,1225],{"class":1217},[1108,2283,2285,2287,2289,2291,2293,2295,2297,2299],{"class":1110,"line":2284},85,[1108,2286,1764],{"class":1121},[1108,2288,2019],{"class":1125},[1108,2290,1867],{"class":1774},[1108,2292,1775],{"class":1774},[1108,2294,1778],{"class":1132},[1108,2296,1627],{"class":1136},[1108,2298,1662],{"class":1630},[1108,2300,1277],{"class":1136},[1108,2302,2304,2306],{"class":1110,"line":2303},86,[1108,2305,2084],{"class":1121},[1108,2307,2308],{"class":1114},"  # Already disabled\n",[1108,2310,2312],{"class":1110,"line":2311},87,[1108,2313,1829],{"class":1125},[1108,2315,2317,2319,2321,2323,2325,2327,2329,2331],{"class":1110,"line":2316},88,[1108,2318,2098],{"class":1125},[1108,2320,2101],{"class":1136},[1108,2322,1778],{"class":1132},[1108,2324,1627],{"class":1136},[1108,2326,1662],{"class":1630},[1108,2328,1433],{"class":1136},[1108,2330,2049],{"class":1630},[1108,2332,2114],{"class":1136},[1108,2334,2336],{"class":1110,"line":2335},89,[1108,2337,1829],{"class":1125},[1108,2339,2341],{"class":1110,"line":2340},90,[1108,2342,2343],{"class":1114},"        # Check if other plugins depend on this one\n",[1108,2345,2347,2349,2352,2354,2356,2358,2360,2362,2365],{"class":1110,"line":2346},91,[1108,2348,1841],{"class":1121},[1108,2350,2351],{"class":1125}," other_plugin ",[1108,2353,1847],{"class":1121},[1108,2355,1778],{"class":1132},[1108,2357,1627],{"class":1136},[1108,2359,1662],{"class":1630},[1108,2361,1627],{"class":1136},[1108,2363,2364],{"class":1809},"values",[1108,2366,2367],{"class":1136},"():\n",[1108,2369,2371,2373,2375,2377,2380,2382,2384],{"class":1110,"line":2370},92,[1108,2372,1862],{"class":1121},[1108,2374,2019],{"class":1125},[1108,2376,1847],{"class":1774},[1108,2378,2379],{"class":1125}," other_plugin",[1108,2381,1627],{"class":1136},[1108,2383,1854],{"class":1630},[1108,2385,1277],{"class":1136},[1108,2387,2389,2391,2393,2395,2397,2400,2402,2404,2406,2409,2411,2414,2416,2418,2420,2422],{"class":1110,"line":2388},93,[1108,2390,1883],{"class":1121},[1108,2392,1793],{"class":1240},[1108,2394,1205],{"class":1136},[1108,2396,1798],{"class":1197},[1108,2398,2399],{"class":1801},"\"Cannot disable ",[1108,2401,1806],{"class":1805},[1108,2403,2049],{"class":1809},[1108,2405,1817],{"class":1805},[1108,2407,2408],{"class":1801},": required by ",[1108,2410,1806],{"class":1805},[1108,2412,2413],{"class":1809},"other_plugin",[1108,2415,1627],{"class":1136},[1108,2417,1771],{"class":1630},[1108,2419,1817],{"class":1805},[1108,2421,1914],{"class":1801},[1108,2423,1823],{"class":1136},[1108,2425,2427],{"class":1110,"line":2426},94,[1108,2428,1829],{"class":1125},[1108,2430,2432],{"class":1110,"line":2431},95,[1108,2433,2434],{"class":1114},"        # Cleanup plugin\n",[1108,2436,2438,2440,2442,2445],{"class":1110,"line":2437},96,[1108,2439,2176],{"class":1125},[1108,2441,1627],{"class":1136},[1108,2443,2444],{"class":1809},"cleanup",[1108,2446,2447],{"class":1136},"()\n",[1108,2449,2451],{"class":1110,"line":2450},97,[1108,2452,1829],{"class":1125},[1108,2454,2456],{"class":1110,"line":2455},98,[1108,2457,2458],{"class":1114},"        # Unregister hooks\n",[1108,2460,2462,2464,2466,2469,2471,2473],{"class":1110,"line":2461},99,[1108,2463,1624],{"class":1132},[1108,2465,1627],{"class":1136},[1108,2467,2468],{"class":1809},"_unregister_plugin_hooks",[1108,2470,1205],{"class":1136},[1108,2472,1810],{"class":1809},[1108,2474,1823],{"class":1136},[1108,2476,2478],{"class":1110,"line":2477},100,[1108,2479,1829],{"class":1125},[1108,2481,2483,2486,2488,2490,2492,2494,2496],{"class":1110,"line":2482},101,[1108,2484,2485],{"class":1121},"        del",[1108,2487,1778],{"class":1132},[1108,2489,1627],{"class":1136},[1108,2491,1662],{"class":1630},[1108,2493,1433],{"class":1136},[1108,2495,2049],{"class":1630},[1108,2497,2114],{"class":1136},[1108,2499,2501],{"class":1110,"line":2500},102,[1108,2502,1231],{"class":1125},[1108,2504,2506,2508,2511,2513,2515,2517,2519,2521,2523,2526],{"class":1110,"line":2505},103,[1108,2507,1256],{"class":1197},[1108,2509,2510],{"class":1249}," get_enabled_plugins",[1108,2512,1205],{"class":1136},[1108,2514,1265],{"class":1264},[1108,2516,1268],{"class":1136},[1108,2518,1271],{"class":1136},[1108,2520,1158],{"class":1125},[1108,2522,1433],{"class":1136},[1108,2524,2525],{"class":1125},"PluginInterface",[1108,2527,1439],{"class":1136},[1108,2529,2531,2533,2536],{"class":1110,"line":2530},104,[1108,2532,1283],{"class":1217},[1108,2534,2535],{"class":1221},"Get list of enabled plugins",[1108,2537,1225],{"class":1217},[1108,2539,2541,2543,2546,2548,2550,2552,2554,2556,2558],{"class":1110,"line":2540},105,[1108,2542,1396],{"class":1121},[1108,2544,2545],{"class":1240}," list",[1108,2547,1205],{"class":1136},[1108,2549,1265],{"class":1132},[1108,2551,1627],{"class":1136},[1108,2553,1662],{"class":1630},[1108,2555,1627],{"class":1136},[1108,2557,2364],{"class":1809},[1108,2559,2560],{"class":1136},"())\n",[1108,2562,2564],{"class":1110,"line":2563},106,[1108,2565,1231],{"class":1125},[1108,2567,2569,2571,2574,2576,2578,2580,2583,2585,2587,2589,2592,2594,2597,2599,2601,2603],{"class":1110,"line":2568},107,[1108,2570,1256],{"class":1197},[1108,2572,2573],{"class":1249}," register_hook",[1108,2575,1205],{"class":1136},[1108,2577,1265],{"class":1264},[1108,2579,1137],{"class":1136},[1108,2581,2582],{"class":1486}," hook_name",[1108,2584,1490],{"class":1136},[1108,2586,1274],{"class":1240},[1108,2588,1137],{"class":1136},[1108,2590,2591],{"class":1486}," callback",[1108,2593,1490],{"class":1136},[1108,2595,2596],{"class":1611}," callable",[1108,2598,1268],{"class":1136},[1108,2600,1271],{"class":1136},[1108,2602,1509],{"class":1508},[1108,2604,1277],{"class":1136},[1108,2606,2608,2610,2613],{"class":1110,"line":2607},108,[1108,2609,1283],{"class":1217},[1108,2611,2612],{"class":1221},"Register a hook callback",[1108,2614,1225],{"class":1217},[1108,2616,2618,2620,2623,2625,2627,2629,2631,2633],{"class":1110,"line":2617},109,[1108,2619,1764],{"class":1121},[1108,2621,2622],{"class":1125}," hook_name ",[1108,2624,1867],{"class":1774},[1108,2626,1775],{"class":1774},[1108,2628,1778],{"class":1132},[1108,2630,1627],{"class":1136},[1108,2632,1690],{"class":1630},[1108,2634,1277],{"class":1136},[1108,2636,2638,2640,2642,2644,2646,2649,2651,2653],{"class":1110,"line":2637},110,[1108,2639,2148],{"class":1132},[1108,2641,1627],{"class":1136},[1108,2643,1690],{"class":1630},[1108,2645,1433],{"class":1136},[1108,2647,2648],{"class":1630},"hook_name",[1108,2650,1646],{"class":1136},[1108,2652,1649],{"class":1136},[1108,2654,1457],{"class":1136},[1108,2656,2658,2660,2662,2664,2666,2668,2671,2674,2676,2679],{"class":1110,"line":2657},111,[1108,2659,1624],{"class":1132},[1108,2661,1627],{"class":1136},[1108,2663,1690],{"class":1630},[1108,2665,1433],{"class":1136},[1108,2667,2648],{"class":1630},[1108,2669,2670],{"class":1136},"].",[1108,2672,2673],{"class":1809},"append",[1108,2675,1205],{"class":1136},[1108,2677,2678],{"class":1809},"callback",[1108,2680,1823],{"class":1136},[1108,2682,2684],{"class":1110,"line":2683},112,[1108,2685,1231],{"class":1125},[1108,2687,2689,2691,2694,2696,2698,2700,2702,2704,2706,2708,2711,2714,2716,2719,2722,2724,2726,2728,2730,2733],{"class":1110,"line":2688},113,[1108,2690,1256],{"class":1197},[1108,2692,2693],{"class":1249}," call_hook",[1108,2695,1205],{"class":1136},[1108,2697,1265],{"class":1264},[1108,2699,1137],{"class":1136},[1108,2701,2582],{"class":1486},[1108,2703,1490],{"class":1136},[1108,2705,1274],{"class":1240},[1108,2707,1137],{"class":1136},[1108,2709,2710],{"class":1774}," *",[1108,2712,2713],{"class":1486},"args",[1108,2715,1137],{"class":1136},[1108,2717,2718],{"class":1774}," **",[1108,2720,2721],{"class":1486},"kwargs",[1108,2723,1268],{"class":1136},[1108,2725,1271],{"class":1136},[1108,2727,1158],{"class":1125},[1108,2729,1433],{"class":1136},[1108,2731,2732],{"class":1125},"Any",[1108,2734,1439],{"class":1136},[1108,2736,2738,2740,2743],{"class":1110,"line":2737},114,[1108,2739,1283],{"class":1217},[1108,2741,2742],{"class":1221},"Call all callbacks for a hook",[1108,2744,1225],{"class":1217},[1108,2746,2748,2751,2753],{"class":1110,"line":2747},115,[1108,2749,2750],{"class":1125},"        results ",[1108,2752,2101],{"class":1136},[1108,2754,1457],{"class":1136},[1108,2756,2758,2760,2762,2764,2766,2768,2770],{"class":1110,"line":2757},116,[1108,2759,1764],{"class":1121},[1108,2761,2622],{"class":1125},[1108,2763,1847],{"class":1774},[1108,2765,1778],{"class":1132},[1108,2767,1627],{"class":1136},[1108,2769,1690],{"class":1630},[1108,2771,1277],{"class":1136},[1108,2773,2775,2778,2781,2783,2785,2787,2789,2791,2793],{"class":1110,"line":2774},117,[1108,2776,2777],{"class":1121},"            for",[1108,2779,2780],{"class":1125}," callback ",[1108,2782,1847],{"class":1121},[1108,2784,1778],{"class":1132},[1108,2786,1627],{"class":1136},[1108,2788,1690],{"class":1630},[1108,2790,1433],{"class":1136},[1108,2792,2648],{"class":1630},[1108,2794,1439],{"class":1136},[1108,2796,2798,2801],{"class":1110,"line":2797},118,[1108,2799,2800],{"class":1121},"                try",[1108,2802,1277],{"class":1136},[1108,2804,2806,2809,2811,2813,2815,2818,2820,2822,2824,2826],{"class":1110,"line":2805},119,[1108,2807,2808],{"class":1125},"                    result ",[1108,2810,2101],{"class":1136},[1108,2812,2591],{"class":1809},[1108,2814,1205],{"class":1136},[1108,2816,2817],{"class":1774},"*",[1108,2819,2713],{"class":1809},[1108,2821,1137],{"class":1136},[1108,2823,2718],{"class":1774},[1108,2825,2721],{"class":1809},[1108,2827,1823],{"class":1136},[1108,2829,2831,2834,2836,2838,2840,2843],{"class":1110,"line":2830},120,[1108,2832,2833],{"class":1125},"                    results",[1108,2835,1627],{"class":1136},[1108,2837,2673],{"class":1809},[1108,2839,1205],{"class":1136},[1108,2841,2842],{"class":1809},"result",[1108,2844,1823],{"class":1136},[1108,2846,2848,2851,2854,2857,2860],{"class":1110,"line":2847},121,[1108,2849,2850],{"class":1121},"                except",[1108,2852,2853],{"class":1240}," Exception",[1108,2855,2856],{"class":1121}," as",[1108,2858,2859],{"class":1125}," e",[1108,2861,1277],{"class":1136},[1108,2863,2865],{"class":1110,"line":2864},122,[1108,2866,2867],{"class":1114},"                    # Log error but continue with other hooks\n",[1108,2869,2871,2874,2876,2878,2881,2883,2885,2887,2890,2892,2895,2897,2899],{"class":1110,"line":2870},123,[1108,2872,2873],{"class":1611},"                    print",[1108,2875,1205],{"class":1136},[1108,2877,1798],{"class":1197},[1108,2879,2880],{"class":1801},"\"Hook ",[1108,2882,1806],{"class":1805},[1108,2884,2648],{"class":1809},[1108,2886,1817],{"class":1805},[1108,2888,2889],{"class":1801}," callback failed: ",[1108,2891,1806],{"class":1805},[1108,2893,2894],{"class":1809},"e",[1108,2896,1817],{"class":1805},[1108,2898,1914],{"class":1801},[1108,2900,1823],{"class":1136},[1108,2902,2904,2906],{"class":1110,"line":2903},124,[1108,2905,1396],{"class":1121},[1108,2907,2908],{"class":1125}," results\n",[1108,2910,2912],{"class":1110,"line":2911},125,[1108,2913,1231],{"class":1125},[1108,2915,2917,2919,2922,2924,2926,2928,2930,2932,2934,2936,2938,2940],{"class":1110,"line":2916},126,[1108,2918,1256],{"class":1197},[1108,2920,2921],{"class":1249}," _register_plugin_hooks",[1108,2923,1205],{"class":1136},[1108,2925,1265],{"class":1264},[1108,2927,1137],{"class":1136},[1108,2929,1736],{"class":1486},[1108,2931,1490],{"class":1136},[1108,2933,1202],{"class":1125},[1108,2935,1268],{"class":1136},[1108,2937,1271],{"class":1136},[1108,2939,1509],{"class":1508},[1108,2941,1277],{"class":1136},[1108,2943,2945,2947,2950],{"class":1110,"line":2944},127,[1108,2946,1283],{"class":1217},[1108,2948,2949],{"class":1221},"Register hooks defined by plugin",[1108,2951,1225],{"class":1217},[1108,2953,2955,2957,2960,2962,2965,2967,2969],{"class":1110,"line":2954},128,[1108,2956,1841],{"class":1121},[1108,2958,2959],{"class":1125}," method_name ",[1108,2961,1847],{"class":1121},[1108,2963,2964],{"class":1611}," dir",[1108,2966,1205],{"class":1136},[1108,2968,1810],{"class":1809},[1108,2970,1211],{"class":1136},[1108,2972,2974,2977,2979,2982,2984,2986,2988,2991],{"class":1110,"line":2973},129,[1108,2975,2976],{"class":1125},"            method ",[1108,2978,2101],{"class":1136},[1108,2980,2981],{"class":1611}," getattr",[1108,2983,1205],{"class":1136},[1108,2985,1810],{"class":1809},[1108,2987,1137],{"class":1136},[1108,2989,2990],{"class":1809}," method_name",[1108,2992,1823],{"class":1136},[1108,2994,2996,2998,3001,3003,3006,3008,3011,3014,3017],{"class":1110,"line":2995},130,[1108,2997,1862],{"class":1121},[1108,2999,3000],{"class":1611}," hasattr",[1108,3002,1205],{"class":1136},[1108,3004,3005],{"class":1809},"method",[1108,3007,1137],{"class":1136},[1108,3009,3010],{"class":1399}," '",[1108,3012,3013],{"class":1801},"_hook_name",[1108,3015,3016],{"class":1399},"'",[1108,3018,1211],{"class":1136},[1108,3020,3022,3025,3027,3030,3032,3034,3036,3038,3040,3043],{"class":1110,"line":3021},131,[1108,3023,3024],{"class":1132},"                self",[1108,3026,1627],{"class":1136},[1108,3028,3029],{"class":1809},"register_hook",[1108,3031,1205],{"class":1136},[1108,3033,3005],{"class":1809},[1108,3035,1627],{"class":1136},[1108,3037,3013],{"class":1630},[1108,3039,1137],{"class":1136},[1108,3041,3042],{"class":1809}," method",[1108,3044,1823],{"class":1136},[1108,3046,3048],{"class":1110,"line":3047},132,[1108,3049,1231],{"class":1125},[1108,3051,3053,3055,3058,3060,3062,3064,3066,3068,3070,3072,3074,3076],{"class":1110,"line":3052},133,[1108,3054,1256],{"class":1197},[1108,3056,3057],{"class":1249}," _unregister_plugin_hooks",[1108,3059,1205],{"class":1136},[1108,3061,1265],{"class":1264},[1108,3063,1137],{"class":1136},[1108,3065,1736],{"class":1486},[1108,3067,1490],{"class":1136},[1108,3069,1202],{"class":1125},[1108,3071,1268],{"class":1136},[1108,3073,1271],{"class":1136},[1108,3075,1509],{"class":1508},[1108,3077,1277],{"class":1136},[1108,3079,3081,3083,3086],{"class":1110,"line":3080},134,[1108,3082,1283],{"class":1217},[1108,3084,3085],{"class":1221},"Unregister hooks defined by plugin",[1108,3087,1225],{"class":1217},[1108,3089,3091,3093,3095,3097,3100,3102,3104,3106,3108,3110,3113],{"class":1110,"line":3090},135,[1108,3092,1841],{"class":1121},[1108,3094,2582],{"class":1125},[1108,3096,1137],{"class":1136},[1108,3098,3099],{"class":1125}," callbacks ",[1108,3101,1847],{"class":1121},[1108,3103,1778],{"class":1132},[1108,3105,1627],{"class":1136},[1108,3107,1690],{"class":1630},[1108,3109,1627],{"class":1136},[1108,3111,3112],{"class":1809},"items",[1108,3114,2367],{"class":1136},[1108,3116,3118,3120,3122,3124,3126,3128,3130,3132],{"class":1110,"line":3117},136,[1108,3119,2148],{"class":1132},[1108,3121,1627],{"class":1136},[1108,3123,1690],{"class":1630},[1108,3125,1433],{"class":1136},[1108,3127,2648],{"class":1630},[1108,3129,1646],{"class":1136},[1108,3131,1649],{"class":1136},[1108,3133,3134],{"class":1136}," [\n",[1108,3136,3138,3141,3144,3147,3149],{"class":1110,"line":3137},137,[1108,3139,3140],{"class":1125},"                cb ",[1108,3142,3143],{"class":1121},"for",[1108,3145,3146],{"class":1125}," cb ",[1108,3148,1847],{"class":1121},[1108,3150,3151],{"class":1125}," callbacks \n",[1108,3153,3155,3158,3161,3164,3167,3169,3172,3174,3176,3179,3181,3183,3186,3189,3191,3194,3197,3199],{"class":1110,"line":3154},138,[1108,3156,3157],{"class":1121},"                if",[1108,3159,3160],{"class":1774}," not",[1108,3162,3163],{"class":1136}," (",[1108,3165,3166],{"class":1611},"hasattr",[1108,3168,1205],{"class":1136},[1108,3170,3171],{"class":1809},"cb",[1108,3173,1137],{"class":1136},[1108,3175,3010],{"class":1399},[1108,3177,3178],{"class":1801},"__self__",[1108,3180,3016],{"class":1399},[1108,3182,1268],{"class":1136},[1108,3184,3185],{"class":1774}," and",[1108,3187,3188],{"class":1125}," cb",[1108,3190,1627],{"class":1136},[1108,3192,3178],{"class":3193},"s131V",[1108,3195,3196],{"class":1774}," ==",[1108,3198,1736],{"class":1125},[1108,3200,1823],{"class":1136},[1108,3202,3204],{"class":1110,"line":3203},139,[1108,3205,3206],{"class":1136},"            ]\n",[1108,3208,3210],{"class":1110,"line":3209},140,[1108,3211,1191],{"emptyLinePlaceholder":1190},[1108,3213,3215],{"class":1110,"line":3214},141,[1108,3216,3217],{"class":1114},"# Hook decorator\n",[1108,3219,3221,3224,3227,3229,3231,3233,3235],{"class":1110,"line":3220},142,[1108,3222,3223],{"class":1197},"def",[1108,3225,3226],{"class":1249}," hook",[1108,3228,1205],{"class":1136},[1108,3230,2648],{"class":1486},[1108,3232,1490],{"class":1136},[1108,3234,1274],{"class":1240},[1108,3236,1211],{"class":1136},[1108,3238,3240,3242,3245],{"class":1110,"line":3239},143,[1108,3241,1218],{"class":1217},[1108,3243,3244],{"class":1221},"Decorator to mark methods as hook handlers",[1108,3246,1225],{"class":1217},[1108,3248,3250,3252,3255,3257,3260],{"class":1110,"line":3249},144,[1108,3251,1256],{"class":1197},[1108,3253,3254],{"class":1249}," decorator",[1108,3256,1205],{"class":1136},[1108,3258,3259],{"class":1486},"func",[1108,3261,1211],{"class":1136},[1108,3263,3265,3268,3270,3272,3274],{"class":1110,"line":3264},145,[1108,3266,3267],{"class":1125},"        func",[1108,3269,1627],{"class":1136},[1108,3271,3013],{"class":1630},[1108,3273,1649],{"class":1136},[1108,3275,3276],{"class":1125}," hook_name\n",[1108,3278,3280,3282],{"class":1110,"line":3279},146,[1108,3281,1396],{"class":1121},[1108,3283,3284],{"class":1125}," func\n",[1108,3286,3288,3291],{"class":1110,"line":3287},147,[1108,3289,3290],{"class":1121},"    return",[1108,3292,3293],{"class":1125}," decorator\n",[1108,3295,3297],{"class":1110,"line":3296},148,[1108,3298,1191],{"emptyLinePlaceholder":1190},[1108,3300,3302],{"class":1110,"line":3301},149,[1108,3303,3304],{"class":1114},"# Global plugin registry\n",[1108,3306,3308,3311,3313,3315],{"class":1110,"line":3307},150,[1108,3309,3310],{"class":1125},"plugin_registry ",[1108,3312,2101],{"class":1136},[1108,3314,1586],{"class":1809},[1108,3316,2447],{"class":1136},[1108,3318,3320],{"class":1110,"line":3319},151,[1108,3321,1191],{"emptyLinePlaceholder":1190},[1108,3323,3325],{"class":1110,"line":3324},152,[1108,3326,3327],{"class":1114},"# Example plugin implementation\n",[1108,3329,3331,3333,3336,3338,3341],{"class":1110,"line":3330},153,[1108,3332,1198],{"class":1197},[1108,3334,3335],{"class":1201}," EmailNotificationPlugin",[1108,3337,1205],{"class":1136},[1108,3339,2525],{"class":3340},"sYn-s",[1108,3342,1211],{"class":1136},[1108,3344,3346,3348,3351],{"class":1110,"line":3345},154,[1108,3347,1218],{"class":1217},[1108,3349,3350],{"class":1221},"Plugin for email notifications",[1108,3352,1225],{"class":1217},[1108,3354,3356],{"class":1110,"line":3355},155,[1108,3357,1231],{"class":1125},[1108,3359,3361,3363],{"class":1110,"line":3360},156,[1108,3362,1237],{"class":1136},[1108,3364,1241],{"class":1240},[1108,3366,3368,3370,3372,3374,3376,3378,3380,3382],{"class":1110,"line":3367},157,[1108,3369,1256],{"class":1197},[1108,3371,1259],{"class":1249},[1108,3373,1205],{"class":1136},[1108,3375,1265],{"class":1264},[1108,3377,1268],{"class":1136},[1108,3379,1271],{"class":1136},[1108,3381,1274],{"class":1240},[1108,3383,1277],{"class":1136},[1108,3385,3387,3389,3392,3395],{"class":1110,"line":3386},158,[1108,3388,1396],{"class":1121},[1108,3390,3391],{"class":1399}," \"",[1108,3393,3394],{"class":1801},"email_notifications",[1108,3396,3397],{"class":1399},"\"\n",[1108,3399,3401],{"class":1110,"line":3400},159,[1108,3402,1231],{"class":1125},[1108,3404,3406,3408],{"class":1110,"line":3405},160,[1108,3407,1237],{"class":1136},[1108,3409,1241],{"class":1240},[1108,3411,3413,3415,3417,3419,3421,3423,3425,3427],{"class":1110,"line":3412},161,[1108,3414,1256],{"class":1197},[1108,3416,1321],{"class":1249},[1108,3418,1205],{"class":1136},[1108,3420,1265],{"class":1264},[1108,3422,1268],{"class":1136},[1108,3424,1271],{"class":1136},[1108,3426,1274],{"class":1240},[1108,3428,1277],{"class":1136},[1108,3430,3432,3434,3436,3439],{"class":1110,"line":3431},162,[1108,3433,1396],{"class":1121},[1108,3435,3391],{"class":1399},[1108,3437,3438],{"class":1801},"1.0.0",[1108,3440,3397],{"class":1399},[1108,3442,3444],{"class":1110,"line":3443},163,[1108,3445,1231],{"class":1125},[1108,3447,3449,3451],{"class":1110,"line":3448},164,[1108,3450,1237],{"class":1136},[1108,3452,1241],{"class":1240},[1108,3454,3456,3458,3460,3462,3464,3466,3468,3470],{"class":1110,"line":3455},165,[1108,3457,1256],{"class":1197},[1108,3459,1368],{"class":1249},[1108,3461,1205],{"class":1136},[1108,3463,1265],{"class":1264},[1108,3465,1268],{"class":1136},[1108,3467,1271],{"class":1136},[1108,3469,1274],{"class":1240},[1108,3471,1277],{"class":1136},[1108,3473,3475,3477,3479,3482],{"class":1110,"line":3474},166,[1108,3476,1396],{"class":1121},[1108,3478,3391],{"class":1399},[1108,3480,3481],{"class":1801},"Sends email notifications for various events",[1108,3483,3397],{"class":1399},[1108,3485,3487],{"class":1110,"line":3486},167,[1108,3488,1231],{"class":1125},[1108,3490,3492,3494,3496,3498,3500,3502,3504,3506,3508,3510,3512,3514,3516,3518,3520,3522],{"class":1110,"line":3491},168,[1108,3493,1256],{"class":1197},[1108,3495,1477],{"class":1249},[1108,3497,1205],{"class":1136},[1108,3499,1265],{"class":1264},[1108,3501,1137],{"class":1136},[1108,3503,1487],{"class":1486},[1108,3505,1490],{"class":1136},[1108,3507,1153],{"class":1125},[1108,3509,1433],{"class":1136},[1108,3511,1436],{"class":1240},[1108,3513,1137],{"class":1136},[1108,3515,1163],{"class":1125},[1108,3517,1503],{"class":1136},[1108,3519,1271],{"class":1136},[1108,3521,1509],{"class":1508},[1108,3523,1277],{"class":1136},[1108,3525,3527,3529,3532],{"class":1110,"line":3526},169,[1108,3528,1283],{"class":1217},[1108,3530,3531],{"class":1221},"Initialize email configuration",[1108,3533,1225],{"class":1217},[1108,3535,3537,3539,3541,3544,3546,3548,3550,3553,3555,3557,3559,3561,3563,3565,3568,3570],{"class":1110,"line":3536},170,[1108,3538,1624],{"class":1132},[1108,3540,1627],{"class":1136},[1108,3542,3543],{"class":1630},"smtp_host",[1108,3545,1649],{"class":1136},[1108,3547,1487],{"class":1125},[1108,3549,1627],{"class":1136},[1108,3551,3552],{"class":1809},"get",[1108,3554,1205],{"class":1136},[1108,3556,3016],{"class":1399},[1108,3558,3543],{"class":1801},[1108,3560,3016],{"class":1399},[1108,3562,1137],{"class":1136},[1108,3564,3010],{"class":1399},[1108,3566,3567],{"class":1801},"localhost",[1108,3569,3016],{"class":1399},[1108,3571,1823],{"class":1136},[1108,3573,3575,3577,3579,3582,3584,3586,3588,3590,3592,3594,3596,3598,3600,3604],{"class":1110,"line":3574},171,[1108,3576,1624],{"class":1132},[1108,3578,1627],{"class":1136},[1108,3580,3581],{"class":1630},"smtp_port",[1108,3583,1649],{"class":1136},[1108,3585,1487],{"class":1125},[1108,3587,1627],{"class":1136},[1108,3589,3552],{"class":1809},[1108,3591,1205],{"class":1136},[1108,3593,3016],{"class":1399},[1108,3595,3581],{"class":1801},[1108,3597,3016],{"class":1399},[1108,3599,1137],{"class":1136},[1108,3601,3603],{"class":3602},"s7CZa"," 587",[1108,3605,1823],{"class":1136},[1108,3607,3609,3611,3613,3616,3618,3620,3622,3624,3626,3628,3630,3632],{"class":1110,"line":3608},172,[1108,3610,1624],{"class":1132},[1108,3612,1627],{"class":1136},[1108,3614,3615],{"class":1630},"username",[1108,3617,1649],{"class":1136},[1108,3619,1487],{"class":1125},[1108,3621,1627],{"class":1136},[1108,3623,3552],{"class":1809},[1108,3625,1205],{"class":1136},[1108,3627,3016],{"class":1399},[1108,3629,3615],{"class":1801},[1108,3631,3016],{"class":1399},[1108,3633,1823],{"class":1136},[1108,3635,3637,3639,3641,3644,3646,3648,3650,3652,3654,3656,3658,3660],{"class":1110,"line":3636},173,[1108,3638,1624],{"class":1132},[1108,3640,1627],{"class":1136},[1108,3642,3643],{"class":1630},"password",[1108,3645,1649],{"class":1136},[1108,3647,1487],{"class":1125},[1108,3649,1627],{"class":1136},[1108,3651,3552],{"class":1809},[1108,3653,1205],{"class":1136},[1108,3655,3016],{"class":1399},[1108,3657,3643],{"class":1801},[1108,3659,3016],{"class":1399},[1108,3661,1823],{"class":1136},[1108,3663,3665,3668,3670,3672,3675,3677,3679,3681,3683,3685,3687,3689,3691,3693,3695,3697,3699],{"class":1110,"line":3664},174,[1108,3666,3667],{"class":1611},"        print",[1108,3669,1205],{"class":1136},[1108,3671,1798],{"class":1197},[1108,3673,3674],{"class":1801},"\"Email plugin initialized with SMTP ",[1108,3676,1806],{"class":1805},[1108,3678,1265],{"class":1132},[1108,3680,1627],{"class":1136},[1108,3682,3543],{"class":1630},[1108,3684,1817],{"class":1805},[1108,3686,1490],{"class":1801},[1108,3688,1806],{"class":1805},[1108,3690,1265],{"class":1132},[1108,3692,1627],{"class":1136},[1108,3694,3581],{"class":1630},[1108,3696,1817],{"class":1805},[1108,3698,1914],{"class":1801},[1108,3700,1823],{"class":1136},[1108,3702,3704],{"class":1110,"line":3703},175,[1108,3705,1231],{"class":1125},[1108,3707,3709,3711,3713,3715,3717,3719,3721,3723],{"class":1110,"line":3708},176,[1108,3710,1256],{"class":1197},[1108,3712,1546],{"class":1249},[1108,3714,1205],{"class":1136},[1108,3716,1265],{"class":1264},[1108,3718,1268],{"class":1136},[1108,3720,1271],{"class":1136},[1108,3722,1509],{"class":1508},[1108,3724,1277],{"class":1136},[1108,3726,3728,3730,3733],{"class":1110,"line":3727},177,[1108,3729,1283],{"class":1217},[1108,3731,3732],{"class":1221},"Cleanup email resources",[1108,3734,1225],{"class":1217},[1108,3736,3738,3740,3742,3744,3747,3749],{"class":1110,"line":3737},178,[1108,3739,3667],{"class":1611},[1108,3741,1205],{"class":1136},[1108,3743,1914],{"class":1399},[1108,3745,3746],{"class":1801},"Email plugin cleaned up",[1108,3748,1914],{"class":1399},[1108,3750,1823],{"class":1136},[1108,3752,3754],{"class":1110,"line":3753},179,[1108,3755,1231],{"class":1125},[1108,3757,3759,3761,3764,3766,3768,3771,3773],{"class":1110,"line":3758},180,[1108,3760,1237],{"class":1136},[1108,3762,3763],{"class":1249},"hook",[1108,3765,1205],{"class":1136},[1108,3767,3016],{"class":1399},[1108,3769,3770],{"class":1801},"user_registered",[1108,3772,3016],{"class":1399},[1108,3774,1823],{"class":1136},[1108,3776,3778,3780,3783,3785,3787,3789,3792],{"class":1110,"line":3777},181,[1108,3779,1256],{"class":1197},[1108,3781,3782],{"class":1249}," send_welcome_email",[1108,3784,1205],{"class":1136},[1108,3786,1265],{"class":1264},[1108,3788,1137],{"class":1136},[1108,3790,3791],{"class":1486}," user",[1108,3793,1211],{"class":1136},[1108,3795,3797,3799,3802],{"class":1110,"line":3796},182,[1108,3798,1283],{"class":1217},[1108,3800,3801],{"class":1221},"Send welcome email when user registers",[1108,3803,1225],{"class":1217},[1108,3805,3807,3809,3811,3813,3816,3818,3821,3823,3826,3828,3830],{"class":1110,"line":3806},183,[1108,3808,3667],{"class":1611},[1108,3810,1205],{"class":1136},[1108,3812,1798],{"class":1197},[1108,3814,3815],{"class":1801},"\"Sending welcome email to ",[1108,3817,1806],{"class":1805},[1108,3819,3820],{"class":1809},"user",[1108,3822,1627],{"class":1136},[1108,3824,3825],{"class":1630},"email",[1108,3827,1817],{"class":1805},[1108,3829,1914],{"class":1801},[1108,3831,1823],{"class":1136},[1108,3833,3835],{"class":1110,"line":3834},184,[1108,3836,3837],{"class":1114},"        # Email sending logic here\n",[1108,3839,3841],{"class":1110,"line":3840},185,[1108,3842,1231],{"class":1125},[1108,3844,3846,3848,3850,3852,3854,3857,3859],{"class":1110,"line":3845},186,[1108,3847,1237],{"class":1136},[1108,3849,3763],{"class":1249},[1108,3851,1205],{"class":1136},[1108,3853,3016],{"class":1399},[1108,3855,3856],{"class":1801},"order_confirmed",[1108,3858,3016],{"class":1399},[1108,3860,1823],{"class":1136},[1108,3862,3864,3866,3869,3871,3873,3875,3878],{"class":1110,"line":3863},187,[1108,3865,1256],{"class":1197},[1108,3867,3868],{"class":1249}," send_order_confirmation",[1108,3870,1205],{"class":1136},[1108,3872,1265],{"class":1264},[1108,3874,1137],{"class":1136},[1108,3876,3877],{"class":1486}," order",[1108,3879,1211],{"class":1136},[1108,3881,3883,3885,3888],{"class":1110,"line":3882},188,[1108,3884,1283],{"class":1217},[1108,3886,3887],{"class":1221},"Send order confirmation email",[1108,3889,1225],{"class":1217},[1108,3891,3893,3895,3897,3899,3902,3904,3907,3909,3912,3914,3916],{"class":1110,"line":3892},189,[1108,3894,3667],{"class":1611},[1108,3896,1205],{"class":1136},[1108,3898,1798],{"class":1197},[1108,3900,3901],{"class":1801},"\"Sending order confirmation for order ",[1108,3903,1806],{"class":1805},[1108,3905,3906],{"class":1809},"order",[1108,3908,1627],{"class":1136},[1108,3910,3911],{"class":1630},"id",[1108,3913,1817],{"class":1805},[1108,3915,1914],{"class":1801},[1108,3917,1823],{"class":1136},[1108,3919,3921],{"class":1110,"line":3920},190,[1108,3922,3837],{"class":1114},[1108,3924,3926],{"class":1110,"line":3925},191,[1108,3927,1191],{"emptyLinePlaceholder":1190},[1108,3929,3931,3933,3936,3938,3940],{"class":1110,"line":3930},192,[1108,3932,1198],{"class":1197},[1108,3934,3935],{"class":1201}," SlackNotificationPlugin",[1108,3937,1205],{"class":1136},[1108,3939,2525],{"class":3340},[1108,3941,1211],{"class":1136},[1108,3943,3945,3947,3950],{"class":1110,"line":3944},193,[1108,3946,1218],{"class":1217},[1108,3948,3949],{"class":1221},"Plugin for Slack notifications",[1108,3951,1225],{"class":1217},[1108,3953,3955],{"class":1110,"line":3954},194,[1108,3956,1231],{"class":1125},[1108,3958,3960,3962],{"class":1110,"line":3959},195,[1108,3961,1237],{"class":1136},[1108,3963,1241],{"class":1240},[1108,3965,3967,3969,3971,3973,3975,3977,3979,3981],{"class":1110,"line":3966},196,[1108,3968,1256],{"class":1197},[1108,3970,1259],{"class":1249},[1108,3972,1205],{"class":1136},[1108,3974,1265],{"class":1264},[1108,3976,1268],{"class":1136},[1108,3978,1271],{"class":1136},[1108,3980,1274],{"class":1240},[1108,3982,1277],{"class":1136},[1108,3984,3986,3988,3990,3993],{"class":1110,"line":3985},197,[1108,3987,1396],{"class":1121},[1108,3989,3391],{"class":1399},[1108,3991,3992],{"class":1801},"slack_notifications",[1108,3994,3397],{"class":1399},[1108,3996,3998],{"class":1110,"line":3997},198,[1108,3999,1231],{"class":1125},[1108,4001,4003,4005],{"class":1110,"line":4002},199,[1108,4004,1237],{"class":1136},[1108,4006,1241],{"class":1240},[1108,4008,4010,4012,4014,4016,4018,4020,4022,4024],{"class":1110,"line":4009},200,[1108,4011,1256],{"class":1197},[1108,4013,1321],{"class":1249},[1108,4015,1205],{"class":1136},[1108,4017,1265],{"class":1264},[1108,4019,1268],{"class":1136},[1108,4021,1271],{"class":1136},[1108,4023,1274],{"class":1240},[1108,4025,1277],{"class":1136},[1108,4027,4029,4031,4033,4035],{"class":1110,"line":4028},201,[1108,4030,1396],{"class":1121},[1108,4032,3391],{"class":1399},[1108,4034,3438],{"class":1801},[1108,4036,3397],{"class":1399},[1108,4038,4040],{"class":1110,"line":4039},202,[1108,4041,1231],{"class":1125},[1108,4043,4045,4047],{"class":1110,"line":4044},203,[1108,4046,1237],{"class":1136},[1108,4048,1241],{"class":1240},[1108,4050,4052,4054,4056,4058,4060,4062,4064,4066],{"class":1110,"line":4051},204,[1108,4053,1256],{"class":1197},[1108,4055,1368],{"class":1249},[1108,4057,1205],{"class":1136},[1108,4059,1265],{"class":1264},[1108,4061,1268],{"class":1136},[1108,4063,1271],{"class":1136},[1108,4065,1274],{"class":1240},[1108,4067,1277],{"class":1136},[1108,4069,4071,4073,4075,4078],{"class":1110,"line":4070},205,[1108,4072,1396],{"class":1121},[1108,4074,3391],{"class":1399},[1108,4076,4077],{"class":1801},"Sends notifications to Slack channels",[1108,4079,3397],{"class":1399},[1108,4081,4083],{"class":1110,"line":4082},206,[1108,4084,1231],{"class":1125},[1108,4086,4088,4090,4092,4094,4096,4098,4100,4102,4104,4106,4108,4110,4112,4114,4116,4118],{"class":1110,"line":4087},207,[1108,4089,1256],{"class":1197},[1108,4091,1477],{"class":1249},[1108,4093,1205],{"class":1136},[1108,4095,1265],{"class":1264},[1108,4097,1137],{"class":1136},[1108,4099,1487],{"class":1486},[1108,4101,1490],{"class":1136},[1108,4103,1153],{"class":1125},[1108,4105,1433],{"class":1136},[1108,4107,1436],{"class":1240},[1108,4109,1137],{"class":1136},[1108,4111,1163],{"class":1125},[1108,4113,1503],{"class":1136},[1108,4115,1271],{"class":1136},[1108,4117,1509],{"class":1508},[1108,4119,1277],{"class":1136},[1108,4121,4123,4125,4128],{"class":1110,"line":4122},208,[1108,4124,1283],{"class":1217},[1108,4126,4127],{"class":1221},"Initialize Slack configuration",[1108,4129,1225],{"class":1217},[1108,4131,4133,4135,4137,4140,4142,4144,4146,4148,4150,4152,4154,4156],{"class":1110,"line":4132},209,[1108,4134,1624],{"class":1132},[1108,4136,1627],{"class":1136},[1108,4138,4139],{"class":1630},"webhook_url",[1108,4141,1649],{"class":1136},[1108,4143,1487],{"class":1125},[1108,4145,1627],{"class":1136},[1108,4147,3552],{"class":1809},[1108,4149,1205],{"class":1136},[1108,4151,3016],{"class":1399},[1108,4153,4139],{"class":1801},[1108,4155,3016],{"class":1399},[1108,4157,1823],{"class":1136},[1108,4159,4161,4163,4165,4168,4170,4172,4174,4176,4178,4180,4182,4184,4186,4188,4191,4193],{"class":1110,"line":4160},210,[1108,4162,1624],{"class":1132},[1108,4164,1627],{"class":1136},[1108,4166,4167],{"class":1630},"channel",[1108,4169,1649],{"class":1136},[1108,4171,1487],{"class":1125},[1108,4173,1627],{"class":1136},[1108,4175,3552],{"class":1809},[1108,4177,1205],{"class":1136},[1108,4179,3016],{"class":1399},[1108,4181,4167],{"class":1801},[1108,4183,3016],{"class":1399},[1108,4185,1137],{"class":1136},[1108,4187,3010],{"class":1399},[1108,4189,4190],{"class":1801},"#general",[1108,4192,3016],{"class":1399},[1108,4194,1823],{"class":1136},[1108,4196,4198,4200,4202,4204,4207,4209,4211,4213,4215,4217,4219],{"class":1110,"line":4197},211,[1108,4199,3667],{"class":1611},[1108,4201,1205],{"class":1136},[1108,4203,1798],{"class":1197},[1108,4205,4206],{"class":1801},"\"Slack plugin initialized for channel ",[1108,4208,1806],{"class":1805},[1108,4210,1265],{"class":1132},[1108,4212,1627],{"class":1136},[1108,4214,4167],{"class":1630},[1108,4216,1817],{"class":1805},[1108,4218,1914],{"class":1801},[1108,4220,1823],{"class":1136},[1108,4222,4224],{"class":1110,"line":4223},212,[1108,4225,1231],{"class":1125},[1108,4227,4229,4231,4233,4235,4237,4239,4241,4243],{"class":1110,"line":4228},213,[1108,4230,1256],{"class":1197},[1108,4232,1546],{"class":1249},[1108,4234,1205],{"class":1136},[1108,4236,1265],{"class":1264},[1108,4238,1268],{"class":1136},[1108,4240,1271],{"class":1136},[1108,4242,1509],{"class":1508},[1108,4244,1277],{"class":1136},[1108,4246,4248,4250,4253],{"class":1110,"line":4247},214,[1108,4249,1283],{"class":1217},[1108,4251,4252],{"class":1221},"Cleanup Slack resources",[1108,4254,1225],{"class":1217},[1108,4256,4258,4260,4262,4264,4267,4269],{"class":1110,"line":4257},215,[1108,4259,3667],{"class":1611},[1108,4261,1205],{"class":1136},[1108,4263,1914],{"class":1399},[1108,4265,4266],{"class":1801},"Slack plugin cleaned up",[1108,4268,1914],{"class":1399},[1108,4270,1823],{"class":1136},[1108,4272,4274],{"class":1110,"line":4273},216,[1108,4275,1231],{"class":1125},[1108,4277,4279,4281,4283,4285,4287,4289,4291],{"class":1110,"line":4278},217,[1108,4280,1237],{"class":1136},[1108,4282,3763],{"class":1249},[1108,4284,1205],{"class":1136},[1108,4286,3016],{"class":1399},[1108,4288,3856],{"class":1801},[1108,4290,3016],{"class":1399},[1108,4292,1823],{"class":1136},[1108,4294,4296,4298,4301,4303,4305,4307,4309],{"class":1110,"line":4295},218,[1108,4297,1256],{"class":1197},[1108,4299,4300],{"class":1249}," notify_order_confirmed",[1108,4302,1205],{"class":1136},[1108,4304,1265],{"class":1264},[1108,4306,1137],{"class":1136},[1108,4308,3877],{"class":1486},[1108,4310,1211],{"class":1136},[1108,4312,4314,4316,4319],{"class":1110,"line":4313},219,[1108,4315,1283],{"class":1217},[1108,4317,4318],{"class":1221},"Notify Slack when order is confirmed",[1108,4320,1225],{"class":1217},[1108,4322,4324,4326,4328,4330,4333,4335,4337,4339,4341,4343,4345],{"class":1110,"line":4323},220,[1108,4325,3667],{"class":1611},[1108,4327,1205],{"class":1136},[1108,4329,1798],{"class":1197},[1108,4331,4332],{"class":1801},"\"Notifying Slack about order ",[1108,4334,1806],{"class":1805},[1108,4336,3906],{"class":1809},[1108,4338,1627],{"class":1136},[1108,4340,3911],{"class":1630},[1108,4342,1817],{"class":1805},[1108,4344,1914],{"class":1801},[1108,4346,1823],{"class":1136},[1108,4348,4350],{"class":1110,"line":4349},221,[1108,4351,4352],{"class":1114},"        # Slack notification logic here\n",[1108,4354,4356],{"class":1110,"line":4355},222,[1108,4357,1231],{"class":1125},[1108,4359,4361,4363,4365,4367,4369,4372,4374],{"class":1110,"line":4360},223,[1108,4362,1237],{"class":1136},[1108,4364,3763],{"class":1249},[1108,4366,1205],{"class":1136},[1108,4368,3016],{"class":1399},[1108,4370,4371],{"class":1801},"system_error",[1108,4373,3016],{"class":1399},[1108,4375,1823],{"class":1136},[1108,4377,4379,4381,4384,4386,4388,4390,4393],{"class":1110,"line":4378},224,[1108,4380,1256],{"class":1197},[1108,4382,4383],{"class":1249}," notify_system_error",[1108,4385,1205],{"class":1136},[1108,4387,1265],{"class":1264},[1108,4389,1137],{"class":1136},[1108,4391,4392],{"class":1486}," error",[1108,4394,1211],{"class":1136},[1108,4396,4398,4400,4403],{"class":1110,"line":4397},225,[1108,4399,1283],{"class":1217},[1108,4401,4402],{"class":1221},"Notify Slack about system errors",[1108,4404,1225],{"class":1217},[1108,4406,4408,4410,4412,4414,4417,4419,4422,4424,4426],{"class":1110,"line":4407},226,[1108,4409,3667],{"class":1611},[1108,4411,1205],{"class":1136},[1108,4413,1798],{"class":1197},[1108,4415,4416],{"class":1801},"\"Notifying Slack about error: ",[1108,4418,1806],{"class":1805},[1108,4420,4421],{"class":1809},"error",[1108,4423,1817],{"class":1805},[1108,4425,1914],{"class":1801},[1108,4427,1823],{"class":1136},[1108,4429,4431],{"class":1110,"line":4430},227,[1108,4432,4352],{"class":1114},[1030,4434,4436],{"id":4435},"django-integration","Django Integration",[1038,4438,4440],{"id":4439},"plugin-aware-django-application","Plugin-Aware Django Application",[1098,4442,4444],{"className":1100,"code":4443,"language":1102,"meta":1103,"style":1103},"# Django integration for plugin system\nfrom django.apps import AppConfig\nfrom django.conf import settings\nfrom django.core.management.base import BaseCommand\n\nclass PluginConfig(AppConfig):\n    \"\"\"Django app config with plugin support\"\"\"\n    \n    name = 'plugins'\n    \n    def ready(self):\n        \"\"\"Initialize plugins when Django starts\"\"\"\n        self.load_plugins()\n    \n    def load_plugins(self):\n        \"\"\"Load and enable plugins from settings\"\"\"\n        plugin_configs = getattr(settings, 'PLUGINS', {})\n        \n        for plugin_name, config in plugin_configs.items():\n            try:\n                # Import plugin module\n                module_path = config.get('module')\n                if module_path:\n                    module = importlib.import_module(module_path)\n                    \n                    # Find plugin class\n                    plugin_class = config.get('class')\n                    if plugin_class and hasattr(module, plugin_class):\n                        plugin_instance = getattr(module, plugin_class)()\n                        \n                        # Register and enable plugin\n                        plugin_registry.register_plugin(plugin_instance)\n                        plugin_registry.enable_plugin(\n                            plugin_name, \n                            config.get('settings', {})\n                        )\n                        \n                        print(f\"Loaded plugin: {plugin_name}\")\n            \n            except Exception as e:\n                print(f\"Failed to load plugin {plugin_name}: {e}\")\n\n# Plugin management command\nclass Command(BaseCommand):\n    \"\"\"Management command for plugin operations\"\"\"\n    \n    help = 'Manage plugins'\n    \n    def add_arguments(self, parser):\n        parser.add_argument('action', choices=['list', 'enable', 'disable'])\n        parser.add_argument('--plugin', help='Plugin name')\n    \n    def handle(self, *args, **options):\n        action = options['action']\n        \n        if action == 'list':\n            self.list_plugins()\n        elif action == 'enable':\n            self.enable_plugin(options['plugin'])\n        elif action == 'disable':\n            self.disable_plugin(options['plugin'])\n    \n    def list_plugins(self):\n        \"\"\"List all plugins\"\"\"\n        self.stdout.write(\"Available plugins:\")\n        for name, plugin in plugin_registry.plugins.items():\n            status = \"enabled\" if name in plugin_registry.enabled_plugins else \"disabled\"\n            self.stdout.write(f\"  {name} ({plugin.version}) - {status}\")\n    \n    def enable_plugin(self, plugin_name):\n        \"\"\"Enable a plugin\"\"\"\n        try:\n            plugin_registry.enable_plugin(plugin_name)\n            self.stdout.write(f\"Enabled plugin: {plugin_name}\")\n        except Exception as e:\n            self.stderr.write(f\"Failed to enable plugin {plugin_name}: {e}\")\n    \n    def disable_plugin(self, plugin_name):\n        \"\"\"Disable a plugin\"\"\"\n        try:\n            plugin_registry.disable_plugin(plugin_name)\n            self.stdout.write(f\"Disabled plugin: {plugin_name}\")\n        except Exception as e:\n            self.stderr.write(f\"Failed to disable plugin {plugin_name}: {e}\")\n\n# Plugin-aware views\nfrom django.http import JsonResponse\nfrom django.views import View\n\nclass PluginAwareView(View):\n    \"\"\"Base view that supports plugin hooks\"\"\"\n    \n    def dispatch(self, request, *args, **kwargs):\n        \"\"\"Dispatch with plugin hooks\"\"\"\n        # Pre-dispatch hook\n        plugin_registry.call_hook('view_pre_dispatch', self, request, *args, **kwargs)\n        \n        try:\n            response = super().dispatch(request, *args, **kwargs)\n            \n            # Post-dispatch hook\n            plugin_registry.call_hook('view_post_dispatch', self, request, response, *args, **kwargs)\n            \n            return response\n        \n        except Exception as e:\n            # Error hook\n            plugin_registry.call_hook('view_error', self, request, e, *args, **kwargs)\n            raise\n\nclass UserRegistrationView(PluginAwareView):\n    \"\"\"User registration with plugin hooks\"\"\"\n    \n    def post(self, request):\n        \"\"\"Handle user registration\"\"\"\n        # Validate user data\n        email = request.POST.get('email')\n        password = request.POST.get('password')\n        \n        # Create user\n        user = User.objects.create_user(\n            username=email,\n            email=email,\n            password=password\n        )\n        \n        # Trigger plugin hook\n        plugin_registry.call_hook('user_registered', user)\n        \n        return JsonResponse({'user_id': user.id, 'status': 'created'})\n\n# Settings configuration\n# settings.py\nPLUGINS = {\n    'email_notifications': {\n        'module': 'plugins.email_plugin',\n        'class': 'EmailNotificationPlugin',\n        'settings': {\n            'smtp_host': 'smtp.gmail.com',\n            'smtp_port': 587,\n            'username': 'your-email@gmail.com',\n            'password': 'your-password',\n        }\n    },\n    'slack_notifications': {\n        'module': 'plugins.slack_plugin',\n        'class': 'SlackNotificationPlugin',\n        'settings': {\n            'webhook_url': 'https://hooks.slack.com/services/...',\n            'channel': '#notifications',\n        }\n    }\n}\n",[1105,4445,4446,4451,4468,4484,4510,4514,4528,4537,4541,4555,4559,4572,4581,4592,4596,4609,4618,4645,4649,4671,4678,4683,4707,4716,4738,4743,4748,4771,4795,4815,4820,4825,4842,4853,4863,4884,4889,4893,4915,4920,4933,4964,4968,4973,4987,4996,5000,5014,5018,5036,5092,5124,5128,5154,5174,5178,5196,5207,5224,5246,5262,5285,5289,5302,5311,5336,5362,5400,5452,5456,5472,5480,5487,5502,5531,5544,5582,5586,5602,5610,5616,5630,5659,5671,5708,5712,5717,5733,5749,5753,5767,5776,5780,5810,5819,5824,5865,5869,5875,5910,5914,5919,5963,5967,5974,5978,5990,5995,6038,6043,6047,6061,6070,6074,6091,6100,6105,6134,6161,6165,6170,6192,6204,6215,6225,6230,6234,6239,6261,6265,6310,6314,6319,6324,6333,6346,6366,6385,6397,6417,6431,6450,6469,6474,6479,6491,6510,6529,6541,6560,6579,6583,6588],{"__ignoreMap":1103},[1108,4447,4448],{"class":1110,"line":1111},[1108,4449,4450],{"class":1114},"# Django integration for plugin system\n",[1108,4452,4453,4455,4458,4460,4463,4465],{"class":1110,"line":1118},[1108,4454,1122],{"class":1121},[1108,4456,4457],{"class":1125}," django",[1108,4459,1627],{"class":1136},[1108,4461,4462],{"class":1125},"apps ",[1108,4464,1129],{"class":1121},[1108,4466,4467],{"class":1125}," AppConfig\n",[1108,4469,4470,4472,4474,4476,4479,4481],{"class":1110,"line":1143},[1108,4471,1122],{"class":1121},[1108,4473,4457],{"class":1125},[1108,4475,1627],{"class":1136},[1108,4477,4478],{"class":1125},"conf ",[1108,4480,1129],{"class":1121},[1108,4482,4483],{"class":1125}," settings\n",[1108,4485,4486,4488,4490,4492,4495,4497,4500,4502,4505,4507],{"class":1110,"line":1171},[1108,4487,1122],{"class":1121},[1108,4489,4457],{"class":1125},[1108,4491,1627],{"class":1136},[1108,4493,4494],{"class":1125},"core",[1108,4496,1627],{"class":1136},[1108,4498,4499],{"class":1125},"management",[1108,4501,1627],{"class":1136},[1108,4503,4504],{"class":1125},"base ",[1108,4506,1129],{"class":1121},[1108,4508,4509],{"class":1125}," BaseCommand\n",[1108,4511,4512],{"class":1110,"line":1179},[1108,4513,1191],{"emptyLinePlaceholder":1190},[1108,4515,4516,4518,4521,4523,4526],{"class":1110,"line":1187},[1108,4517,1198],{"class":1197},[1108,4519,4520],{"class":1201}," PluginConfig",[1108,4522,1205],{"class":1136},[1108,4524,4525],{"class":3340},"AppConfig",[1108,4527,1211],{"class":1136},[1108,4529,4530,4532,4535],{"class":1110,"line":1194},[1108,4531,1218],{"class":1217},[1108,4533,4534],{"class":1221},"Django app config with plugin support",[1108,4536,1225],{"class":1217},[1108,4538,4539],{"class":1110,"line":1214},[1108,4540,1231],{"class":1125},[1108,4542,4543,4546,4548,4550,4552],{"class":1110,"line":1228},[1108,4544,4545],{"class":1125},"    name ",[1108,4547,2101],{"class":1136},[1108,4549,3010],{"class":1399},[1108,4551,1631],{"class":1801},[1108,4553,4554],{"class":1399},"'\n",[1108,4556,4557],{"class":1110,"line":1234},[1108,4558,1231],{"class":1125},[1108,4560,4561,4563,4566,4568,4570],{"class":1110,"line":1244},[1108,4562,1256],{"class":1197},[1108,4564,4565],{"class":1249}," ready",[1108,4567,1205],{"class":1136},[1108,4569,1265],{"class":1264},[1108,4571,1211],{"class":1136},[1108,4573,4574,4576,4579],{"class":1110,"line":1253},[1108,4575,1283],{"class":1217},[1108,4577,4578],{"class":1221},"Initialize plugins when Django starts",[1108,4580,1225],{"class":1217},[1108,4582,4583,4585,4587,4590],{"class":1110,"line":1280},[1108,4584,1624],{"class":1132},[1108,4586,1627],{"class":1136},[1108,4588,4589],{"class":1809},"load_plugins",[1108,4591,2447],{"class":1136},[1108,4593,4594],{"class":1110,"line":1291},[1108,4595,1231],{"class":1125},[1108,4597,4598,4600,4603,4605,4607],{"class":1110,"line":1297},[1108,4599,1256],{"class":1197},[1108,4601,4602],{"class":1249}," load_plugins",[1108,4604,1205],{"class":1136},[1108,4606,1265],{"class":1264},[1108,4608,1211],{"class":1136},[1108,4610,4611,4613,4616],{"class":1110,"line":1302},[1108,4612,1283],{"class":1217},[1108,4614,4615],{"class":1221},"Load and enable plugins from settings",[1108,4617,1225],{"class":1217},[1108,4619,4620,4623,4625,4627,4629,4632,4634,4636,4639,4641,4643],{"class":1110,"line":1309},[1108,4621,4622],{"class":1125},"        plugin_configs ",[1108,4624,2101],{"class":1136},[1108,4626,2981],{"class":1611},[1108,4628,1205],{"class":1136},[1108,4630,4631],{"class":1809},"settings",[1108,4633,1137],{"class":1136},[1108,4635,3010],{"class":1399},[1108,4637,4638],{"class":1801},"PLUGINS",[1108,4640,3016],{"class":1399},[1108,4642,1137],{"class":1136},[1108,4644,2192],{"class":1136},[1108,4646,4647],{"class":1110,"line":1316},[1108,4648,1829],{"class":1125},[1108,4650,4651,4653,4655,4657,4660,4662,4665,4667,4669],{"class":1110,"line":1336},[1108,4652,1841],{"class":1121},[1108,4654,1967],{"class":1125},[1108,4656,1137],{"class":1136},[1108,4658,4659],{"class":1125}," config ",[1108,4661,1847],{"class":1121},[1108,4663,4664],{"class":1125}," plugin_configs",[1108,4666,1627],{"class":1136},[1108,4668,3112],{"class":1809},[1108,4670,2367],{"class":1136},[1108,4672,4673,4676],{"class":1110,"line":1346},[1108,4674,4675],{"class":1121},"            try",[1108,4677,1277],{"class":1136},[1108,4679,4680],{"class":1110,"line":1351},[1108,4681,4682],{"class":1114},"                # Import plugin module\n",[1108,4684,4685,4688,4690,4692,4694,4696,4698,4700,4703,4705],{"class":1110,"line":1356},[1108,4686,4687],{"class":1125},"                module_path ",[1108,4689,2101],{"class":1136},[1108,4691,1487],{"class":1125},[1108,4693,1627],{"class":1136},[1108,4695,3552],{"class":1809},[1108,4697,1205],{"class":1136},[1108,4699,3016],{"class":1399},[1108,4701,4702],{"class":1801},"module",[1108,4704,3016],{"class":1399},[1108,4706,1823],{"class":1136},[1108,4708,4709,4711,4714],{"class":1110,"line":1363},[1108,4710,3157],{"class":1121},[1108,4712,4713],{"class":1125}," module_path",[1108,4715,1277],{"class":1136},[1108,4717,4718,4721,4723,4726,4728,4731,4733,4736],{"class":1110,"line":1383},[1108,4719,4720],{"class":1125},"                    module ",[1108,4722,2101],{"class":1136},[1108,4724,4725],{"class":1125}," importlib",[1108,4727,1627],{"class":1136},[1108,4729,4730],{"class":1809},"import_module",[1108,4732,1205],{"class":1136},[1108,4734,4735],{"class":1809},"module_path",[1108,4737,1823],{"class":1136},[1108,4739,4740],{"class":1110,"line":1393},[1108,4741,4742],{"class":1125},"                    \n",[1108,4744,4745],{"class":1110,"line":1403},[1108,4746,4747],{"class":1114},"                    # Find plugin class\n",[1108,4749,4750,4753,4755,4757,4759,4761,4763,4765,4767,4769],{"class":1110,"line":1408},[1108,4751,4752],{"class":1125},"                    plugin_class ",[1108,4754,2101],{"class":1136},[1108,4756,1487],{"class":1125},[1108,4758,1627],{"class":1136},[1108,4760,3552],{"class":1809},[1108,4762,1205],{"class":1136},[1108,4764,3016],{"class":1399},[1108,4766,1198],{"class":1801},[1108,4768,3016],{"class":1399},[1108,4770,1823],{"class":1136},[1108,4772,4773,4776,4779,4782,4784,4786,4788,4790,4793],{"class":1110,"line":1415},[1108,4774,4775],{"class":1121},"                    if",[1108,4777,4778],{"class":1125}," plugin_class ",[1108,4780,4781],{"class":1774},"and",[1108,4783,3000],{"class":1611},[1108,4785,1205],{"class":1136},[1108,4787,4702],{"class":1809},[1108,4789,1137],{"class":1136},[1108,4791,4792],{"class":1809}," plugin_class",[1108,4794,1211],{"class":1136},[1108,4796,4797,4800,4802,4804,4806,4808,4810,4812],{"class":1110,"line":1442},[1108,4798,4799],{"class":1125},"                        plugin_instance ",[1108,4801,2101],{"class":1136},[1108,4803,2981],{"class":1611},[1108,4805,1205],{"class":1136},[1108,4807,4702],{"class":1809},[1108,4809,1137],{"class":1136},[1108,4811,4792],{"class":1809},[1108,4813,4814],{"class":1136},")()\n",[1108,4816,4817],{"class":1110,"line":1452},[1108,4818,4819],{"class":1125},"                        \n",[1108,4821,4822],{"class":1110,"line":1460},[1108,4823,4824],{"class":1114},"                        # Register and enable plugin\n",[1108,4826,4827,4830,4832,4835,4837,4840],{"class":1110,"line":1465},[1108,4828,4829],{"class":1125},"                        plugin_registry",[1108,4831,1627],{"class":1136},[1108,4833,4834],{"class":1809},"register_plugin",[1108,4836,1205],{"class":1136},[1108,4838,4839],{"class":1809},"plugin_instance",[1108,4841,1823],{"class":1136},[1108,4843,4844,4846,4848,4850],{"class":1110,"line":1472},[1108,4845,4829],{"class":1125},[1108,4847,1627],{"class":1136},[1108,4849,2153],{"class":1809},[1108,4851,4852],{"class":1136},"(\n",[1108,4854,4855,4858,4860],{"class":1110,"line":1514},[1108,4856,4857],{"class":1809},"                            plugin_name",[1108,4859,1137],{"class":1136},[1108,4861,4862],{"class":1809}," \n",[1108,4864,4865,4868,4870,4872,4874,4876,4878,4880,4882],{"class":1110,"line":1524},[1108,4866,4867],{"class":1809},"                            config",[1108,4869,1627],{"class":1136},[1108,4871,3552],{"class":1809},[1108,4873,1205],{"class":1136},[1108,4875,3016],{"class":1399},[1108,4877,4631],{"class":1801},[1108,4879,3016],{"class":1399},[1108,4881,1137],{"class":1136},[1108,4883,2192],{"class":1136},[1108,4885,4886],{"class":1110,"line":1529},[1108,4887,4888],{"class":1136},"                        )\n",[1108,4890,4891],{"class":1110,"line":1534},[1108,4892,4819],{"class":1125},[1108,4894,4895,4898,4900,4902,4905,4907,4909,4911,4913],{"class":1110,"line":1541},[1108,4896,4897],{"class":1611},"                        print",[1108,4899,1205],{"class":1136},[1108,4901,1798],{"class":1197},[1108,4903,4904],{"class":1801},"\"Loaded plugin: ",[1108,4906,1806],{"class":1805},[1108,4908,2049],{"class":1809},[1108,4910,1817],{"class":1805},[1108,4912,1914],{"class":1801},[1108,4914,1823],{"class":1136},[1108,4916,4917],{"class":1110,"line":1561},[1108,4918,4919],{"class":1125},"            \n",[1108,4921,4922,4925,4927,4929,4931],{"class":1110,"line":1571},[1108,4923,4924],{"class":1121},"            except",[1108,4926,2853],{"class":1240},[1108,4928,2856],{"class":1121},[1108,4930,2859],{"class":1125},[1108,4932,1277],{"class":1136},[1108,4934,4935,4938,4940,4942,4945,4947,4949,4951,4954,4956,4958,4960,4962],{"class":1110,"line":1576},[1108,4936,4937],{"class":1611},"                print",[1108,4939,1205],{"class":1136},[1108,4941,1798],{"class":1197},[1108,4943,4944],{"class":1801},"\"Failed to load plugin ",[1108,4946,1806],{"class":1805},[1108,4948,2049],{"class":1809},[1108,4950,1817],{"class":1805},[1108,4952,4953],{"class":1801},": ",[1108,4955,1806],{"class":1805},[1108,4957,2894],{"class":1809},[1108,4959,1817],{"class":1805},[1108,4961,1914],{"class":1801},[1108,4963,1823],{"class":1136},[1108,4965,4966],{"class":1110,"line":1581},[1108,4967,1191],{"emptyLinePlaceholder":1190},[1108,4969,4970],{"class":1110,"line":1591},[1108,4971,4972],{"class":1114},"# Plugin management command\n",[1108,4974,4975,4977,4980,4982,4985],{"class":1110,"line":1601},[1108,4976,1198],{"class":1197},[1108,4978,4979],{"class":1201}," Command",[1108,4981,1205],{"class":1136},[1108,4983,4984],{"class":3340},"BaseCommand",[1108,4986,1211],{"class":1136},[1108,4988,4989,4991,4994],{"class":1110,"line":1606},[1108,4990,1218],{"class":1217},[1108,4992,4993],{"class":1221},"Management command for plugin operations",[1108,4995,1225],{"class":1217},[1108,4997,4998],{"class":1110,"line":1621},[1108,4999,1231],{"class":1125},[1108,5001,5002,5005,5007,5009,5012],{"class":1110,"line":1655},[1108,5003,5004],{"class":1611},"    help",[1108,5006,1649],{"class":1136},[1108,5008,3010],{"class":1399},[1108,5010,5011],{"class":1801},"Manage plugins",[1108,5013,4554],{"class":1399},[1108,5015,5016],{"class":1110,"line":1683},[1108,5017,1231],{"class":1125},[1108,5019,5020,5022,5025,5027,5029,5031,5034],{"class":1110,"line":1717},[1108,5021,1256],{"class":1197},[1108,5023,5024],{"class":1249}," add_arguments",[1108,5026,1205],{"class":1136},[1108,5028,1265],{"class":1264},[1108,5030,1137],{"class":1136},[1108,5032,5033],{"class":1486}," parser",[1108,5035,1211],{"class":1136},[1108,5037,5038,5041,5043,5046,5048,5050,5053,5055,5057,5061,5064,5066,5069,5071,5073,5075,5078,5080,5082,5084,5087,5089],{"class":1110,"line":1722},[1108,5039,5040],{"class":1125},"        parser",[1108,5042,1627],{"class":1136},[1108,5044,5045],{"class":1809},"add_argument",[1108,5047,1205],{"class":1136},[1108,5049,3016],{"class":1399},[1108,5051,5052],{"class":1801},"action",[1108,5054,3016],{"class":1399},[1108,5056,1137],{"class":1136},[1108,5058,5060],{"class":5059},"sqOPj"," choices",[1108,5062,5063],{"class":1136},"=[",[1108,5065,3016],{"class":1399},[1108,5067,5068],{"class":1801},"list",[1108,5070,3016],{"class":1399},[1108,5072,1137],{"class":1136},[1108,5074,3010],{"class":1399},[1108,5076,5077],{"class":1801},"enable",[1108,5079,3016],{"class":1399},[1108,5081,1137],{"class":1136},[1108,5083,3010],{"class":1399},[1108,5085,5086],{"class":1801},"disable",[1108,5088,3016],{"class":1399},[1108,5090,5091],{"class":1136},"])\n",[1108,5093,5094,5096,5098,5100,5102,5104,5107,5109,5111,5114,5116,5118,5120,5122],{"class":1110,"line":1751},[1108,5095,5040],{"class":1125},[1108,5097,1627],{"class":1136},[1108,5099,5045],{"class":1809},[1108,5101,1205],{"class":1136},[1108,5103,3016],{"class":1399},[1108,5105,5106],{"class":1801},"--plugin",[1108,5108,3016],{"class":1399},[1108,5110,1137],{"class":1136},[1108,5112,5113],{"class":5059}," help",[1108,5115,2101],{"class":1136},[1108,5117,3016],{"class":1399},[1108,5119,1286],{"class":1801},[1108,5121,3016],{"class":1399},[1108,5123,1823],{"class":1136},[1108,5125,5126],{"class":1110,"line":1761},[1108,5127,1231],{"class":1125},[1108,5129,5130,5132,5135,5137,5139,5141,5143,5145,5147,5149,5152],{"class":1110,"line":1787},[1108,5131,1256],{"class":1197},[1108,5133,5134],{"class":1249}," handle",[1108,5136,1205],{"class":1136},[1108,5138,1265],{"class":1264},[1108,5140,1137],{"class":1136},[1108,5142,2710],{"class":1774},[1108,5144,2713],{"class":1486},[1108,5146,1137],{"class":1136},[1108,5148,2718],{"class":1774},[1108,5150,5151],{"class":1486},"options",[1108,5153,1211],{"class":1136},[1108,5155,5156,5159,5161,5164,5166,5168,5170,5172],{"class":1110,"line":1826},[1108,5157,5158],{"class":1125},"        action ",[1108,5160,2101],{"class":1136},[1108,5162,5163],{"class":1125}," options",[1108,5165,1433],{"class":1136},[1108,5167,3016],{"class":1399},[1108,5169,5052],{"class":1801},[1108,5171,3016],{"class":1399},[1108,5173,2114],{"class":1136},[1108,5175,5176],{"class":1110,"line":1832},[1108,5177,1829],{"class":1125},[1108,5179,5180,5182,5185,5188,5190,5192,5194],{"class":1110,"line":1838},[1108,5181,1764],{"class":1121},[1108,5183,5184],{"class":1125}," action ",[1108,5186,5187],{"class":1774},"==",[1108,5189,3010],{"class":1399},[1108,5191,5068],{"class":1801},[1108,5193,3016],{"class":1399},[1108,5195,1277],{"class":1136},[1108,5197,5198,5200,5202,5205],{"class":1110,"line":1859},[1108,5199,2148],{"class":1132},[1108,5201,1627],{"class":1136},[1108,5203,5204],{"class":1809},"list_plugins",[1108,5206,2447],{"class":1136},[1108,5208,5209,5212,5214,5216,5218,5220,5222],{"class":1110,"line":1880},[1108,5210,5211],{"class":1121},"        elif",[1108,5213,5184],{"class":1125},[1108,5215,5187],{"class":1774},[1108,5217,3010],{"class":1399},[1108,5219,5077],{"class":1801},[1108,5221,3016],{"class":1399},[1108,5223,1277],{"class":1136},[1108,5225,5226,5228,5230,5232,5234,5236,5238,5240,5242,5244],{"class":1110,"line":1919},[1108,5227,2148],{"class":1132},[1108,5229,1627],{"class":1136},[1108,5231,2153],{"class":1809},[1108,5233,1205],{"class":1136},[1108,5235,5151],{"class":1809},[1108,5237,1433],{"class":1136},[1108,5239,3016],{"class":1399},[1108,5241,1810],{"class":1801},[1108,5243,3016],{"class":1399},[1108,5245,5091],{"class":1136},[1108,5247,5248,5250,5252,5254,5256,5258,5260],{"class":1110,"line":1924},[1108,5249,5211],{"class":1121},[1108,5251,5184],{"class":1125},[1108,5253,5187],{"class":1774},[1108,5255,3010],{"class":1399},[1108,5257,5086],{"class":1801},[1108,5259,3016],{"class":1399},[1108,5261,1277],{"class":1136},[1108,5263,5264,5266,5268,5271,5273,5275,5277,5279,5281,5283],{"class":1110,"line":1948},[1108,5265,2148],{"class":1132},[1108,5267,1627],{"class":1136},[1108,5269,5270],{"class":1809},"disable_plugin",[1108,5272,1205],{"class":1136},[1108,5274,5151],{"class":1809},[1108,5276,1433],{"class":1136},[1108,5278,3016],{"class":1399},[1108,5280,1810],{"class":1801},[1108,5282,3016],{"class":1399},[1108,5284,5091],{"class":1136},[1108,5286,5287],{"class":1110,"line":1953},[1108,5288,1231],{"class":1125},[1108,5290,5291,5293,5296,5298,5300],{"class":1110,"line":2004},[1108,5292,1256],{"class":1197},[1108,5294,5295],{"class":1249}," list_plugins",[1108,5297,1205],{"class":1136},[1108,5299,1265],{"class":1264},[1108,5301,1211],{"class":1136},[1108,5303,5304,5306,5309],{"class":1110,"line":2014},[1108,5305,1283],{"class":1217},[1108,5307,5308],{"class":1221},"List all plugins",[1108,5310,1225],{"class":1217},[1108,5312,5313,5315,5317,5320,5322,5325,5327,5329,5332,5334],{"class":1110,"line":2034},[1108,5314,1624],{"class":1132},[1108,5316,1627],{"class":1136},[1108,5318,5319],{"class":1630},"stdout",[1108,5321,1627],{"class":1136},[1108,5323,5324],{"class":1809},"write",[1108,5326,1205],{"class":1136},[1108,5328,1914],{"class":1399},[1108,5330,5331],{"class":1801},"Available plugins:",[1108,5333,1914],{"class":1399},[1108,5335,1823],{"class":1136},[1108,5337,5338,5340,5342,5344,5347,5349,5352,5354,5356,5358,5360],{"class":1110,"line":2059},[1108,5339,1841],{"class":1121},[1108,5341,1259],{"class":1125},[1108,5343,1137],{"class":1136},[1108,5345,5346],{"class":1125}," plugin ",[1108,5348,1847],{"class":1121},[1108,5350,5351],{"class":1125}," plugin_registry",[1108,5353,1627],{"class":1136},[1108,5355,1631],{"class":1630},[1108,5357,1627],{"class":1136},[1108,5359,3112],{"class":1809},[1108,5361,2367],{"class":1136},[1108,5363,5364,5367,5369,5371,5374,5376,5379,5382,5384,5386,5388,5390,5393,5395,5398],{"class":1110,"line":2064},[1108,5365,5366],{"class":1125},"            status ",[1108,5368,2101],{"class":1136},[1108,5370,3391],{"class":1399},[1108,5372,5373],{"class":1801},"enabled",[1108,5375,1914],{"class":1399},[1108,5377,5378],{"class":1121}," if",[1108,5380,5381],{"class":1125}," name ",[1108,5383,1847],{"class":1774},[1108,5385,5351],{"class":1125},[1108,5387,1627],{"class":1136},[1108,5389,1662],{"class":1630},[1108,5391,5392],{"class":1121}," else",[1108,5394,3391],{"class":1399},[1108,5396,5397],{"class":1801},"disabled",[1108,5399,3397],{"class":1399},[1108,5401,5402,5404,5406,5408,5410,5412,5414,5416,5419,5421,5423,5425,5427,5429,5431,5433,5436,5438,5441,5443,5446,5448,5450],{"class":1110,"line":2081},[1108,5403,2148],{"class":1132},[1108,5405,1627],{"class":1136},[1108,5407,5319],{"class":1630},[1108,5409,1627],{"class":1136},[1108,5411,5324],{"class":1809},[1108,5413,1205],{"class":1136},[1108,5415,1798],{"class":1197},[1108,5417,5418],{"class":1801},"\"  ",[1108,5420,1806],{"class":1805},[1108,5422,1771],{"class":1809},[1108,5424,1817],{"class":1805},[1108,5426,3163],{"class":1801},[1108,5428,1806],{"class":1805},[1108,5430,1810],{"class":1809},[1108,5432,1627],{"class":1136},[1108,5434,5435],{"class":1630},"version",[1108,5437,1817],{"class":1805},[1108,5439,5440],{"class":1801},") - ",[1108,5442,1806],{"class":1805},[1108,5444,5445],{"class":1809},"status",[1108,5447,1817],{"class":1805},[1108,5449,1914],{"class":1801},[1108,5451,1823],{"class":1136},[1108,5453,5454],{"class":1110,"line":2090},[1108,5455,1231],{"class":1125},[1108,5457,5458,5460,5462,5464,5466,5468,5470],{"class":1110,"line":2095},[1108,5459,1256],{"class":1197},[1108,5461,1958],{"class":1249},[1108,5463,1205],{"class":1136},[1108,5465,1265],{"class":1264},[1108,5467,1137],{"class":1136},[1108,5469,1967],{"class":1486},[1108,5471,1211],{"class":1136},[1108,5473,5474,5476,5478],{"class":1110,"line":2117},[1108,5475,1283],{"class":1217},[1108,5477,2009],{"class":1221},[1108,5479,1225],{"class":1217},[1108,5481,5482,5485],{"class":1110,"line":2122},[1108,5483,5484],{"class":1121},"        try",[1108,5486,1277],{"class":1136},[1108,5488,5489,5492,5494,5496,5498,5500],{"class":1110,"line":2128},[1108,5490,5491],{"class":1125},"            plugin_registry",[1108,5493,1627],{"class":1136},[1108,5495,2153],{"class":1809},[1108,5497,1205],{"class":1136},[1108,5499,2049],{"class":1809},[1108,5501,1823],{"class":1136},[1108,5503,5504,5506,5508,5510,5512,5514,5516,5518,5521,5523,5525,5527,5529],{"class":1110,"line":2145},[1108,5505,2148],{"class":1132},[1108,5507,1627],{"class":1136},[1108,5509,5319],{"class":1630},[1108,5511,1627],{"class":1136},[1108,5513,5324],{"class":1809},[1108,5515,1205],{"class":1136},[1108,5517,1798],{"class":1197},[1108,5519,5520],{"class":1801},"\"Enabled plugin: ",[1108,5522,1806],{"class":1805},[1108,5524,2049],{"class":1809},[1108,5526,1817],{"class":1805},[1108,5528,1914],{"class":1801},[1108,5530,1823],{"class":1136},[1108,5532,5533,5536,5538,5540,5542],{"class":1110,"line":2162},[1108,5534,5535],{"class":1121},"        except",[1108,5537,2853],{"class":1240},[1108,5539,2856],{"class":1121},[1108,5541,2859],{"class":1125},[1108,5543,1277],{"class":1136},[1108,5545,5546,5548,5550,5553,5555,5557,5559,5561,5564,5566,5568,5570,5572,5574,5576,5578,5580],{"class":1110,"line":2167},[1108,5547,2148],{"class":1132},[1108,5549,1627],{"class":1136},[1108,5551,5552],{"class":1630},"stderr",[1108,5554,1627],{"class":1136},[1108,5556,5324],{"class":1809},[1108,5558,1205],{"class":1136},[1108,5560,1798],{"class":1197},[1108,5562,5563],{"class":1801},"\"Failed to enable plugin ",[1108,5565,1806],{"class":1805},[1108,5567,2049],{"class":1809},[1108,5569,1817],{"class":1805},[1108,5571,4953],{"class":1801},[1108,5573,1806],{"class":1805},[1108,5575,2894],{"class":1809},[1108,5577,1817],{"class":1805},[1108,5579,1914],{"class":1801},[1108,5581,1823],{"class":1136},[1108,5583,5584],{"class":1110,"line":2173},[1108,5585,1231],{"class":1125},[1108,5587,5588,5590,5592,5594,5596,5598,5600],{"class":1110,"line":2195},[1108,5589,1256],{"class":1197},[1108,5591,2251],{"class":1249},[1108,5593,1205],{"class":1136},[1108,5595,1265],{"class":1264},[1108,5597,1137],{"class":1136},[1108,5599,1967],{"class":1486},[1108,5601,1211],{"class":1136},[1108,5603,5604,5606,5608],{"class":1110,"line":2214},[1108,5605,1283],{"class":1217},[1108,5607,2279],{"class":1221},[1108,5609,1225],{"class":1217},[1108,5611,5612,5614],{"class":1110,"line":2219},[1108,5613,5484],{"class":1121},[1108,5615,1277],{"class":1136},[1108,5617,5618,5620,5622,5624,5626,5628],{"class":1110,"line":2225},[1108,5619,5491],{"class":1125},[1108,5621,1627],{"class":1136},[1108,5623,5270],{"class":1809},[1108,5625,1205],{"class":1136},[1108,5627,2049],{"class":1809},[1108,5629,1823],{"class":1136},[1108,5631,5632,5634,5636,5638,5640,5642,5644,5646,5649,5651,5653,5655,5657],{"class":1110,"line":2241},[1108,5633,2148],{"class":1132},[1108,5635,1627],{"class":1136},[1108,5637,5319],{"class":1630},[1108,5639,1627],{"class":1136},[1108,5641,5324],{"class":1809},[1108,5643,1205],{"class":1136},[1108,5645,1798],{"class":1197},[1108,5647,5648],{"class":1801},"\"Disabled plugin: ",[1108,5650,1806],{"class":1805},[1108,5652,2049],{"class":1809},[1108,5654,1817],{"class":1805},[1108,5656,1914],{"class":1801},[1108,5658,1823],{"class":1136},[1108,5660,5661,5663,5665,5667,5669],{"class":1110,"line":2246},[1108,5662,5535],{"class":1121},[1108,5664,2853],{"class":1240},[1108,5666,2856],{"class":1121},[1108,5668,2859],{"class":1125},[1108,5670,1277],{"class":1136},[1108,5672,5673,5675,5677,5679,5681,5683,5685,5687,5690,5692,5694,5696,5698,5700,5702,5704,5706],{"class":1110,"line":2274},[1108,5674,2148],{"class":1132},[1108,5676,1627],{"class":1136},[1108,5678,5552],{"class":1630},[1108,5680,1627],{"class":1136},[1108,5682,5324],{"class":1809},[1108,5684,1205],{"class":1136},[1108,5686,1798],{"class":1197},[1108,5688,5689],{"class":1801},"\"Failed to disable plugin ",[1108,5691,1806],{"class":1805},[1108,5693,2049],{"class":1809},[1108,5695,1817],{"class":1805},[1108,5697,4953],{"class":1801},[1108,5699,1806],{"class":1805},[1108,5701,2894],{"class":1809},[1108,5703,1817],{"class":1805},[1108,5705,1914],{"class":1801},[1108,5707,1823],{"class":1136},[1108,5709,5710],{"class":1110,"line":2284},[1108,5711,1191],{"emptyLinePlaceholder":1190},[1108,5713,5714],{"class":1110,"line":2303},[1108,5715,5716],{"class":1114},"# Plugin-aware views\n",[1108,5718,5719,5721,5723,5725,5728,5730],{"class":1110,"line":2311},[1108,5720,1122],{"class":1121},[1108,5722,4457],{"class":1125},[1108,5724,1627],{"class":1136},[1108,5726,5727],{"class":1125},"http ",[1108,5729,1129],{"class":1121},[1108,5731,5732],{"class":1125}," JsonResponse\n",[1108,5734,5735,5737,5739,5741,5744,5746],{"class":1110,"line":2316},[1108,5736,1122],{"class":1121},[1108,5738,4457],{"class":1125},[1108,5740,1627],{"class":1136},[1108,5742,5743],{"class":1125},"views ",[1108,5745,1129],{"class":1121},[1108,5747,5748],{"class":1125}," View\n",[1108,5750,5751],{"class":1110,"line":2335},[1108,5752,1191],{"emptyLinePlaceholder":1190},[1108,5754,5755,5757,5760,5762,5765],{"class":1110,"line":2340},[1108,5756,1198],{"class":1197},[1108,5758,5759],{"class":1201}," PluginAwareView",[1108,5761,1205],{"class":1136},[1108,5763,5764],{"class":3340},"View",[1108,5766,1211],{"class":1136},[1108,5768,5769,5771,5774],{"class":1110,"line":2346},[1108,5770,1218],{"class":1217},[1108,5772,5773],{"class":1221},"Base view that supports plugin hooks",[1108,5775,1225],{"class":1217},[1108,5777,5778],{"class":1110,"line":2370},[1108,5779,1231],{"class":1125},[1108,5781,5782,5784,5787,5789,5791,5793,5796,5798,5800,5802,5804,5806,5808],{"class":1110,"line":2388},[1108,5783,1256],{"class":1197},[1108,5785,5786],{"class":1249}," dispatch",[1108,5788,1205],{"class":1136},[1108,5790,1265],{"class":1264},[1108,5792,1137],{"class":1136},[1108,5794,5795],{"class":1486}," request",[1108,5797,1137],{"class":1136},[1108,5799,2710],{"class":1774},[1108,5801,2713],{"class":1486},[1108,5803,1137],{"class":1136},[1108,5805,2718],{"class":1774},[1108,5807,2721],{"class":1486},[1108,5809,1211],{"class":1136},[1108,5811,5812,5814,5817],{"class":1110,"line":2426},[1108,5813,1283],{"class":1217},[1108,5815,5816],{"class":1221},"Dispatch with plugin hooks",[1108,5818,1225],{"class":1217},[1108,5820,5821],{"class":1110,"line":2431},[1108,5822,5823],{"class":1114},"        # Pre-dispatch hook\n",[1108,5825,5826,5829,5831,5834,5836,5838,5841,5843,5845,5847,5849,5851,5853,5855,5857,5859,5861,5863],{"class":1110,"line":2437},[1108,5827,5828],{"class":1125},"        plugin_registry",[1108,5830,1627],{"class":1136},[1108,5832,5833],{"class":1809},"call_hook",[1108,5835,1205],{"class":1136},[1108,5837,3016],{"class":1399},[1108,5839,5840],{"class":1801},"view_pre_dispatch",[1108,5842,3016],{"class":1399},[1108,5844,1137],{"class":1136},[1108,5846,1778],{"class":1132},[1108,5848,1137],{"class":1136},[1108,5850,5795],{"class":1809},[1108,5852,1137],{"class":1136},[1108,5854,2710],{"class":1774},[1108,5856,2713],{"class":1809},[1108,5858,1137],{"class":1136},[1108,5860,2718],{"class":1774},[1108,5862,2721],{"class":1809},[1108,5864,1823],{"class":1136},[1108,5866,5867],{"class":1110,"line":2450},[1108,5868,1829],{"class":1125},[1108,5870,5871,5873],{"class":1110,"line":2455},[1108,5872,5484],{"class":1121},[1108,5874,1277],{"class":1136},[1108,5876,5877,5880,5882,5885,5888,5891,5893,5896,5898,5900,5902,5904,5906,5908],{"class":1110,"line":2461},[1108,5878,5879],{"class":1125},"            response ",[1108,5881,2101],{"class":1136},[1108,5883,5884],{"class":1240}," super",[1108,5886,5887],{"class":1136},"().",[1108,5889,5890],{"class":1809},"dispatch",[1108,5892,1205],{"class":1136},[1108,5894,5895],{"class":1809},"request",[1108,5897,1137],{"class":1136},[1108,5899,2710],{"class":1774},[1108,5901,2713],{"class":1809},[1108,5903,1137],{"class":1136},[1108,5905,2718],{"class":1774},[1108,5907,2721],{"class":1809},[1108,5909,1823],{"class":1136},[1108,5911,5912],{"class":1110,"line":2477},[1108,5913,4919],{"class":1125},[1108,5915,5916],{"class":1110,"line":2482},[1108,5917,5918],{"class":1114},"            # Post-dispatch hook\n",[1108,5920,5921,5923,5925,5927,5929,5931,5934,5936,5938,5940,5942,5944,5946,5949,5951,5953,5955,5957,5959,5961],{"class":1110,"line":2500},[1108,5922,5491],{"class":1125},[1108,5924,1627],{"class":1136},[1108,5926,5833],{"class":1809},[1108,5928,1205],{"class":1136},[1108,5930,3016],{"class":1399},[1108,5932,5933],{"class":1801},"view_post_dispatch",[1108,5935,3016],{"class":1399},[1108,5937,1137],{"class":1136},[1108,5939,1778],{"class":1132},[1108,5941,1137],{"class":1136},[1108,5943,5795],{"class":1809},[1108,5945,1137],{"class":1136},[1108,5947,5948],{"class":1809}," response",[1108,5950,1137],{"class":1136},[1108,5952,2710],{"class":1774},[1108,5954,2713],{"class":1809},[1108,5956,1137],{"class":1136},[1108,5958,2718],{"class":1774},[1108,5960,2721],{"class":1809},[1108,5962,1823],{"class":1136},[1108,5964,5965],{"class":1110,"line":2505},[1108,5966,4919],{"class":1125},[1108,5968,5969,5971],{"class":1110,"line":2530},[1108,5970,2084],{"class":1121},[1108,5972,5973],{"class":1125}," response\n",[1108,5975,5976],{"class":1110,"line":2540},[1108,5977,1829],{"class":1125},[1108,5979,5980,5982,5984,5986,5988],{"class":1110,"line":2563},[1108,5981,5535],{"class":1121},[1108,5983,2853],{"class":1240},[1108,5985,2856],{"class":1121},[1108,5987,2859],{"class":1125},[1108,5989,1277],{"class":1136},[1108,5991,5992],{"class":1110,"line":2568},[1108,5993,5994],{"class":1114},"            # Error hook\n",[1108,5996,5997,5999,6001,6003,6005,6007,6010,6012,6014,6016,6018,6020,6022,6024,6026,6028,6030,6032,6034,6036],{"class":1110,"line":2607},[1108,5998,5491],{"class":1125},[1108,6000,1627],{"class":1136},[1108,6002,5833],{"class":1809},[1108,6004,1205],{"class":1136},[1108,6006,3016],{"class":1399},[1108,6008,6009],{"class":1801},"view_error",[1108,6011,3016],{"class":1399},[1108,6013,1137],{"class":1136},[1108,6015,1778],{"class":1132},[1108,6017,1137],{"class":1136},[1108,6019,5795],{"class":1809},[1108,6021,1137],{"class":1136},[1108,6023,2859],{"class":1809},[1108,6025,1137],{"class":1136},[1108,6027,2710],{"class":1774},[1108,6029,2713],{"class":1809},[1108,6031,1137],{"class":1136},[1108,6033,2718],{"class":1774},[1108,6035,2721],{"class":1809},[1108,6037,1823],{"class":1136},[1108,6039,6040],{"class":1110,"line":2617},[1108,6041,6042],{"class":1121},"            raise\n",[1108,6044,6045],{"class":1110,"line":2637},[1108,6046,1191],{"emptyLinePlaceholder":1190},[1108,6048,6049,6051,6054,6056,6059],{"class":1110,"line":2657},[1108,6050,1198],{"class":1197},[1108,6052,6053],{"class":1201}," UserRegistrationView",[1108,6055,1205],{"class":1136},[1108,6057,6058],{"class":3340},"PluginAwareView",[1108,6060,1211],{"class":1136},[1108,6062,6063,6065,6068],{"class":1110,"line":2683},[1108,6064,1218],{"class":1217},[1108,6066,6067],{"class":1221},"User registration with plugin hooks",[1108,6069,1225],{"class":1217},[1108,6071,6072],{"class":1110,"line":2688},[1108,6073,1231],{"class":1125},[1108,6075,6076,6078,6081,6083,6085,6087,6089],{"class":1110,"line":2737},[1108,6077,1256],{"class":1197},[1108,6079,6080],{"class":1249}," post",[1108,6082,1205],{"class":1136},[1108,6084,1265],{"class":1264},[1108,6086,1137],{"class":1136},[1108,6088,5795],{"class":1486},[1108,6090,1211],{"class":1136},[1108,6092,6093,6095,6098],{"class":1110,"line":2747},[1108,6094,1283],{"class":1217},[1108,6096,6097],{"class":1221},"Handle user registration",[1108,6099,1225],{"class":1217},[1108,6101,6102],{"class":1110,"line":2757},[1108,6103,6104],{"class":1114},"        # Validate user data\n",[1108,6106,6107,6110,6112,6114,6116,6120,6122,6124,6126,6128,6130,6132],{"class":1110,"line":2774},[1108,6108,6109],{"class":1125},"        email ",[1108,6111,2101],{"class":1136},[1108,6113,5795],{"class":1125},[1108,6115,1627],{"class":1136},[1108,6117,6119],{"class":6118},"sFGJz","POST",[1108,6121,1627],{"class":1136},[1108,6123,3552],{"class":1809},[1108,6125,1205],{"class":1136},[1108,6127,3016],{"class":1399},[1108,6129,3825],{"class":1801},[1108,6131,3016],{"class":1399},[1108,6133,1823],{"class":1136},[1108,6135,6136,6139,6141,6143,6145,6147,6149,6151,6153,6155,6157,6159],{"class":1110,"line":2797},[1108,6137,6138],{"class":1125},"        password ",[1108,6140,2101],{"class":1136},[1108,6142,5795],{"class":1125},[1108,6144,1627],{"class":1136},[1108,6146,6119],{"class":6118},[1108,6148,1627],{"class":1136},[1108,6150,3552],{"class":1809},[1108,6152,1205],{"class":1136},[1108,6154,3016],{"class":1399},[1108,6156,3643],{"class":1801},[1108,6158,3016],{"class":1399},[1108,6160,1823],{"class":1136},[1108,6162,6163],{"class":1110,"line":2805},[1108,6164,1829],{"class":1125},[1108,6166,6167],{"class":1110,"line":2830},[1108,6168,6169],{"class":1114},"        # Create user\n",[1108,6171,6172,6175,6177,6180,6182,6185,6187,6190],{"class":1110,"line":2847},[1108,6173,6174],{"class":1125},"        user ",[1108,6176,2101],{"class":1136},[1108,6178,6179],{"class":1125}," User",[1108,6181,1627],{"class":1136},[1108,6183,6184],{"class":1630},"objects",[1108,6186,1627],{"class":1136},[1108,6188,6189],{"class":1809},"create_user",[1108,6191,4852],{"class":1136},[1108,6193,6194,6197,6199,6201],{"class":1110,"line":2864},[1108,6195,6196],{"class":5059},"            username",[1108,6198,2101],{"class":1136},[1108,6200,3825],{"class":1809},[1108,6202,6203],{"class":1136},",\n",[1108,6205,6206,6209,6211,6213],{"class":1110,"line":2870},[1108,6207,6208],{"class":5059},"            email",[1108,6210,2101],{"class":1136},[1108,6212,3825],{"class":1809},[1108,6214,6203],{"class":1136},[1108,6216,6217,6220,6222],{"class":1110,"line":2903},[1108,6218,6219],{"class":5059},"            password",[1108,6221,2101],{"class":1136},[1108,6223,6224],{"class":1809},"password\n",[1108,6226,6227],{"class":1110,"line":2911},[1108,6228,6229],{"class":1136},"        )\n",[1108,6231,6232],{"class":1110,"line":2916},[1108,6233,1829],{"class":1125},[1108,6235,6236],{"class":1110,"line":2944},[1108,6237,6238],{"class":1114},"        # Trigger plugin hook\n",[1108,6240,6241,6243,6245,6247,6249,6251,6253,6255,6257,6259],{"class":1110,"line":2954},[1108,6242,5828],{"class":1125},[1108,6244,1627],{"class":1136},[1108,6246,5833],{"class":1809},[1108,6248,1205],{"class":1136},[1108,6250,3016],{"class":1399},[1108,6252,3770],{"class":1801},[1108,6254,3016],{"class":1399},[1108,6256,1137],{"class":1136},[1108,6258,3791],{"class":1809},[1108,6260,1823],{"class":1136},[1108,6262,6263],{"class":1110,"line":2973},[1108,6264,1829],{"class":1125},[1108,6266,6267,6269,6272,6275,6277,6280,6282,6284,6286,6288,6290,6292,6294,6296,6298,6300,6302,6305,6307],{"class":1110,"line":2995},[1108,6268,1396],{"class":1121},[1108,6270,6271],{"class":1809}," JsonResponse",[1108,6273,6274],{"class":1136},"({",[1108,6276,3016],{"class":1399},[1108,6278,6279],{"class":1801},"user_id",[1108,6281,3016],{"class":1399},[1108,6283,1490],{"class":1136},[1108,6285,3791],{"class":1809},[1108,6287,1627],{"class":1136},[1108,6289,3911],{"class":1630},[1108,6291,1137],{"class":1136},[1108,6293,3010],{"class":1399},[1108,6295,5445],{"class":1801},[1108,6297,3016],{"class":1399},[1108,6299,1490],{"class":1136},[1108,6301,3010],{"class":1399},[1108,6303,6304],{"class":1801},"created",[1108,6306,3016],{"class":1399},[1108,6308,6309],{"class":1136},"})\n",[1108,6311,6312],{"class":1110,"line":3021},[1108,6313,1191],{"emptyLinePlaceholder":1190},[1108,6315,6316],{"class":1110,"line":3047},[1108,6317,6318],{"class":1114},"# Settings configuration\n",[1108,6320,6321],{"class":1110,"line":3052},[1108,6322,6323],{"class":1114},"# settings.py\n",[1108,6325,6326,6328,6330],{"class":1110,"line":3080},[1108,6327,4638],{"class":1132},[1108,6329,1649],{"class":1136},[1108,6331,6332],{"class":1136}," {\n",[1108,6334,6335,6338,6340,6342,6344],{"class":1110,"line":3090},[1108,6336,6337],{"class":1399},"    '",[1108,6339,3394],{"class":1801},[1108,6341,3016],{"class":1399},[1108,6343,1490],{"class":1136},[1108,6345,6332],{"class":1136},[1108,6347,6348,6351,6353,6355,6357,6359,6362,6364],{"class":1110,"line":3117},[1108,6349,6350],{"class":1399},"        '",[1108,6352,4702],{"class":1801},[1108,6354,3016],{"class":1399},[1108,6356,1490],{"class":1136},[1108,6358,3010],{"class":1399},[1108,6360,6361],{"class":1801},"plugins.email_plugin",[1108,6363,3016],{"class":1399},[1108,6365,6203],{"class":1136},[1108,6367,6368,6370,6372,6374,6376,6378,6381,6383],{"class":1110,"line":3137},[1108,6369,6350],{"class":1399},[1108,6371,1198],{"class":1801},[1108,6373,3016],{"class":1399},[1108,6375,1490],{"class":1136},[1108,6377,3010],{"class":1399},[1108,6379,6380],{"class":1801},"EmailNotificationPlugin",[1108,6382,3016],{"class":1399},[1108,6384,6203],{"class":1136},[1108,6386,6387,6389,6391,6393,6395],{"class":1110,"line":3154},[1108,6388,6350],{"class":1399},[1108,6390,4631],{"class":1801},[1108,6392,3016],{"class":1399},[1108,6394,1490],{"class":1136},[1108,6396,6332],{"class":1136},[1108,6398,6399,6402,6404,6406,6408,6410,6413,6415],{"class":1110,"line":3203},[1108,6400,6401],{"class":1399},"            '",[1108,6403,3543],{"class":1801},[1108,6405,3016],{"class":1399},[1108,6407,1490],{"class":1136},[1108,6409,3010],{"class":1399},[1108,6411,6412],{"class":1801},"smtp.gmail.com",[1108,6414,3016],{"class":1399},[1108,6416,6203],{"class":1136},[1108,6418,6419,6421,6423,6425,6427,6429],{"class":1110,"line":3209},[1108,6420,6401],{"class":1399},[1108,6422,3581],{"class":1801},[1108,6424,3016],{"class":1399},[1108,6426,1490],{"class":1136},[1108,6428,3603],{"class":3602},[1108,6430,6203],{"class":1136},[1108,6432,6433,6435,6437,6439,6441,6443,6446,6448],{"class":1110,"line":3214},[1108,6434,6401],{"class":1399},[1108,6436,3615],{"class":1801},[1108,6438,3016],{"class":1399},[1108,6440,1490],{"class":1136},[1108,6442,3010],{"class":1399},[1108,6444,6445],{"class":1801},"your-email@gmail.com",[1108,6447,3016],{"class":1399},[1108,6449,6203],{"class":1136},[1108,6451,6452,6454,6456,6458,6460,6462,6465,6467],{"class":1110,"line":3220},[1108,6453,6401],{"class":1399},[1108,6455,3643],{"class":1801},[1108,6457,3016],{"class":1399},[1108,6459,1490],{"class":1136},[1108,6461,3010],{"class":1399},[1108,6463,6464],{"class":1801},"your-password",[1108,6466,3016],{"class":1399},[1108,6468,6203],{"class":1136},[1108,6470,6471],{"class":1110,"line":3239},[1108,6472,6473],{"class":1136},"        }\n",[1108,6475,6476],{"class":1110,"line":3249},[1108,6477,6478],{"class":1136},"    },\n",[1108,6480,6481,6483,6485,6487,6489],{"class":1110,"line":3264},[1108,6482,6337],{"class":1399},[1108,6484,3992],{"class":1801},[1108,6486,3016],{"class":1399},[1108,6488,1490],{"class":1136},[1108,6490,6332],{"class":1136},[1108,6492,6493,6495,6497,6499,6501,6503,6506,6508],{"class":1110,"line":3279},[1108,6494,6350],{"class":1399},[1108,6496,4702],{"class":1801},[1108,6498,3016],{"class":1399},[1108,6500,1490],{"class":1136},[1108,6502,3010],{"class":1399},[1108,6504,6505],{"class":1801},"plugins.slack_plugin",[1108,6507,3016],{"class":1399},[1108,6509,6203],{"class":1136},[1108,6511,6512,6514,6516,6518,6520,6522,6525,6527],{"class":1110,"line":3287},[1108,6513,6350],{"class":1399},[1108,6515,1198],{"class":1801},[1108,6517,3016],{"class":1399},[1108,6519,1490],{"class":1136},[1108,6521,3010],{"class":1399},[1108,6523,6524],{"class":1801},"SlackNotificationPlugin",[1108,6526,3016],{"class":1399},[1108,6528,6203],{"class":1136},[1108,6530,6531,6533,6535,6537,6539],{"class":1110,"line":3296},[1108,6532,6350],{"class":1399},[1108,6534,4631],{"class":1801},[1108,6536,3016],{"class":1399},[1108,6538,1490],{"class":1136},[1108,6540,6332],{"class":1136},[1108,6542,6543,6545,6547,6549,6551,6553,6556,6558],{"class":1110,"line":3301},[1108,6544,6401],{"class":1399},[1108,6546,4139],{"class":1801},[1108,6548,3016],{"class":1399},[1108,6550,1490],{"class":1136},[1108,6552,3010],{"class":1399},[1108,6554,6555],{"class":1801},"https://hooks.slack.com/services/...",[1108,6557,3016],{"class":1399},[1108,6559,6203],{"class":1136},[1108,6561,6562,6564,6566,6568,6570,6572,6575,6577],{"class":1110,"line":3307},[1108,6563,6401],{"class":1399},[1108,6565,4167],{"class":1801},[1108,6567,3016],{"class":1399},[1108,6569,1490],{"class":1136},[1108,6571,3010],{"class":1399},[1108,6573,6574],{"class":1801},"#notifications",[1108,6576,3016],{"class":1399},[1108,6578,6203],{"class":1136},[1108,6580,6581],{"class":1110,"line":3319},[1108,6582,6473],{"class":1136},[1108,6584,6585],{"class":1110,"line":3324},[1108,6586,6587],{"class":1136},"    }\n",[1108,6589,6590],{"class":1110,"line":3330},[1108,6591,6592],{"class":1136},"}\n",[1030,6594,6596],{"id":6595},"advanced-plugin-features","Advanced Plugin Features",[1038,6598,6600],{"id":6599},"plugin-configuration-and-settings","Plugin Configuration and Settings",[1098,6602,6604],{"className":1100,"code":6603,"language":1102,"meta":1103,"style":1103},"# Advanced plugin with configuration UI\nclass ConfigurablePlugin(PluginInterface):\n    \"\"\"Plugin with configuration interface\"\"\"\n    \n    def get_config_schema(self) -> Dict[str, Any]:\n        \"\"\"Return configuration schema for UI generation\"\"\"\n        return {\n            'type': 'object',\n            'properties': {\n                'api_key': {\n                    'type': 'string',\n                    'title': 'API Key',\n                    'description': 'API key for external service'\n                },\n                'timeout': {\n                    'type': 'integer',\n                    'title': 'Timeout (seconds)',\n                    'default': 30,\n                    'minimum': 1,\n                    'maximum': 300\n                },\n                'enabled_features': {\n                    'type': 'array',\n                    'title': 'Enabled Features',\n                    'items': {\n                        'type': 'string',\n                        'enum': ['feature1', 'feature2', 'feature3']\n                    }\n                }\n            },\n            'required': ['api_key']\n        }\n    \n    def validate_config(self, config: Dict[str, Any]) -> List[str]:\n        \"\"\"Validate configuration and return errors\"\"\"\n        errors = []\n        \n        if not config.get('api_key'):\n            errors.append('API key is required')\n        \n        timeout = config.get('timeout', 30)\n        if not isinstance(timeout, int) or timeout \u003C 1:\n            errors.append('Timeout must be a positive integer')\n        \n        return errors\n\n# Plugin with database models\nfrom django.db import models\n\nclass PluginModel(models.Model):\n    \"\"\"Base model for plugin data\"\"\"\n    \n    plugin_name = models.CharField(max_length=100)\n    created_at = models.DateTimeField(auto_now_add=True)\n    updated_at = models.DateTimeField(auto_now=True)\n    \n    class Meta:\n        abstract = True\n\nclass PluginSetting(PluginModel):\n    \"\"\"Model for storing plugin settings\"\"\"\n    \n    key = models.CharField(max_length=100)\n    value = models.JSONField()\n    \n    class Meta:\n        unique_together = ['plugin_name', 'key']\n\nclass DatabasePlugin(PluginInterface):\n    \"\"\"Plugin that uses database models\"\"\"\n    \n    @property\n    def name(self) -> str:\n        return \"database_plugin\"\n    \n    @property\n    def version(self) -> str:\n        return \"1.0.0\"\n    \n    def initialize(self, config: Dict[str, Any]) -> None:\n        \"\"\"Initialize with database settings\"\"\"\n        # Store settings in database\n        for key, value in config.items():\n            PluginSetting.objects.update_or_create(\n                plugin_name=self.name,\n                key=key,\n                defaults={'value': value}\n            )\n    \n    def get_setting(self, key: str, default=None):\n        \"\"\"Get setting from database\"\"\"\n        try:\n            setting = PluginSetting.objects.get(plugin_name=self.name, key=key)\n            return setting.value\n        except PluginSetting.DoesNotExist:\n            return default\n    \n    def set_setting(self, key: str, value):\n        \"\"\"Set setting in database\"\"\"\n        PluginSetting.objects.update_or_create(\n            plugin_name=self.name,\n            key=key,\n            defaults={'value': value}\n        )\n    \n    def cleanup(self) -> None:\n        \"\"\"Cleanup database settings\"\"\"\n        PluginSetting.objects.filter(plugin_name=self.name).delete()\n",[1105,6605,6606,6611,6624,6633,6637,6664,6673,6679,6699,6712,6726,6746,6766,6784,6789,6802,6821,6840,6856,6872,6886,6890,6903,6922,6941,6953,6972,7013,7018,7023,7028,7049,7053,7057,7096,7105,7114,7118,7140,7160,7164,7191,7224,7243,7247,7254,7258,7263,7279,7283,7302,7311,7315,7342,7368,7392,7396,7406,7416,7420,7434,7443,7447,7470,7486,7490,7498,7524,7528,7541,7550,7554,7560,7578,7589,7593,7599,7617,7627,7631,7665,7674,7679,7701,7717,7732,7743,7765,7770,7774,7805,7814,7820,7859,7871,7884,7891,7895,7920,7929,7944,7959,7970,7989,7993,7997,8015,8024],{"__ignoreMap":1103},[1108,6607,6608],{"class":1110,"line":1111},[1108,6609,6610],{"class":1114},"# Advanced plugin with configuration UI\n",[1108,6612,6613,6615,6618,6620,6622],{"class":1110,"line":1118},[1108,6614,1198],{"class":1197},[1108,6616,6617],{"class":1201}," ConfigurablePlugin",[1108,6619,1205],{"class":1136},[1108,6621,2525],{"class":3340},[1108,6623,1211],{"class":1136},[1108,6625,6626,6628,6631],{"class":1110,"line":1143},[1108,6627,1218],{"class":1217},[1108,6629,6630],{"class":1221},"Plugin with configuration interface",[1108,6632,1225],{"class":1217},[1108,6634,6635],{"class":1110,"line":1171},[1108,6636,1231],{"class":1125},[1108,6638,6639,6641,6644,6646,6648,6650,6652,6654,6656,6658,6660,6662],{"class":1110,"line":1179},[1108,6640,1256],{"class":1197},[1108,6642,6643],{"class":1249}," get_config_schema",[1108,6645,1205],{"class":1136},[1108,6647,1265],{"class":1264},[1108,6649,1268],{"class":1136},[1108,6651,1271],{"class":1136},[1108,6653,1153],{"class":1125},[1108,6655,1433],{"class":1136},[1108,6657,1436],{"class":1240},[1108,6659,1137],{"class":1136},[1108,6661,1163],{"class":1125},[1108,6663,1439],{"class":1136},[1108,6665,6666,6668,6671],{"class":1110,"line":1187},[1108,6667,1283],{"class":1217},[1108,6669,6670],{"class":1221},"Return configuration schema for UI generation",[1108,6672,1225],{"class":1217},[1108,6674,6675,6677],{"class":1110,"line":1194},[1108,6676,1396],{"class":1121},[1108,6678,6332],{"class":1136},[1108,6680,6681,6683,6686,6688,6690,6692,6695,6697],{"class":1110,"line":1214},[1108,6682,6401],{"class":1399},[1108,6684,6685],{"class":1801},"type",[1108,6687,3016],{"class":1399},[1108,6689,1490],{"class":1136},[1108,6691,3010],{"class":1399},[1108,6693,6694],{"class":1801},"object",[1108,6696,3016],{"class":1399},[1108,6698,6203],{"class":1136},[1108,6700,6701,6703,6706,6708,6710],{"class":1110,"line":1228},[1108,6702,6401],{"class":1399},[1108,6704,6705],{"class":1801},"properties",[1108,6707,3016],{"class":1399},[1108,6709,1490],{"class":1136},[1108,6711,6332],{"class":1136},[1108,6713,6714,6717,6720,6722,6724],{"class":1110,"line":1234},[1108,6715,6716],{"class":1399},"                '",[1108,6718,6719],{"class":1801},"api_key",[1108,6721,3016],{"class":1399},[1108,6723,1490],{"class":1136},[1108,6725,6332],{"class":1136},[1108,6727,6728,6731,6733,6735,6737,6739,6742,6744],{"class":1110,"line":1244},[1108,6729,6730],{"class":1399},"                    '",[1108,6732,6685],{"class":1801},[1108,6734,3016],{"class":1399},[1108,6736,1490],{"class":1136},[1108,6738,3010],{"class":1399},[1108,6740,6741],{"class":1801},"string",[1108,6743,3016],{"class":1399},[1108,6745,6203],{"class":1136},[1108,6747,6748,6750,6753,6755,6757,6759,6762,6764],{"class":1110,"line":1253},[1108,6749,6730],{"class":1399},[1108,6751,6752],{"class":1801},"title",[1108,6754,3016],{"class":1399},[1108,6756,1490],{"class":1136},[1108,6758,3010],{"class":1399},[1108,6760,6761],{"class":1801},"API Key",[1108,6763,3016],{"class":1399},[1108,6765,6203],{"class":1136},[1108,6767,6768,6770,6773,6775,6777,6779,6782],{"class":1110,"line":1280},[1108,6769,6730],{"class":1399},[1108,6771,6772],{"class":1801},"description",[1108,6774,3016],{"class":1399},[1108,6776,1490],{"class":1136},[1108,6778,3010],{"class":1399},[1108,6780,6781],{"class":1801},"API key for external service",[1108,6783,4554],{"class":1399},[1108,6785,6786],{"class":1110,"line":1291},[1108,6787,6788],{"class":1136},"                },\n",[1108,6790,6791,6793,6796,6798,6800],{"class":1110,"line":1297},[1108,6792,6716],{"class":1399},[1108,6794,6795],{"class":1801},"timeout",[1108,6797,3016],{"class":1399},[1108,6799,1490],{"class":1136},[1108,6801,6332],{"class":1136},[1108,6803,6804,6806,6808,6810,6812,6814,6817,6819],{"class":1110,"line":1302},[1108,6805,6730],{"class":1399},[1108,6807,6685],{"class":1801},[1108,6809,3016],{"class":1399},[1108,6811,1490],{"class":1136},[1108,6813,3010],{"class":1399},[1108,6815,6816],{"class":1801},"integer",[1108,6818,3016],{"class":1399},[1108,6820,6203],{"class":1136},[1108,6822,6823,6825,6827,6829,6831,6833,6836,6838],{"class":1110,"line":1309},[1108,6824,6730],{"class":1399},[1108,6826,6752],{"class":1801},[1108,6828,3016],{"class":1399},[1108,6830,1490],{"class":1136},[1108,6832,3010],{"class":1399},[1108,6834,6835],{"class":1801},"Timeout (seconds)",[1108,6837,3016],{"class":1399},[1108,6839,6203],{"class":1136},[1108,6841,6842,6844,6847,6849,6851,6854],{"class":1110,"line":1316},[1108,6843,6730],{"class":1399},[1108,6845,6846],{"class":1801},"default",[1108,6848,3016],{"class":1399},[1108,6850,1490],{"class":1136},[1108,6852,6853],{"class":3602}," 30",[1108,6855,6203],{"class":1136},[1108,6857,6858,6860,6863,6865,6867,6870],{"class":1110,"line":1336},[1108,6859,6730],{"class":1399},[1108,6861,6862],{"class":1801},"minimum",[1108,6864,3016],{"class":1399},[1108,6866,1490],{"class":1136},[1108,6868,6869],{"class":3602}," 1",[1108,6871,6203],{"class":1136},[1108,6873,6874,6876,6879,6881,6883],{"class":1110,"line":1346},[1108,6875,6730],{"class":1399},[1108,6877,6878],{"class":1801},"maximum",[1108,6880,3016],{"class":1399},[1108,6882,1490],{"class":1136},[1108,6884,6885],{"class":3602}," 300\n",[1108,6887,6888],{"class":1110,"line":1351},[1108,6889,6788],{"class":1136},[1108,6891,6892,6894,6897,6899,6901],{"class":1110,"line":1356},[1108,6893,6716],{"class":1399},[1108,6895,6896],{"class":1801},"enabled_features",[1108,6898,3016],{"class":1399},[1108,6900,1490],{"class":1136},[1108,6902,6332],{"class":1136},[1108,6904,6905,6907,6909,6911,6913,6915,6918,6920],{"class":1110,"line":1363},[1108,6906,6730],{"class":1399},[1108,6908,6685],{"class":1801},[1108,6910,3016],{"class":1399},[1108,6912,1490],{"class":1136},[1108,6914,3010],{"class":1399},[1108,6916,6917],{"class":1801},"array",[1108,6919,3016],{"class":1399},[1108,6921,6203],{"class":1136},[1108,6923,6924,6926,6928,6930,6932,6934,6937,6939],{"class":1110,"line":1383},[1108,6925,6730],{"class":1399},[1108,6927,6752],{"class":1801},[1108,6929,3016],{"class":1399},[1108,6931,1490],{"class":1136},[1108,6933,3010],{"class":1399},[1108,6935,6936],{"class":1801},"Enabled Features",[1108,6938,3016],{"class":1399},[1108,6940,6203],{"class":1136},[1108,6942,6943,6945,6947,6949,6951],{"class":1110,"line":1393},[1108,6944,6730],{"class":1399},[1108,6946,3112],{"class":1801},[1108,6948,3016],{"class":1399},[1108,6950,1490],{"class":1136},[1108,6952,6332],{"class":1136},[1108,6954,6955,6958,6960,6962,6964,6966,6968,6970],{"class":1110,"line":1403},[1108,6956,6957],{"class":1399},"                        '",[1108,6959,6685],{"class":1801},[1108,6961,3016],{"class":1399},[1108,6963,1490],{"class":1136},[1108,6965,3010],{"class":1399},[1108,6967,6741],{"class":1801},[1108,6969,3016],{"class":1399},[1108,6971,6203],{"class":1136},[1108,6973,6974,6976,6979,6981,6983,6986,6988,6991,6993,6995,6997,7000,7002,7004,7006,7009,7011],{"class":1110,"line":1408},[1108,6975,6957],{"class":1399},[1108,6977,6978],{"class":1801},"enum",[1108,6980,3016],{"class":1399},[1108,6982,1490],{"class":1136},[1108,6984,6985],{"class":1136}," [",[1108,6987,3016],{"class":1399},[1108,6989,6990],{"class":1801},"feature1",[1108,6992,3016],{"class":1399},[1108,6994,1137],{"class":1136},[1108,6996,3010],{"class":1399},[1108,6998,6999],{"class":1801},"feature2",[1108,7001,3016],{"class":1399},[1108,7003,1137],{"class":1136},[1108,7005,3010],{"class":1399},[1108,7007,7008],{"class":1801},"feature3",[1108,7010,3016],{"class":1399},[1108,7012,2114],{"class":1136},[1108,7014,7015],{"class":1110,"line":1415},[1108,7016,7017],{"class":1136},"                    }\n",[1108,7019,7020],{"class":1110,"line":1442},[1108,7021,7022],{"class":1136},"                }\n",[1108,7024,7025],{"class":1110,"line":1452},[1108,7026,7027],{"class":1136},"            },\n",[1108,7029,7030,7032,7035,7037,7039,7041,7043,7045,7047],{"class":1110,"line":1460},[1108,7031,6401],{"class":1399},[1108,7033,7034],{"class":1801},"required",[1108,7036,3016],{"class":1399},[1108,7038,1490],{"class":1136},[1108,7040,6985],{"class":1136},[1108,7042,3016],{"class":1399},[1108,7044,6719],{"class":1801},[1108,7046,3016],{"class":1399},[1108,7048,2114],{"class":1136},[1108,7050,7051],{"class":1110,"line":1465},[1108,7052,6473],{"class":1136},[1108,7054,7055],{"class":1110,"line":1472},[1108,7056,1231],{"class":1125},[1108,7058,7059,7061,7064,7066,7068,7070,7072,7074,7076,7078,7080,7082,7084,7086,7088,7090,7092,7094],{"class":1110,"line":1514},[1108,7060,1256],{"class":1197},[1108,7062,7063],{"class":1249}," validate_config",[1108,7065,1205],{"class":1136},[1108,7067,1265],{"class":1264},[1108,7069,1137],{"class":1136},[1108,7071,1487],{"class":1486},[1108,7073,1490],{"class":1136},[1108,7075,1153],{"class":1125},[1108,7077,1433],{"class":1136},[1108,7079,1436],{"class":1240},[1108,7081,1137],{"class":1136},[1108,7083,1163],{"class":1125},[1108,7085,1503],{"class":1136},[1108,7087,1271],{"class":1136},[1108,7089,1158],{"class":1125},[1108,7091,1433],{"class":1136},[1108,7093,1436],{"class":1240},[1108,7095,1439],{"class":1136},[1108,7097,7098,7100,7103],{"class":1110,"line":1524},[1108,7099,1283],{"class":1217},[1108,7101,7102],{"class":1221},"Validate configuration and return errors",[1108,7104,1225],{"class":1217},[1108,7106,7107,7110,7112],{"class":1110,"line":1529},[1108,7108,7109],{"class":1125},"        errors ",[1108,7111,2101],{"class":1136},[1108,7113,1457],{"class":1136},[1108,7115,7116],{"class":1110,"line":1534},[1108,7117,1829],{"class":1125},[1108,7119,7120,7122,7124,7126,7128,7130,7132,7134,7136,7138],{"class":1110,"line":1541},[1108,7121,1764],{"class":1121},[1108,7123,3160],{"class":1774},[1108,7125,1487],{"class":1125},[1108,7127,1627],{"class":1136},[1108,7129,3552],{"class":1809},[1108,7131,1205],{"class":1136},[1108,7133,3016],{"class":1399},[1108,7135,6719],{"class":1801},[1108,7137,3016],{"class":1399},[1108,7139,1211],{"class":1136},[1108,7141,7142,7145,7147,7149,7151,7153,7156,7158],{"class":1110,"line":1561},[1108,7143,7144],{"class":1125},"            errors",[1108,7146,1627],{"class":1136},[1108,7148,2673],{"class":1809},[1108,7150,1205],{"class":1136},[1108,7152,3016],{"class":1399},[1108,7154,7155],{"class":1801},"API key is required",[1108,7157,3016],{"class":1399},[1108,7159,1823],{"class":1136},[1108,7161,7162],{"class":1110,"line":1571},[1108,7163,1829],{"class":1125},[1108,7165,7166,7169,7171,7173,7175,7177,7179,7181,7183,7185,7187,7189],{"class":1110,"line":1576},[1108,7167,7168],{"class":1125},"        timeout ",[1108,7170,2101],{"class":1136},[1108,7172,1487],{"class":1125},[1108,7174,1627],{"class":1136},[1108,7176,3552],{"class":1809},[1108,7178,1205],{"class":1136},[1108,7180,3016],{"class":1399},[1108,7182,6795],{"class":1801},[1108,7184,3016],{"class":1399},[1108,7186,1137],{"class":1136},[1108,7188,6853],{"class":3602},[1108,7190,1823],{"class":1136},[1108,7192,7193,7195,7197,7200,7202,7204,7206,7209,7211,7214,7217,7220,7222],{"class":1110,"line":1581},[1108,7194,1764],{"class":1121},[1108,7196,3160],{"class":1774},[1108,7198,7199],{"class":1611}," isinstance",[1108,7201,1205],{"class":1136},[1108,7203,6795],{"class":1809},[1108,7205,1137],{"class":1136},[1108,7207,7208],{"class":1240}," int",[1108,7210,1268],{"class":1136},[1108,7212,7213],{"class":1774}," or",[1108,7215,7216],{"class":1125}," timeout ",[1108,7218,7219],{"class":1774},"\u003C",[1108,7221,6869],{"class":3602},[1108,7223,1277],{"class":1136},[1108,7225,7226,7228,7230,7232,7234,7236,7239,7241],{"class":1110,"line":1591},[1108,7227,7144],{"class":1125},[1108,7229,1627],{"class":1136},[1108,7231,2673],{"class":1809},[1108,7233,1205],{"class":1136},[1108,7235,3016],{"class":1399},[1108,7237,7238],{"class":1801},"Timeout must be a positive integer",[1108,7240,3016],{"class":1399},[1108,7242,1823],{"class":1136},[1108,7244,7245],{"class":1110,"line":1601},[1108,7246,1829],{"class":1125},[1108,7248,7249,7251],{"class":1110,"line":1606},[1108,7250,1396],{"class":1121},[1108,7252,7253],{"class":1125}," errors\n",[1108,7255,7256],{"class":1110,"line":1621},[1108,7257,1191],{"emptyLinePlaceholder":1190},[1108,7259,7260],{"class":1110,"line":1655},[1108,7261,7262],{"class":1114},"# Plugin with database models\n",[1108,7264,7265,7267,7269,7271,7274,7276],{"class":1110,"line":1683},[1108,7266,1122],{"class":1121},[1108,7268,4457],{"class":1125},[1108,7270,1627],{"class":1136},[1108,7272,7273],{"class":1125},"db ",[1108,7275,1129],{"class":1121},[1108,7277,7278],{"class":1125}," models\n",[1108,7280,7281],{"class":1110,"line":1717},[1108,7282,1191],{"emptyLinePlaceholder":1190},[1108,7284,7285,7287,7290,7292,7295,7297,7300],{"class":1110,"line":1722},[1108,7286,1198],{"class":1197},[1108,7288,7289],{"class":1201}," PluginModel",[1108,7291,1205],{"class":1136},[1108,7293,7294],{"class":3340},"models",[1108,7296,1627],{"class":1136},[1108,7298,7299],{"class":3340},"Model",[1108,7301,1211],{"class":1136},[1108,7303,7304,7306,7309],{"class":1110,"line":1751},[1108,7305,1218],{"class":1217},[1108,7307,7308],{"class":1221},"Base model for plugin data",[1108,7310,1225],{"class":1217},[1108,7312,7313],{"class":1110,"line":1761},[1108,7314,1231],{"class":1125},[1108,7316,7317,7320,7322,7325,7327,7330,7332,7335,7337,7340],{"class":1110,"line":1787},[1108,7318,7319],{"class":1125},"    plugin_name ",[1108,7321,2101],{"class":1136},[1108,7323,7324],{"class":1125}," models",[1108,7326,1627],{"class":1136},[1108,7328,7329],{"class":1809},"CharField",[1108,7331,1205],{"class":1136},[1108,7333,7334],{"class":5059},"max_length",[1108,7336,2101],{"class":1136},[1108,7338,7339],{"class":3602},"100",[1108,7341,1823],{"class":1136},[1108,7343,7344,7347,7349,7351,7353,7356,7358,7361,7363,7366],{"class":1110,"line":1826},[1108,7345,7346],{"class":1125},"    created_at ",[1108,7348,2101],{"class":1136},[1108,7350,7324],{"class":1125},[1108,7352,1627],{"class":1136},[1108,7354,7355],{"class":1809},"DateTimeField",[1108,7357,1205],{"class":1136},[1108,7359,7360],{"class":5059},"auto_now_add",[1108,7362,2101],{"class":1136},[1108,7364,7365],{"class":1508},"True",[1108,7367,1823],{"class":1136},[1108,7369,7370,7373,7375,7377,7379,7381,7383,7386,7388,7390],{"class":1110,"line":1832},[1108,7371,7372],{"class":1125},"    updated_at ",[1108,7374,2101],{"class":1136},[1108,7376,7324],{"class":1125},[1108,7378,1627],{"class":1136},[1108,7380,7355],{"class":1809},[1108,7382,1205],{"class":1136},[1108,7384,7385],{"class":5059},"auto_now",[1108,7387,2101],{"class":1136},[1108,7389,7365],{"class":1508},[1108,7391,1823],{"class":1136},[1108,7393,7394],{"class":1110,"line":1838},[1108,7395,1231],{"class":1125},[1108,7397,7398,7401,7404],{"class":1110,"line":1859},[1108,7399,7400],{"class":1197},"    class",[1108,7402,7403],{"class":1201}," Meta",[1108,7405,1277],{"class":1136},[1108,7407,7408,7411,7413],{"class":1110,"line":1880},[1108,7409,7410],{"class":1125},"        abstract ",[1108,7412,2101],{"class":1136},[1108,7414,7415],{"class":1508}," True\n",[1108,7417,7418],{"class":1110,"line":1919},[1108,7419,1191],{"emptyLinePlaceholder":1190},[1108,7421,7422,7424,7427,7429,7432],{"class":1110,"line":1924},[1108,7423,1198],{"class":1197},[1108,7425,7426],{"class":1201}," PluginSetting",[1108,7428,1205],{"class":1136},[1108,7430,7431],{"class":3340},"PluginModel",[1108,7433,1211],{"class":1136},[1108,7435,7436,7438,7441],{"class":1110,"line":1948},[1108,7437,1218],{"class":1217},[1108,7439,7440],{"class":1221},"Model for storing plugin settings",[1108,7442,1225],{"class":1217},[1108,7444,7445],{"class":1110,"line":1953},[1108,7446,1231],{"class":1125},[1108,7448,7449,7452,7454,7456,7458,7460,7462,7464,7466,7468],{"class":1110,"line":2004},[1108,7450,7451],{"class":1125},"    key ",[1108,7453,2101],{"class":1136},[1108,7455,7324],{"class":1125},[1108,7457,1627],{"class":1136},[1108,7459,7329],{"class":1809},[1108,7461,1205],{"class":1136},[1108,7463,7334],{"class":5059},[1108,7465,2101],{"class":1136},[1108,7467,7339],{"class":3602},[1108,7469,1823],{"class":1136},[1108,7471,7472,7475,7477,7479,7481,7484],{"class":1110,"line":2014},[1108,7473,7474],{"class":1125},"    value ",[1108,7476,2101],{"class":1136},[1108,7478,7324],{"class":1125},[1108,7480,1627],{"class":1136},[1108,7482,7483],{"class":1809},"JSONField",[1108,7485,2447],{"class":1136},[1108,7487,7488],{"class":1110,"line":2034},[1108,7489,1231],{"class":1125},[1108,7491,7492,7494,7496],{"class":1110,"line":2059},[1108,7493,7400],{"class":1197},[1108,7495,7403],{"class":1201},[1108,7497,1277],{"class":1136},[1108,7499,7500,7503,7505,7507,7509,7511,7513,7515,7517,7520,7522],{"class":1110,"line":2064},[1108,7501,7502],{"class":1125},"        unique_together ",[1108,7504,2101],{"class":1136},[1108,7506,6985],{"class":1136},[1108,7508,3016],{"class":1399},[1108,7510,2049],{"class":1801},[1108,7512,3016],{"class":1399},[1108,7514,1137],{"class":1136},[1108,7516,3010],{"class":1399},[1108,7518,7519],{"class":1801},"key",[1108,7521,3016],{"class":1399},[1108,7523,2114],{"class":1136},[1108,7525,7526],{"class":1110,"line":2081},[1108,7527,1191],{"emptyLinePlaceholder":1190},[1108,7529,7530,7532,7535,7537,7539],{"class":1110,"line":2090},[1108,7531,1198],{"class":1197},[1108,7533,7534],{"class":1201}," DatabasePlugin",[1108,7536,1205],{"class":1136},[1108,7538,2525],{"class":3340},[1108,7540,1211],{"class":1136},[1108,7542,7543,7545,7548],{"class":1110,"line":2095},[1108,7544,1218],{"class":1217},[1108,7546,7547],{"class":1221},"Plugin that uses database models",[1108,7549,1225],{"class":1217},[1108,7551,7552],{"class":1110,"line":2117},[1108,7553,1231],{"class":1125},[1108,7555,7556,7558],{"class":1110,"line":2122},[1108,7557,1237],{"class":1136},[1108,7559,1241],{"class":1240},[1108,7561,7562,7564,7566,7568,7570,7572,7574,7576],{"class":1110,"line":2128},[1108,7563,1256],{"class":1197},[1108,7565,1259],{"class":1249},[1108,7567,1205],{"class":1136},[1108,7569,1265],{"class":1264},[1108,7571,1268],{"class":1136},[1108,7573,1271],{"class":1136},[1108,7575,1274],{"class":1240},[1108,7577,1277],{"class":1136},[1108,7579,7580,7582,7584,7587],{"class":1110,"line":2145},[1108,7581,1396],{"class":1121},[1108,7583,3391],{"class":1399},[1108,7585,7586],{"class":1801},"database_plugin",[1108,7588,3397],{"class":1399},[1108,7590,7591],{"class":1110,"line":2162},[1108,7592,1231],{"class":1125},[1108,7594,7595,7597],{"class":1110,"line":2167},[1108,7596,1237],{"class":1136},[1108,7598,1241],{"class":1240},[1108,7600,7601,7603,7605,7607,7609,7611,7613,7615],{"class":1110,"line":2173},[1108,7602,1256],{"class":1197},[1108,7604,1321],{"class":1249},[1108,7606,1205],{"class":1136},[1108,7608,1265],{"class":1264},[1108,7610,1268],{"class":1136},[1108,7612,1271],{"class":1136},[1108,7614,1274],{"class":1240},[1108,7616,1277],{"class":1136},[1108,7618,7619,7621,7623,7625],{"class":1110,"line":2195},[1108,7620,1396],{"class":1121},[1108,7622,3391],{"class":1399},[1108,7624,3438],{"class":1801},[1108,7626,3397],{"class":1399},[1108,7628,7629],{"class":1110,"line":2214},[1108,7630,1231],{"class":1125},[1108,7632,7633,7635,7637,7639,7641,7643,7645,7647,7649,7651,7653,7655,7657,7659,7661,7663],{"class":1110,"line":2219},[1108,7634,1256],{"class":1197},[1108,7636,1477],{"class":1249},[1108,7638,1205],{"class":1136},[1108,7640,1265],{"class":1264},[1108,7642,1137],{"class":1136},[1108,7644,1487],{"class":1486},[1108,7646,1490],{"class":1136},[1108,7648,1153],{"class":1125},[1108,7650,1433],{"class":1136},[1108,7652,1436],{"class":1240},[1108,7654,1137],{"class":1136},[1108,7656,1163],{"class":1125},[1108,7658,1503],{"class":1136},[1108,7660,1271],{"class":1136},[1108,7662,1509],{"class":1508},[1108,7664,1277],{"class":1136},[1108,7666,7667,7669,7672],{"class":1110,"line":2225},[1108,7668,1283],{"class":1217},[1108,7670,7671],{"class":1221},"Initialize with database settings",[1108,7673,1225],{"class":1217},[1108,7675,7676],{"class":1110,"line":2241},[1108,7677,7678],{"class":1114},"        # Store settings in database\n",[1108,7680,7681,7683,7686,7688,7691,7693,7695,7697,7699],{"class":1110,"line":2246},[1108,7682,1841],{"class":1121},[1108,7684,7685],{"class":1125}," key",[1108,7687,1137],{"class":1136},[1108,7689,7690],{"class":1125}," value ",[1108,7692,1847],{"class":1121},[1108,7694,1487],{"class":1125},[1108,7696,1627],{"class":1136},[1108,7698,3112],{"class":1809},[1108,7700,2367],{"class":1136},[1108,7702,7703,7706,7708,7710,7712,7715],{"class":1110,"line":2274},[1108,7704,7705],{"class":1125},"            PluginSetting",[1108,7707,1627],{"class":1136},[1108,7709,6184],{"class":1630},[1108,7711,1627],{"class":1136},[1108,7713,7714],{"class":1809},"update_or_create",[1108,7716,4852],{"class":1136},[1108,7718,7719,7722,7724,7726,7728,7730],{"class":1110,"line":2284},[1108,7720,7721],{"class":5059},"                plugin_name",[1108,7723,2101],{"class":1136},[1108,7725,1265],{"class":1132},[1108,7727,1627],{"class":1136},[1108,7729,1771],{"class":1630},[1108,7731,6203],{"class":1136},[1108,7733,7734,7737,7739,7741],{"class":1110,"line":2303},[1108,7735,7736],{"class":5059},"                key",[1108,7738,2101],{"class":1136},[1108,7740,7519],{"class":1809},[1108,7742,6203],{"class":1136},[1108,7744,7745,7748,7751,7753,7756,7758,7760,7763],{"class":1110,"line":2311},[1108,7746,7747],{"class":5059},"                defaults",[1108,7749,7750],{"class":1136},"={",[1108,7752,3016],{"class":1399},[1108,7754,7755],{"class":1801},"value",[1108,7757,3016],{"class":1399},[1108,7759,1490],{"class":1136},[1108,7761,7762],{"class":1809}," value",[1108,7764,6592],{"class":1136},[1108,7766,7767],{"class":1110,"line":2316},[1108,7768,7769],{"class":1136},"            )\n",[1108,7771,7772],{"class":1110,"line":2335},[1108,7773,1231],{"class":1125},[1108,7775,7776,7778,7781,7783,7785,7787,7789,7791,7793,7795,7798,7800,7803],{"class":1110,"line":2340},[1108,7777,1256],{"class":1197},[1108,7779,7780],{"class":1249}," get_setting",[1108,7782,1205],{"class":1136},[1108,7784,1265],{"class":1264},[1108,7786,1137],{"class":1136},[1108,7788,7685],{"class":1486},[1108,7790,1490],{"class":1136},[1108,7792,1274],{"class":1240},[1108,7794,1137],{"class":1136},[1108,7796,7797],{"class":1486}," default",[1108,7799,2101],{"class":1774},[1108,7801,7802],{"class":1508},"None",[1108,7804,1211],{"class":1136},[1108,7806,7807,7809,7812],{"class":1110,"line":2346},[1108,7808,1283],{"class":1217},[1108,7810,7811],{"class":1221},"Get setting from database",[1108,7813,1225],{"class":1217},[1108,7815,7816,7818],{"class":1110,"line":2370},[1108,7817,5484],{"class":1121},[1108,7819,1277],{"class":1136},[1108,7821,7822,7825,7827,7829,7831,7833,7835,7837,7839,7841,7843,7845,7847,7849,7851,7853,7855,7857],{"class":1110,"line":2388},[1108,7823,7824],{"class":1125},"            setting ",[1108,7826,2101],{"class":1136},[1108,7828,7426],{"class":1125},[1108,7830,1627],{"class":1136},[1108,7832,6184],{"class":1630},[1108,7834,1627],{"class":1136},[1108,7836,3552],{"class":1809},[1108,7838,1205],{"class":1136},[1108,7840,2049],{"class":5059},[1108,7842,2101],{"class":1136},[1108,7844,1265],{"class":1132},[1108,7846,1627],{"class":1136},[1108,7848,1771],{"class":1630},[1108,7850,1137],{"class":1136},[1108,7852,7685],{"class":5059},[1108,7854,2101],{"class":1136},[1108,7856,7519],{"class":1809},[1108,7858,1823],{"class":1136},[1108,7860,7861,7863,7866,7868],{"class":1110,"line":2426},[1108,7862,2084],{"class":1121},[1108,7864,7865],{"class":1125}," setting",[1108,7867,1627],{"class":1136},[1108,7869,7870],{"class":1630},"value\n",[1108,7872,7873,7875,7877,7879,7882],{"class":1110,"line":2431},[1108,7874,5535],{"class":1121},[1108,7876,7426],{"class":1125},[1108,7878,1627],{"class":1136},[1108,7880,7881],{"class":1630},"DoesNotExist",[1108,7883,1277],{"class":1136},[1108,7885,7886,7888],{"class":1110,"line":2437},[1108,7887,2084],{"class":1121},[1108,7889,7890],{"class":1125}," default\n",[1108,7892,7893],{"class":1110,"line":2450},[1108,7894,1231],{"class":1125},[1108,7896,7897,7899,7902,7904,7906,7908,7910,7912,7914,7916,7918],{"class":1110,"line":2455},[1108,7898,1256],{"class":1197},[1108,7900,7901],{"class":1249}," set_setting",[1108,7903,1205],{"class":1136},[1108,7905,1265],{"class":1264},[1108,7907,1137],{"class":1136},[1108,7909,7685],{"class":1486},[1108,7911,1490],{"class":1136},[1108,7913,1274],{"class":1240},[1108,7915,1137],{"class":1136},[1108,7917,7762],{"class":1486},[1108,7919,1211],{"class":1136},[1108,7921,7922,7924,7927],{"class":1110,"line":2461},[1108,7923,1283],{"class":1217},[1108,7925,7926],{"class":1221},"Set setting in database",[1108,7928,1225],{"class":1217},[1108,7930,7931,7934,7936,7938,7940,7942],{"class":1110,"line":2477},[1108,7932,7933],{"class":1125},"        PluginSetting",[1108,7935,1627],{"class":1136},[1108,7937,6184],{"class":1630},[1108,7939,1627],{"class":1136},[1108,7941,7714],{"class":1809},[1108,7943,4852],{"class":1136},[1108,7945,7946,7949,7951,7953,7955,7957],{"class":1110,"line":2482},[1108,7947,7948],{"class":5059},"            plugin_name",[1108,7950,2101],{"class":1136},[1108,7952,1265],{"class":1132},[1108,7954,1627],{"class":1136},[1108,7956,1771],{"class":1630},[1108,7958,6203],{"class":1136},[1108,7960,7961,7964,7966,7968],{"class":1110,"line":2500},[1108,7962,7963],{"class":5059},"            key",[1108,7965,2101],{"class":1136},[1108,7967,7519],{"class":1809},[1108,7969,6203],{"class":1136},[1108,7971,7972,7975,7977,7979,7981,7983,7985,7987],{"class":1110,"line":2505},[1108,7973,7974],{"class":5059},"            defaults",[1108,7976,7750],{"class":1136},[1108,7978,3016],{"class":1399},[1108,7980,7755],{"class":1801},[1108,7982,3016],{"class":1399},[1108,7984,1490],{"class":1136},[1108,7986,7762],{"class":1809},[1108,7988,6592],{"class":1136},[1108,7990,7991],{"class":1110,"line":2530},[1108,7992,6229],{"class":1136},[1108,7994,7995],{"class":1110,"line":2540},[1108,7996,1231],{"class":1125},[1108,7998,7999,8001,8003,8005,8007,8009,8011,8013],{"class":1110,"line":2563},[1108,8000,1256],{"class":1197},[1108,8002,1546],{"class":1249},[1108,8004,1205],{"class":1136},[1108,8006,1265],{"class":1264},[1108,8008,1268],{"class":1136},[1108,8010,1271],{"class":1136},[1108,8012,1509],{"class":1508},[1108,8014,1277],{"class":1136},[1108,8016,8017,8019,8022],{"class":1110,"line":2568},[1108,8018,1283],{"class":1217},[1108,8020,8021],{"class":1221},"Cleanup database settings",[1108,8023,1225],{"class":1217},[1108,8025,8026,8028,8030,8032,8034,8037,8039,8041,8043,8045,8047,8049,8052,8055],{"class":1110,"line":2607},[1108,8027,7933],{"class":1125},[1108,8029,1627],{"class":1136},[1108,8031,6184],{"class":1630},[1108,8033,1627],{"class":1136},[1108,8035,8036],{"class":1809},"filter",[1108,8038,1205],{"class":1136},[1108,8040,2049],{"class":5059},[1108,8042,2101],{"class":1136},[1108,8044,1265],{"class":1132},[1108,8046,1627],{"class":1136},[1108,8048,1771],{"class":1630},[1108,8050,8051],{"class":1136},").",[1108,8053,8054],{"class":1809},"delete",[1108,8056,2447],{"class":1136},[1026,8058,8059],{},"Plugin architectures transform Django applications from monolithic systems into flexible, extensible platforms. By implementing proper plugin interfaces, hook systems, and management tools, you create applications that can grow and adapt to changing requirements without modifying core code.",[1026,8061,8062],{},"The key is designing stable APIs, providing clear extension points, and maintaining backward compatibility as your plugin ecosystem evolves.",[8064,8065,8066],"style",{},"html pre.shiki code .s9Tkl, html code.shiki .s9Tkl{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#A0ADA0;--shiki-default-font-style:inherit;--shiki-dark:#758575DD;--shiki-dark-font-style:inherit}html pre.shiki code .siDh9, html code.shiki .siDh9{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#1E754F;--shiki-default-font-style:inherit;--shiki-dark:#4D9375;--shiki-dark-font-style:inherit}html pre.shiki code .sftqT, html code.shiki .sftqT{--shiki-light:#90A4AE;--shiki-default:#393A34;--shiki-dark:#DBD7CAEE}html pre.shiki code .se3Ec, html code.shiki .se3Ec{--shiki-light:#90A4AE;--shiki-default:#A65E2B;--shiki-dark:#C99076}html pre.shiki code .soVBu, html code.shiki .soVBu{--shiki-light:#39ADB5;--shiki-default:#999999;--shiki-dark:#666666}html pre.shiki code .s5Kfy, html code.shiki .s5Kfy{--shiki-light:#9C3EDA;--shiki-default:#AB5959;--shiki-dark:#CB7676}html pre.shiki code .sD-vU, html code.shiki .sD-vU{--shiki-light:#E2931D;--shiki-default:#2E8F82;--shiki-dark:#5DA994}html pre.shiki code .sm7ve, html code.shiki .sm7ve{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#B5695977;--shiki-default-font-style:inherit;--shiki-dark:#C98A7D77;--shiki-dark-font-style:inherit}html pre.shiki code .sVyVU, html code.shiki .sVyVU{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#B56959;--shiki-default-font-style:inherit;--shiki-dark:#C98A7D;--shiki-dark-font-style:inherit}html pre.shiki code .sa2tF, html code.shiki .sa2tF{--shiki-light:#E2931D;--shiki-default:#998418;--shiki-dark:#B8A965}html pre.shiki code .sljsM, html code.shiki .sljsM{--shiki-light:#6182B8;--shiki-default:#59873A;--shiki-dark:#80A665}html pre.shiki code .sRjD_, html code.shiki .sRjD_{--shiki-light:#E53935;--shiki-light-font-style:italic;--shiki-default:#393A34;--shiki-default-font-style:inherit;--shiki-dark:#DBD7CAEE;--shiki-dark-font-style:inherit}html pre.shiki code .sbYkP, html code.shiki .sbYkP{--shiki-light:#39ADB5;--shiki-default:#B5695977;--shiki-dark:#C98A7D77}html pre.shiki code .sCyAa, html code.shiki .sCyAa{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#393A34;--shiki-default-font-style:inherit;--shiki-dark:#DBD7CAEE;--shiki-dark-font-style:inherit}html pre.shiki code .s8XtY, html code.shiki .s8XtY{--shiki-light:#39ADB5;--shiki-default:#1E754F;--shiki-dark:#4D9375}html pre.shiki code .sJdAF, html code.shiki .sJdAF{--shiki-light:#6182B8;--shiki-default:#998418;--shiki-dark:#B8A965}html pre.shiki code .sBPpx, html code.shiki .sBPpx{--shiki-light:#E53935;--shiki-default:#393A34;--shiki-dark:#DBD7CAEE}html pre.shiki code .sVsLi, html code.shiki .sVsLi{--shiki-light:#39ADB5;--shiki-default:#AB5959;--shiki-dark:#CB7676}html pre.shiki code .sTbE_, html code.shiki .sTbE_{--shiki-light:#91B859;--shiki-default:#B56959;--shiki-dark:#C98A7D}html pre.shiki code .s3h35, html code.shiki .s3h35{--shiki-light:#F76D47;--shiki-default:#A65E2B;--shiki-dark:#C99076}html pre.shiki code .siWMO, html code.shiki .siWMO{--shiki-light:#6182B8;--shiki-default:#393A34;--shiki-dark:#DBD7CAEE}html pre.shiki code .s131V, html code.shiki .s131V{--shiki-light:#90A4AE;--shiki-default:#998418;--shiki-dark:#B8A965}html pre.shiki code .sYn-s, html code.shiki .sYn-s{--shiki-light:#E2931D;--shiki-default:#59873A;--shiki-dark:#80A665}html pre.shiki code .s7CZa, html code.shiki .s7CZa{--shiki-light:#F76D47;--shiki-default:#2F798A;--shiki-dark:#4C9A91}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 .sqOPj, html code.shiki .sqOPj{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#B07D48;--shiki-default-font-style:inherit;--shiki-dark:#BD976A;--shiki-dark-font-style:inherit}html pre.shiki code .sFGJz, html code.shiki .sFGJz{--shiki-light:#E53935;--shiki-default:#A65E2B;--shiki-dark:#C99076}",{"title":1103,"searchDepth":1111,"depth":1118,"links":8068},[8069,8073,8076],{"id":1032,"depth":1118,"text":1033,"children":8070},[8071,8072],{"id":1040,"depth":1143,"text":1041},{"id":1095,"depth":1143,"text":1096},{"id":4435,"depth":1118,"text":4436,"children":8074},[8075],{"id":4439,"depth":1143,"text":4440},{"id":6595,"depth":1118,"text":6596,"children":8077},[8078],{"id":6599,"depth":1143,"text":6600},"md",null,{},{"title":819,"description":1028},"b57uVIz3kPE2a2qOB2pX8X-z4Z4NPYXSQXk2Au-ucos",[8085,8087],{"title":815,"path":816,"stem":817,"description":8086,"children":-1},"Large-scale Django projects require careful architecture, organization, and development practices to remain maintainable as they grow. This comprehensive guide covers strategies for organizing massive Django applications, managing complexity, scaling development teams, and maintaining code quality across hundreds of models and thousands of views.",{"title":823,"path":824,"stem":825,"description":8088,"children":-1},"Django's architecture allows deep customization and extension of its core components. This comprehensive guide covers advanced techniques for extending Django's ORM, admin interface, authentication system, and other core components to create powerful, customized functionality that integrates seamlessly with the framework.",1772474958465]