diff --git a/ARTISAN.md b/ARTISAN.md index 97b3c7d..d761cee 100644 --- a/ARTISAN.md +++ b/ARTISAN.md @@ -1,4 +1,4 @@ -a make:model OrientierungZuAbschlaege -m +a make:model TextblockKennung -m a make:filament-resource Customer @@ -29,7 +29,7 @@ php artisan make:filament-importer Raeumealle A make:filament-resource Allgemeinflaechen --nested -a make:filament-relation-manager OrientierungZuAbschlaegeResource orientierung_zu_abschlaeges top_nummer +a make:filament-relation-manager ProjektInhaltsverzeichnisResource projekt_inhaltsverzeichnis text for import in prod run diff --git a/app/Filament/Resources/Inhaltsverzeichnis/InhaltsverzeichnisResource.php b/app/Filament/Resources/Inhaltsverzeichnis/InhaltsverzeichnisResource.php index 0fee22d..df66174 100644 --- a/app/Filament/Resources/Inhaltsverzeichnis/InhaltsverzeichnisResource.php +++ b/app/Filament/Resources/Inhaltsverzeichnis/InhaltsverzeichnisResource.php @@ -29,6 +29,8 @@ class InhaltsverzeichnisResource extends Resource protected static ?string $pluralModelLabel = 'Inhaltsverzeichnis'; + protected static ?int $navigationSort = 1; + public static function form(Schema $schema): Schema { return InhaltsverzeichnisForm::configure($schema); diff --git a/app/Filament/Resources/Inhaltsverzeichnis/Schemas/InhaltsverzeichnisForm.php b/app/Filament/Resources/Inhaltsverzeichnis/Schemas/InhaltsverzeichnisForm.php index 9bf74ae..e478680 100644 --- a/app/Filament/Resources/Inhaltsverzeichnis/Schemas/InhaltsverzeichnisForm.php +++ b/app/Filament/Resources/Inhaltsverzeichnis/Schemas/InhaltsverzeichnisForm.php @@ -12,7 +12,7 @@ class InhaltsverzeichnisForm return $schema ->components([ TextInput::make('ordnungszahl'), - TextInput::make('text'), + TextInput::make('name'), ])->columns(1); } } diff --git a/app/Filament/Resources/Inhaltsverzeichnis/Tables/InhaltsverzeichnisTable.php b/app/Filament/Resources/Inhaltsverzeichnis/Tables/InhaltsverzeichnisTable.php index a15e97b..b1d89ba 100644 --- a/app/Filament/Resources/Inhaltsverzeichnis/Tables/InhaltsverzeichnisTable.php +++ b/app/Filament/Resources/Inhaltsverzeichnis/Tables/InhaltsverzeichnisTable.php @@ -15,7 +15,8 @@ class InhaltsverzeichnisTable // TextColumn::make('sort'), TextColumn::make('ordnungszahl') ->getStateUsing(fn ($record): string => $record->ordnungszahl == '0' ? '' : number_format($record->ordnungszahl, 2)), - TextColumn::make('text'), + TextColumn::make('name') + ->description(fn ($record): string => $record->textblock_kennung->name ?? ''), TextColumn::make('seite') ->alignCenter() ->badge() diff --git a/app/Filament/Resources/Methodes/MethodeResource.php b/app/Filament/Resources/Methodes/MethodeResource.php index 074c973..fafc15b 100644 --- a/app/Filament/Resources/Methodes/MethodeResource.php +++ b/app/Filament/Resources/Methodes/MethodeResource.php @@ -29,6 +29,8 @@ class MethodeResource extends Resource protected static ?string $pluralModelLabel = 'Methoden'; + protected static ?int $navigationSort = 4; + public static function form(Schema $schema): Schema { return MethodeForm::configure($schema); diff --git a/app/Filament/Resources/Methodes/Tables/MethodesTable.php b/app/Filament/Resources/Methodes/Tables/MethodesTable.php index 95dcc29..4cdc5a6 100644 --- a/app/Filament/Resources/Methodes/Tables/MethodesTable.php +++ b/app/Filament/Resources/Methodes/Tables/MethodesTable.php @@ -13,8 +13,9 @@ class MethodesTable { return $table ->columns([ - TextColumn::make('kennung')->badge()->color('info'), + TextColumn::make('id'), TextColumn::make('name') + ->color('info') ->wrap() ->description(function ($record) { return new HtmlString($record->description); diff --git a/app/Filament/Resources/Orientierungs/OrientierungResource.php b/app/Filament/Resources/Orientierungs/OrientierungResource.php index 72ec709..816029a 100644 --- a/app/Filament/Resources/Orientierungs/OrientierungResource.php +++ b/app/Filament/Resources/Orientierungs/OrientierungResource.php @@ -29,6 +29,8 @@ class OrientierungResource extends Resource protected static ?string $pluralModelLabel = 'Orientierungen'; + protected static ?int $navigationSort = 3; + public static function form(Schema $schema): Schema { return OrientierungForm::configure($schema); diff --git a/app/Filament/Resources/Projektes/RelationManagers/ProjektInhaltsverzeichnisRelationManager.php b/app/Filament/Resources/Projektes/RelationManagers/ProjektInhaltsverzeichnisRelationManager.php new file mode 100644 index 0000000..4fbab9a --- /dev/null +++ b/app/Filament/Resources/Projektes/RelationManagers/ProjektInhaltsverzeichnisRelationManager.php @@ -0,0 +1,60 @@ +components([ + TextInput::make('text') + ->required() + ->maxLength(255), + ]); + } + + public function table(Table $table): Table + { + return $table + ->recordTitleAttribute('text') + ->columns([ + TextColumn::make('text') + ->searchable(), + ]) + ->filters([ + // + ]) + ->headerActions([ + CreateAction::make(), + AssociateAction::make(), + ]) + ->recordActions([ + EditAction::make(), + DissociateAction::make(), + DeleteAction::make(), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DissociateBulkAction::make(), + DeleteBulkAction::make(), + ]), + ]); + } +} diff --git a/app/Filament/Resources/Textblocks/Schemas/TextblockForm.php b/app/Filament/Resources/Textblocks/Schemas/TextblockForm.php index ecd4d65..9c09f70 100644 --- a/app/Filament/Resources/Textblocks/Schemas/TextblockForm.php +++ b/app/Filament/Resources/Textblocks/Schemas/TextblockForm.php @@ -2,7 +2,10 @@ namespace App\Filament\Resources\Textblocks\Schemas; +use App\Models\TextblockKennung; use Filament\Forms\Components\RichEditor; +use Filament\Forms\Components\Select; +use Filament\Forms\Components\Textarea; use Filament\Forms\Components\TextInput; use Filament\Schemas\Schema; @@ -14,6 +17,11 @@ class TextblockForm ->components([ TextInput::make('name') ->required(), + Textarea::make('beschreibung') + ->afterLabel('Bei gleichen Textblockarten kann hier der Unterschied kurz angerissen werden.'), + Select::make('textblock_kennung_id') + ->label('Textblock Art') + ->options(TextblockKennung::pluck('name', 'id')), RichEditor::make('textblock') ->toolbarButtons([ ['bold', 'italic', 'underline', 'strike', 'subscript', 'superscript'], diff --git a/app/Filament/Resources/Textblocks/Tables/TextblocksTable.php b/app/Filament/Resources/Textblocks/Tables/TextblocksTable.php index 125b058..dd7e8de 100644 --- a/app/Filament/Resources/Textblocks/Tables/TextblocksTable.php +++ b/app/Filament/Resources/Textblocks/Tables/TextblocksTable.php @@ -14,6 +14,12 @@ class TextblocksTable { return $table ->columns([ + TextColumn::make('textblock_kennung.name') + ->color('info') + ->wrap() + ->description(function ($record) { + return new HtmlString($record->beschreibung); + }), TextColumn::make('name') ->weight(FontWeight::Bold) ->wrap() diff --git a/app/Filament/Resources/Textblocks/TextblockResource.php b/app/Filament/Resources/Textblocks/TextblockResource.php index 74804a5..715eec7 100644 --- a/app/Filament/Resources/Textblocks/TextblockResource.php +++ b/app/Filament/Resources/Textblocks/TextblockResource.php @@ -29,6 +29,8 @@ class TextblockResource extends Resource protected static ?string $pluralModelLabel = 'Textblöcke'; + protected static ?int $navigationSort = 2; + public static function form(Schema $schema): Schema { return TextblockForm::configure($schema); diff --git a/app/Models/Inhaltsverzeichnis.php b/app/Models/Inhaltsverzeichnis.php index 98de976..e270606 100644 --- a/app/Models/Inhaltsverzeichnis.php +++ b/app/Models/Inhaltsverzeichnis.php @@ -7,9 +7,15 @@ use Illuminate\Database\Eloquent\Model; class Inhaltsverzeichnis extends Model { protected $fillable = [ + 'name', + 'textblock_kennung_id', 'sort', 'ordnungszahl', - 'text', 'seite', ]; + + public function textblock_kennung() + { + return $this->hasOne(TextblockKennung::class, 'id'); + } } diff --git a/app/Models/ProjektInhaltsverzeichnis.php b/app/Models/ProjektInhaltsverzeichnis.php new file mode 100644 index 0000000..75aaa52 --- /dev/null +++ b/app/Models/ProjektInhaltsverzeichnis.php @@ -0,0 +1,18 @@ +hasMany(ProjektMethode::class); } + + public function projekt_inhaltsverzeichnis() + { + return $this->hasMany(ProjektInhaltsverzeichnis::class); + } } diff --git a/app/Models/Textblock.php b/app/Models/Textblock.php index 610af56..c814235 100644 --- a/app/Models/Textblock.php +++ b/app/Models/Textblock.php @@ -7,8 +7,14 @@ use Illuminate\Database\Eloquent\Model; class Textblock extends Model { protected $fillable = [ - 'kennung', 'name', + 'beschreibung', + 'textblock_kennung_id', 'textblock', ]; + + public function textblock_kennung() + { + return $this->hasMany(TextblockKennung::class, 'id'); + } } diff --git a/app/Models/TextblockKennung.php b/app/Models/TextblockKennung.php new file mode 100644 index 0000000..fe170f3 --- /dev/null +++ b/app/Models/TextblockKennung.php @@ -0,0 +1,12 @@ + 'App\\Filament\\Resources\\Projektes\\Pages\\ListProjektes', 'app.filament.resources.projektes.relation-managers.allgemeinflaechens-relation-manager' => 'App\\Filament\\Resources\\Projektes\\RelationManagers\\AllgemeinflaechensRelationManager', 'app.filament.resources.projektes.relation-managers.orientierung-zu-abschlaeges-relation-manager' => 'App\\Filament\\Resources\\Projektes\\RelationManagers\\OrientierungZuAbschlaegesRelationManager', + 'app.filament.resources.projektes.relation-managers.projekt-inhaltsverzeichnis-relation-manager' => 'App\\Filament\\Resources\\Projektes\\RelationManagers\\ProjektInhaltsverzeichnisRelationManager', 'app.filament.resources.projektes.relation-managers.projekt-methodes-relation-manager' => 'App\\Filament\\Resources\\Projektes\\RelationManagers\\ProjektMethodesRelationManager', 'app.filament.resources.projektes.relation-managers.raeumealles-relation-manager' => 'App\\Filament\\Resources\\Projektes\\RelationManagers\\RaeumeallesRelationManager', 'app.filament.resources.projektes.widgets.widget-merkmale' => 'App\\Filament\\Resources\\Projektes\\Widgets\\WidgetMerkmale', diff --git a/bootstrap/cache/routes-v7.php b/bootstrap/cache/routes-v7.php index fb23935..601b4a7 100644 --- a/bootstrap/cache/routes-v7.php +++ b/bootstrap/cache/routes-v7.php @@ -511,7 +511,7 @@ app('router')->setCompiledRoutes( array ( 0 => array ( - '_route' => 'generated::ImdwJtVhYfCKnSdA', + '_route' => 'generated::llOxEKzJrZGaLKrB', ), 1 => NULL, 2 => @@ -531,7 +531,7 @@ app('router')->setCompiledRoutes( array ( 0 => array ( - '_route' => 'generated::HI5z9GiwKfSAqWO0', + '_route' => 'generated::BP26AY5ncyQIeMtX', ), 1 => NULL, 2 => @@ -589,7 +589,7 @@ app('router')->setCompiledRoutes( array ( 0 => array ( - '_route' => 'generated::eheMN9HMzijWiM0B', + '_route' => 'generated::01yWvBevTudzWtnb', ), 1 => NULL, 2 => @@ -609,7 +609,7 @@ app('router')->setCompiledRoutes( array ( 0 => array ( - '_route' => 'generated::xYVDxcwoa06C2yCe', + '_route' => 'generated::KtirFSRWVMX3MXZy', ), 1 => NULL, 2 => @@ -629,7 +629,7 @@ app('router')->setCompiledRoutes( array ( 0 => array ( - '_route' => 'generated::WholLVDS2X19VLCD', + '_route' => 'generated::RCYsfjr62x0BA3wj', ), 1 => NULL, 2 => @@ -649,7 +649,7 @@ app('router')->setCompiledRoutes( array ( 0 => array ( - '_route' => 'generated::hvrj9pv1HBrI50Wn', + '_route' => 'generated::3MT8VWZJK8QmmLKn', ), 1 => NULL, 2 => @@ -669,7 +669,7 @@ app('router')->setCompiledRoutes( array ( 0 => array ( - '_route' => 'generated::fvw0qi4fbrvuqgah', + '_route' => 'generated::TMmZkpUIIYYDQius', ), 1 => NULL, 2 => @@ -2595,7 +2595,7 @@ app('router')->setCompiledRoutes( 'waitSeconds' => NULL, 'withTrashed' => false, ), - 'generated::ImdwJtVhYfCKnSdA' => + 'generated::llOxEKzJrZGaLKrB' => array ( 'methods' => array ( @@ -2607,7 +2607,7 @@ app('router')->setCompiledRoutes( array ( 'uses' => 'Livewire\\Mechanisms\\FrontendAssets\\FrontendAssets@returnJavaScriptAsFile', 'controller' => 'Livewire\\Mechanisms\\FrontendAssets\\FrontendAssets@returnJavaScriptAsFile', - 'as' => 'generated::ImdwJtVhYfCKnSdA', + 'as' => 'generated::llOxEKzJrZGaLKrB', ), 'fallback' => false, 'defaults' => @@ -2623,7 +2623,7 @@ app('router')->setCompiledRoutes( 'waitSeconds' => NULL, 'withTrashed' => false, ), - 'generated::HI5z9GiwKfSAqWO0' => + 'generated::BP26AY5ncyQIeMtX' => array ( 'methods' => array ( @@ -2635,7 +2635,7 @@ app('router')->setCompiledRoutes( array ( 'uses' => 'Livewire\\Mechanisms\\FrontendAssets\\FrontendAssets@maps', 'controller' => 'Livewire\\Mechanisms\\FrontendAssets\\FrontendAssets@maps', - 'as' => 'generated::HI5z9GiwKfSAqWO0', + 'as' => 'generated::BP26AY5ncyQIeMtX', ), 'fallback' => false, 'defaults' => @@ -2737,7 +2737,7 @@ app('router')->setCompiledRoutes( 'waitSeconds' => NULL, 'withTrashed' => false, ), - 'generated::eheMN9HMzijWiM0B' => + 'generated::01yWvBevTudzWtnb' => array ( 'methods' => array ( @@ -2766,7 +2766,7 @@ app('router')->setCompiledRoutes( \'exception\' => $exception, ]), status: $exception ? 500 : 200); }";s:5:"scope";s:54:"Illuminate\\Foundation\\Configuration\\ApplicationBuilder";s:4:"this";N;s:4:"self";s:32:"0000000000000f2d0000000000000000";}}', - 'as' => 'generated::eheMN9HMzijWiM0B', + 'as' => 'generated::01yWvBevTudzWtnb', ), 'fallback' => false, 'defaults' => @@ -2782,7 +2782,7 @@ app('router')->setCompiledRoutes( 'waitSeconds' => NULL, 'withTrashed' => false, ), - 'generated::xYVDxcwoa06C2yCe' => + 'generated::KtirFSRWVMX3MXZy' => array ( 'methods' => array ( @@ -2804,7 +2804,7 @@ app('router')->setCompiledRoutes( 'where' => array ( ), - 'as' => 'generated::xYVDxcwoa06C2yCe', + 'as' => 'generated::KtirFSRWVMX3MXZy', ), 'fallback' => false, 'defaults' => @@ -2820,7 +2820,7 @@ app('router')->setCompiledRoutes( 'waitSeconds' => NULL, 'withTrashed' => false, ), - 'generated::WholLVDS2X19VLCD' => + 'generated::RCYsfjr62x0BA3wj' => array ( 'methods' => array ( @@ -2842,7 +2842,7 @@ app('router')->setCompiledRoutes( 'where' => array ( ), - 'as' => 'generated::WholLVDS2X19VLCD', + 'as' => 'generated::RCYsfjr62x0BA3wj', ), 'fallback' => false, 'defaults' => @@ -2858,7 +2858,7 @@ app('router')->setCompiledRoutes( 'waitSeconds' => NULL, 'withTrashed' => false, ), - 'generated::hvrj9pv1HBrI50Wn' => + 'generated::3MT8VWZJK8QmmLKn' => array ( 'methods' => array ( @@ -2880,7 +2880,7 @@ app('router')->setCompiledRoutes( 'where' => array ( ), - 'as' => 'generated::hvrj9pv1HBrI50Wn', + 'as' => 'generated::3MT8VWZJK8QmmLKn', ), 'fallback' => false, 'defaults' => @@ -2896,7 +2896,7 @@ app('router')->setCompiledRoutes( 'waitSeconds' => NULL, 'withTrashed' => false, ), - 'generated::fvw0qi4fbrvuqgah' => + 'generated::TMmZkpUIIYYDQius' => array ( 'methods' => array ( @@ -2918,7 +2918,7 @@ app('router')->setCompiledRoutes( 'where' => array ( ), - 'as' => 'generated::fvw0qi4fbrvuqgah', + 'as' => 'generated::TMmZkpUIIYYDQius', ), 'fallback' => false, 'defaults' => diff --git a/database/migrations/2025_09_23_135826_create_methodes_table.php b/database/migrations/2025_09_23_135826_create_methodes_table.php index 59d083c..9b77d3a 100644 --- a/database/migrations/2025_09_23_135826_create_methodes_table.php +++ b/database/migrations/2025_09_23_135826_create_methodes_table.php @@ -13,7 +13,6 @@ return new class extends Migration { Schema::create('methodes', function (Blueprint $table) { $table->id(); - $table->string('kennung'); $table->string('name'); $table->text('description'); $table->timestamps(); diff --git a/database/migrations/2025_10_02_163208_create_textblocks_table.php b/database/migrations/2025_10_02_163208_create_textblocks_table.php index d67d9d9..5216c92 100644 --- a/database/migrations/2025_10_02_163208_create_textblocks_table.php +++ b/database/migrations/2025_10_02_163208_create_textblocks_table.php @@ -13,8 +13,9 @@ return new class extends Migration { Schema::create('textblocks', function (Blueprint $table) { $table->id(); - $table->string('kennung'); $table->string('name'); + $table->string('beschreibung')->nullable(); + $table->integer('textblock_kennung_id')->default(0); $table->text('textblock'); $table->timestamps(); }); diff --git a/database/migrations/2025_10_02_170241_create_inhaltsverzeichnis_table.php b/database/migrations/2025_10_02_170241_create_inhaltsverzeichnis_table.php index 278f7ed..a29d125 100644 --- a/database/migrations/2025_10_02_170241_create_inhaltsverzeichnis_table.php +++ b/database/migrations/2025_10_02_170241_create_inhaltsverzeichnis_table.php @@ -13,9 +13,10 @@ return new class extends Migration { Schema::create('inhaltsverzeichnis', function (Blueprint $table) { $table->id(); + $table->string('name'); + $table->integer('textblock_kennung_id')->default(0); $table->integer('sort')->default(0); $table->double('ordnungszahl')->default(0.00); - $table->string('text'); $table->integer('seite')->default(0); $table->timestamps(); }); diff --git a/database/migrations/2025_10_10_085849_create_projekt_inhaltsverzeichnis_table.php b/database/migrations/2025_10_10_085849_create_projekt_inhaltsverzeichnis_table.php new file mode 100644 index 0000000..4c259db --- /dev/null +++ b/database/migrations/2025_10_10_085849_create_projekt_inhaltsverzeichnis_table.php @@ -0,0 +1,34 @@ +id(); + $table->foreignId('projekte_id')->constrained()->cascadeOnDelete(); + $table->integer('textblock_kennung_id')->default(0); + $table->integer('sort')->default(0); + $table->double('ordnungszahl')->default(0.00); + $table->string('name'); + $table->text('textblock'); + $table->integer('seite')->default(0); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('projekt_inhaltsverzeichnis'); + } +}; diff --git a/database/migrations/2025_10_10_091736_create_textblock_kennungs_table.php b/database/migrations/2025_10_10_091736_create_textblock_kennungs_table.php new file mode 100644 index 0000000..0ec0a66 --- /dev/null +++ b/database/migrations/2025_10_10_091736_create_textblock_kennungs_table.php @@ -0,0 +1,28 @@ +id(); + $table->string('name'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('textblock_kennungs'); + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 0d153ac..069b9db 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -20,6 +20,7 @@ class DatabaseSeeder extends Seeder OrientierungenSeeder::class, PlansSeeder::class, TextblockSeeder::class, + TextblockKennungSeeder::class, InhaltsverzeichnisSeeder::class, ]); diff --git a/database/seeders/InhaltsverzeichnisSeeder.php b/database/seeders/InhaltsverzeichnisSeeder.php index 73ad54c..79f6898 100644 --- a/database/seeders/InhaltsverzeichnisSeeder.php +++ b/database/seeders/InhaltsverzeichnisSeeder.php @@ -12,30 +12,33 @@ class InhaltsverzeichnisSeeder extends Seeder */ public function run(): void { - $sql = "INSERT INTO `inhaltsverzeichnis` (`id`, `sort`, `ordnungszahl`, `text`, `seite`, `created_at`, `updated_at`) + $sql = "INSERT INTO `inhaltsverzeichnis` (`id`, `name`, `textblock_kennung_id`, `sort`, `ordnungszahl`, `seite`, `created_at`, `updated_at`) VALUES - ('1', '1', '1', 'ALLGEMEINE ANGABEN', '3', NULL, NULL), - ('2', '2', '1.1', 'AUFTRAGGEBER', '3', NULL, NULL), - ('3', '3', '1.2', 'ZWECK UND GEGENSTAND DES GUTACHTENS', '3', NULL, NULL), - ('4', '4', '1.3', 'ORTSBESICHTIGUNG', '3', NULL, NULL), - ('5', '5', '1.4', 'UNTERLAGEN', '3', NULL, NULL), - ('6', '6', '2', 'BEFUND', '4', NULL, NULL), - ('7', '7', '2.1', 'GRUNDBUCHSTAND', '4', NULL, NULL), - ('8', '8', '2.2', 'BESCHREIBUNG DER LIEGENSCHAFT', '4', NULL, NULL), - ('9', '9', '2.3', '§ 6 BESTÄTIGUNG', '5', NULL, NULL), - ('10', '10', '3', 'GUTACHTEN', '0', NULL, NULL), - ('11', '11', '3.1', 'ALLGEMEINE GRUNDSÄTZE', '0', NULL, NULL), - ('12', '12', '3.2', 'ERMITTLUNG DER NUTZWERTE – BEWERTUNGEN', '0', NULL, NULL), - ('13', '13', '3.21', 'TABELLE ZU + ABSCHLÄGE', '0', NULL, NULL), - ('14', '14', '3.3', 'NUTZWERTBERECHNUNG', '0', NULL, NULL), - ('15', '15', '3.4', 'ZUSAMMENSTELLUNG', '0', NULL, NULL), - ('16', '16', '3.5', 'ALLGEMEINFLÄCHEN', '0', NULL, NULL), - ('17', '17', '4', 'PARIFIZIERUNGSPLÄNE ', '0', NULL, NULL), - ('18', '18', '5', 'ANHANG', '0', NULL, NULL), - ('19', '19', '0', 'GRUNDBUCHAUSZUG ', '0', NULL, NULL), - ('20', '20', '0', 'BAUBESCHEID', '0', NULL, NULL), - ('21', '21', '0', 'HAUSTECHNISCHE BESCHREIBUNG', '0', NULL, NULL), - ('22', '22', '0', 'NUTZFLÄCHENERMITTLUNGEN', '0', NULL, NULL); + ('1', 'ALLGEMEINE ANGABEN', '0', '1', '1', '3', NULL, NULL), + ('2', 'AUFTRAGGEBER', '0', '2', '1.1', '3', NULL, NULL), + ('3', 'ZWECK UND GEGENSTAND DES GUTACHTENS', '1', '3', '1.2', '3', NULL, NULL), + ('4', 'ORTSBESICHTIGUNG', '2', '4', '1.3', '3', NULL, NULL), + ('5', 'UNTERLAGEN', '3', '5', '1.4', '3', NULL, NULL), + ('6', 'BEFUND', '0', '6', '2', '4', NULL, NULL), + ('7', 'GRUNDBUCHSTAND', '4', '7', '2.1', '4', NULL, NULL), + ('8', 'BESCHREIBUNG DER LIEGENSCHAFT', '5', '8', '2.2', '4', NULL, NULL), + ('9', '§ 6 Teil 1', '6', '9', '2.3', '5', NULL, NULL), + ('10', 'Tabelle § 6', '0', '10', '0', '5', NULL, NULL), + ('11', '§ 6 Teil 2', '7', '11', '2.3', '5', NULL, NULL), + ('12', 'GUTACHTEN', '0', '12', '3', '0', NULL, NULL), + ('13', 'ALLGEMEINE GRUNDSÄTZE', '8', '13', '3.1', '0', NULL, NULL), + ('14', 'ERMITTLUNG DER NUTZWERTE – ZUBEHÖRBEWERTUNG', '9', '14', '3.2', '0', NULL, NULL), + ('15', 'TABELLE ZU + ABSCHLÄGE', '0', '15', '3.21', '0', NULL, NULL), + ('16', 'Zubehör', '10', '16', '0', '0', NULL, NULL), + ('17', 'NUTZWERTBERECHNUNG', '0', '17', '3.3', '0', NULL, NULL), + ('18', 'ZUSAMMENSTELLUNG', '0', '18', '3.4', '0', NULL, NULL), + ('19', 'ALLGEMEINFLÄCHEN', '0', '19', '3.5', '0', NULL, NULL), + ('20', 'PARIFIZIERUNGSPLÄNE ', '0', '20', '4', '0', NULL, NULL), + ('21', 'ANHANG', '0', '21', '5', '0', NULL, NULL), + ('22', 'GRUNDBUCHAUSZUG ', '0', '22', '0', '0', NULL, NULL), + ('23', 'BAUBESCHEID', '0', '23', '0', '0', NULL, NULL), + ('24', 'HAUSTECHNISCHE BESCHREIBUNG', '0', '24', '0', '0', NULL, NULL), + ('25', 'NUTZFLÄCHENERMITTLUNGEN', '0', '25', '0', '0', NULL, NULL); "; DB::unprepared($sql); } diff --git a/database/seeders/MethodeSeeder.php b/database/seeders/MethodeSeeder.php index cc1fe4c..3d99fdf 100644 --- a/database/seeders/MethodeSeeder.php +++ b/database/seeders/MethodeSeeder.php @@ -12,14 +12,14 @@ class MethodeSeeder extends Seeder */ public function run(): void { - $sql = "INSERT INTO `methodes` (`id`, `kennung`, `name`, `description`, `created_at`, `updated_at`) + $sql = "INSERT INTO `methodes` (`id`, `name`, `description`, `created_at`, `updated_at`) VALUES - ('1', 'standard', 'Normale Wohnnutzflächen', 'Hierbei werden alle Wohnnutzflächen des Objekts die nicht einer anderen Methode zugeordnet sind zusammengezählt.', NULL, NULL), - ('2', 'winterloggien', 'Wintergarten, Loggien', '
Alle Objekte werden einzeln aufgelistet mit Absolutem Faktor und Relativem Faktor multipliziert. Die Nutzwerte werden ungerundet zusammengezählt.
', NULL, '2025-10-02 16:00:09'), - ('3', 'terassebalkon', 'Terasse, Balkon', 'Terasse, Balkon werden mit Absolutem Faktor multipliziert und dann gerundet. Jedes Ergebnis wird einzeln aufgeführt.
', NULL, '2025-10-02 15:59:55'), - ('4', 'kellergarten', 'Keller, Garten', 'Objekte werden mit dem Absoluten Faktor multipliziert dann gerundet. Jedes Ergebnis wird einzeln aufgeführt.', NULL, NULL), - ('5', 'stellplatz', 'Stellplätze', 'Stellplätze werden nur mit Absolutem Faktor multipliziert, nicht in Orientierung & Typ aufgeführt und im PDF als eigenes Objekt ausgegeben.
', NULL, '2025-10-02 15:59:18'), - ('6', 'zubehoer', 'Zubehör', 'Zubehör welches mit dem Stellplatz direkt verbunden ist. (zB. das Kellerabteil hinter dem Stellplatz, oder eine eigene Zufahrt nur zu einem Stellplatz).
Das Objekt wird mit Absolutem Faktor multipliziert und ungerundet zum Stellplatz dazugezählt, und dann erst die Summe des Nutzwertes gerundet.
', NULL, '2025-10-02 15:59:29'); + ('1', 'Normale Wohnnutzflächen', 'Hierbei werden alle Wohnnutzflächen des Objekts die nicht einer anderen Methode zugeordnet sind zusammengezählt.', NULL, NULL), + ('2', 'Wintergarten, Loggien', 'Alle Objekte werden einzeln aufgelistet mit Absolutem Faktor und Relativem Faktor multipliziert. Die Nutzwerte werden ungerundet zusammengezählt.
', NULL, '2025-10-02 16:00:09'), + ('3', 'Terasse, Balkon', 'Terasse, Balkon werden mit Absolutem Faktor multipliziert und dann gerundet. Jedes Ergebnis wird einzeln aufgeführt.
', NULL, '2025-10-02 15:59:55'), + ('4', 'Keller, Garten', 'Objekte werden mit dem Absoluten Faktor multipliziert dann gerundet. Jedes Ergebnis wird einzeln aufgeführt.', NULL, NULL), + ('5', 'Stellplätze', 'Stellplätze werden nur mit Absolutem Faktor multipliziert, nicht in Orientierung & Typ aufgeführt und im PDF als eigenes Objekt ausgegeben.
', NULL, '2025-10-02 15:59:18'), + ('6', 'Zubehör', 'Zubehör welches mit dem Stellplatz direkt verbunden ist. (zB. das Kellerabteil hinter dem Stellplatz, oder eine eigene Zufahrt nur zu einem Stellplatz).
Das Objekt wird mit Absolutem Faktor multipliziert und ungerundet zum Stellplatz dazugezählt, und dann erst die Summe des Nutzwertes gerundet.
', NULL, '2025-10-02 15:59:29'); "; DB::unprepared($sql); } diff --git a/database/seeders/TextblockKennungSeeder.php b/database/seeders/TextblockKennungSeeder.php new file mode 100644 index 0000000..3f07e53 --- /dev/null +++ b/database/seeders/TextblockKennungSeeder.php @@ -0,0 +1,30 @@ +Liegenschaftsadresse|###LIEGENSCHAFTSADRESSE###
Grundbuch|###GRUNDBUCH###
Einlagezahl|###EINLAGEZAHL###
Grundstücksnummer|###GSTNR###
Bezirksgericht|###BEZIRKSGERICHT###
Es wird bestätigt, dass die Wohnanlage (Gst-Nr. ###GSTNR### In EZ ###EINLAGEZAHL###) folgende Einheiten umfasst, an welchen Wohnungseigentum begründet wird:
Grundlage ist die Einreichplanung mit dem Baubescheid Zl. ###BAUBESCHEID### sowie die Werkplanung.
XX Wohnungen (mit vorangestelltem "W") samt Zubehör.
XX Kfz-Stellplätze in der Tiefgarage (mit vorangestelltem "P")
Weitere XX Stellplätze in der Tiefgarage sowie XX freie Stellplätze verbleiben laut Widmung zur allgemeinen Benützung.
Wohnungseigentum ist das dem Miteigentümer einer Liegenschaft oder einer Eigentümerpartnerschaft eingeräumte dingliche Recht, ein Wohnungseigentumsobjekt ausschließlich zu nutzen und allein darüber zu verfügen. (Auszug §2 (1))
Wohnungseigentumsobjekte sind Wohnungen, sonstige selbständige Räumlichkeiten und Abstellplätze für Kraftfahrzeuge (wohnungseigentumstaugliche Objekte), an denen Wohnungseigentum begründet wurde. (Auszug §2 (2))
Eine Wohnung ist ein baulich abgeschlossener, nach der Verkehrsauffassung selbständiger Teil eines Gebäudes, der nach seiner Art und Größe geeignet ist, der Befriedigung eines individuellen Wohnbedürfnisses von Menschen zu dienen. Eine sonstige selbständige Räumlichkeit ist ein baulich abgeschlossener, nach der Verkehrsauffassung selbständiger Teil eines Gebäudes, dem nach seiner Art und Größe eine erhebliche wirtschaftliche Bedeutung zukommt, ein Abstellplatz für ein Kraftfahrzeug ist eine - etwa durch Bodenmarkierung - deutlich abgegrenzte Bodenfläche, die ausschließlich zum Abstellen eines Kraftfahrzeugs gewidmet und dazu nach ihrer Größe, Lage und Beschaffenheit geeignet ist. (Auszug §2 (2))
Zubehör-Wohnungseigentum ist das mit dem Wohnungseigentum verbundene Recht, andere, mit dem Wohnungseigentumsobjekt baulich nicht verbundene Teile der Liegenschaft, wie etwa Keller- oder Dachbodenräume, Hausgärten oder Lagerplätze, ausschließlich zu nutzen. (Auszug §2 (3))
Allgemeine Teile der Liegenschaft sind solche, die der allgemeinen Benützung dienen oder deren Zweckbestimmung einer ausschließlichen Benützung entgegensteht. (Auszug §2 (4))
Der Nutzwert ist die Maßzahl, mit der der Wert eines Wohnungseigentumsobjekts im Verhältnis zu den Werten der anderen Wohnungseigentumsobjekte der Liegenschaft bezeichnet wird. Er ergibt sich aus der Nutzfläche des Objekts und aus Zuschlägen oder Abstrichen für werterhöhende oder wertvermindernde Eigenschaften desselben. (Auszug §2 (8))
Der Mindestanteil ist jener Miteigentumsanteil an der Liegenschaft, der zum Erwerb von Wohnungseigentum an einem Wohnungseigentumsobjekt erforderlich ist. Er entspricht dem Verhältnis des Nutzwerts des Objekts zur Summe der Nutzwerte aller Wohnungseigentumsobjekte der Liegenschaft. (Auszug §2 (9))
Der Nutzwert ist in einer ganzen Zahl auszudrücken, wobei Teilbeträge unter 0,5 abgerundet und ab 0,5 aufgerundet werden. Er ist aus der Nutzfläche und aus Zuschlägen oder Abstrichen für Umstände zu berechnen, die nach der Verkehrsauffassung den Wert des Wohnungseigentumsobjekts erhöhen oder vermindern, wie etwa dessen Zweckbestimmung, Stockwerkslage, Lage innerhalb eines Stockwerks oder dessen Ausstattung mit offenen Balkonen, Terrassen und Zubehörobjekten (Auszug §8 (1))
Zuschläge für die Ausstattung mit Zubehörobjekten sowie mit offenen Balkonen und Terrassen sind in einer ganzen Zahl auszudrücken; der Zuschlag ist jedoch mindestens mit der Zahl Eins anzusetzen. (Auszug §8 (2))
Die Wohnungsobjekte erhalten den Buchstaben "W" der Nummer vorangestellt. Die Kfz-Stellplätze erhalten den Buchstaben "P" der Nummer vorangestellt.
Bei den Zubehörobjekten sind die Keller mit einem vorangestellten "K" gekennzeichnet, die Gärten mit einem "G".
Es wird vorgeschlagen, die Nutzwerte wie folgt zu bestimmen:
Die Wohnung W07 ist eine Dreizimmerwohnung, liegt im ersten Obergeschoß und ihre Haupträume sind nach Westen orientiert. Diese Wohnung erhält den Regelnutzwert von 1,00.
Folgende Kriterien werden für die Nutzwertberechnung berücksichtigt:
Erdgeschoßlage:
Die Lage im Erdgeschoß führt zu einer Beeinträchtigung durch Einsehbarkeit von den direkt angrenzenden Allgemeinflächen (Zugänge, Wege). Weiters erfolgen Beeinträchtigungen durch den Geländeverlauf, wenn im Nahbereich der Einheit eine nach oben führenden Böschung die Aussicht beeinträchtigt und auch durch das auf dem Bauplatz befindliche Zweitgebäude.
Die Einheit W01 wird durch den direkt im Osten vorbeiführenden Zugangsbereich beeinträchtigt und um -2,5% abgewertet.
Die Einheit W02 wird durch die südlich bzw. südöstlich liegende Böschung sowie durch den Fußweg beeinträchtigt und um -5,0% abgewertet.
Die Einheit W03 orientiert sich mit dem Hauptraum direkt auf das nebenan errichtete Haus B, was an dieser Stelle drei oberirdische Geschoße aufweist. Diese Einheit wird daher um -5,0% abgewertet.
Die Wohnung W11 wird durch den direkt im Osten vorbeiführenden Zugangsbereich beeinträchtigt und um -2,5% abgewertet.
Die Wohneinheit W12 wird durch die südliche Böschung und im Osten durch den Zugangsweg beeinträchtigt und somit um -5,0% abgewertet.
Die Einheit W13 wird durch die im Süden und Westen angelegte Böschung beeinträchtigt und daher um -5,0% abgewertet.
Lage im letzten Geschoß:
Die Wohnungen im letzten Geschoß (Durch den Geländeverlauf betrifft das beim Haus A das 2. Obergeschoß und beim Haus B das 3.) werden aufgrund der günstigeren Aussichts- und Besonnungsmöglichkeit um 2,5% aufgewertet.
Außer die Wohnung W20: Hier ist durch die gute dreiseitige Orientierung nach Süden, Osten und Westen ein Zuschlag von insgesamt 5,0% gerechtfertigt.
KFZ-Abstellplätze:
Die Stellplätze in der Tiefgarage werden mit 55% des Regelnutzwertes bewertet.
Jene in der Tiefgarage, welche eine Übergröße aufweisen mit 50%.
Die Balkon- und Terrassenflächen werden mit 25% des Regelnutzwertes in Ansatz gebracht.
Hinweis: Einige Wohnungen werden insgesamt um 2,5% auf- bzw. abgewertet. Unter dem Punkt 3.30 Nutzwertberechnung wird dies für die einzelnen Wohnungen nachvollziehbar dargestellt. Hier wird der Faktor auf zwei Stellen gerundet angeschrieben, jedoch richtigerweise mit 97,5% bzw. 102,5% berechnet.
Bemerkung: Nach Rücksprache mit dem Auftraggeber (Freigabe am 29.09.2014) wurden folgende Flächen wie im aktuellen Außenanlagenplan (Eingang 25.09.2014, vom Architekten) dargestellt in Ansatz gebracht:
Die Terrasse W02 wurde nach Westen hin verschoben. Der Garten G02 wurde aufgrund des Fußweges verändert. Die Gärten der Wohnungen W12 und W13 werden in ihrem Flächenausmaß so wie in den Verkaufsunterlagen dargestellt in Ansatz gebracht.
Die Gartenflächen werden mit 5% ihres Flächenausmaßes in Ansatz gebracht.
Die Kellerabteile (Lattenverschlag) werden mit 15% ihrer Fläche berechnet.
Liegenschaftsadresse|###LIEGENSCHAFTSADRESSE###
Grundbuch|###GRUNDBUCH###
Einlagezahl|###EINLAGEZAHL###
Grundstücksnummer|###GSTNR###
Bezirksgericht|###BEZIRKSGERICHT###
Es wird bestätigt, dass die Wohnanlage (Gst-Nr. ###GSTNR### In EZ ###EINLAGEZAHL###) folgende Einheiten umfasst, an welchen Wohnungseigentum begründet wird:
Grundlage ist die Einreichplanung mit dem Baubescheid Zl. ###BAUBESCHEID### sowie die Werkplanung.
XX Wohnungen (mit vorangestelltem "W") samt Zubehör.
XX Kfz-Stellplätze in der Tiefgarage (mit vorangestelltem "P")
Weitere XX Stellplätze in der Tiefgarage sowie XX freie Stellplätze verbleiben laut Widmung zur allgemeinen Benützung.
Wohnungseigentum ist das dem Miteigentümer einer Liegenschaft oder einer Eigentümerpartnerschaft eingeräumte dingliche Recht, ein Wohnungseigentumsobjekt ausschließlich zu nutzen und allein darüber zu verfügen. (Auszug §2 (1))
Wohnungseigentumsobjekte sind Wohnungen, sonstige selbständige Räumlichkeiten und Abstellplätze für Kraftfahrzeuge (wohnungseigentumstaugliche Objekte), an denen Wohnungseigentum begründet wurde. (Auszug §2 (2))
Eine Wohnung ist ein baulich abgeschlossener, nach der Verkehrsauffassung selbständiger Teil eines Gebäudes, der nach seiner Art und Größe geeignet ist, der Befriedigung eines individuellen Wohnbedürfnisses von Menschen zu dienen. Eine sonstige selbständige Räumlichkeit ist ein baulich abgeschlossener, nach der Verkehrsauffassung selbständiger Teil eines Gebäudes, dem nach seiner Art und Größe eine erhebliche wirtschaftliche Bedeutung zukommt, ein Abstellplatz für ein Kraftfahrzeug ist eine - etwa durch Bodenmarkierung - deutlich abgegrenzte Bodenfläche, die ausschließlich zum Abstellen eines Kraftfahrzeugs gewidmet und dazu nach ihrer Größe, Lage und Beschaffenheit geeignet ist. (Auszug §2 (2))
Zubehör-Wohnungseigentum ist das mit dem Wohnungseigentum verbundene Recht, andere, mit dem Wohnungseigentumsobjekt baulich nicht verbundene Teile der Liegenschaft, wie etwa Keller- oder Dachbodenräume, Hausgärten oder Lagerplätze, ausschließlich zu nutzen. (Auszug §2 (3))
Allgemeine Teile der Liegenschaft sind solche, die der allgemeinen Benützung dienen oder deren Zweckbestimmung einer ausschließlichen Benützung entgegensteht. (Auszug §2 (4))
Der Nutzwert ist die Maßzahl, mit der der Wert eines Wohnungseigentumsobjekts im Verhältnis zu den Werten der anderen Wohnungseigentumsobjekte der Liegenschaft bezeichnet wird. Er ergibt sich aus der Nutzfläche des Objekts und aus Zuschlägen oder Abstrichen für werterhöhende oder wertvermindernde Eigenschaften desselben. (Auszug §2 (8))
Der Mindestanteil ist jener Miteigentumsanteil an der Liegenschaft, der zum Erwerb von Wohnungseigentum an einem Wohnungseigentumsobjekt erforderlich ist. Er entspricht dem Verhältnis des Nutzwerts des Objekts zur Summe der Nutzwerte aller Wohnungseigentumsobjekte der Liegenschaft. (Auszug §2 (9))
Der Nutzwert ist in einer ganzen Zahl auszudrücken, wobei Teilbeträge unter 0,5 abgerundet und ab 0,5 aufgerundet werden. Er ist aus der Nutzfläche und aus Zuschlägen oder Abstrichen für Umstände zu berechnen, die nach der Verkehrsauffassung den Wert des Wohnungseigentumsobjekts erhöhen oder vermindern, wie etwa dessen Zweckbestimmung, Stockwerkslage, Lage innerhalb eines Stockwerks oder dessen Ausstattung mit offenen Balkonen, Terrassen und Zubehörobjekten (Auszug §8 (1))
Zuschläge für die Ausstattung mit Zubehörobjekten sowie mit offenen Balkonen und Terrassen sind in einer ganzen Zahl auszudrücken; der Zuschlag ist jedoch mindestens mit der Zahl Eins anzusetzen. (Auszug §8 (2))
Die Wohnungsobjekte erhalten den Buchstaben "W" der Nummer vorangestellt. Die Kfz-Stellplätze erhalten den Buchstaben "P" der Nummer vorangestellt.
Bei den Zubehörobjekten sind die Keller mit einem vorangestellten "K" gekennzeichnet, die Gärten mit einem "G".
Es wird vorgeschlagen, die Nutzwerte wie folgt zu bestimmen:
Die Wohnung W07 ist eine Dreizimmerwohnung, liegt im ersten Obergeschoß und ihre Haupträume sind nach Westen orientiert. Diese Wohnung erhält den Regelnutzwert von 1,00.
Folgende Kriterien werden für die Nutzwertberechnung berücksichtigt:
Erdgeschoßlage:
Die Lage im Erdgeschoß führt zu einer Beeinträchtigung durch Einsehbarkeit von den direkt angrenzenden Allgemeinflächen (Zugänge, Wege). Weiters erfolgen Beeinträchtigungen durch den Geländeverlauf, wenn im Nahbereich der Einheit eine nach oben führenden Böschung die Aussicht beeinträchtigt und auch durch das auf dem Bauplatz befindliche Zweitgebäude.
Die Einheit W01 wird durch den direkt im Osten vorbeiführenden Zugangsbereich beeinträchtigt und um -2,5% abgewertet.
Die Einheit W02 wird durch die südlich bzw. südöstlich liegende Böschung sowie durch den Fußweg beeinträchtigt und um -5,0% abgewertet.
Die Einheit W03 orientiert sich mit dem Hauptraum direkt auf das nebenan errichtete Haus B, was an dieser Stelle drei oberirdische Geschoße aufweist. Diese Einheit wird daher um -5,0% abgewertet.
Die Wohnung W11 wird durch den direkt im Osten vorbeiführenden Zugangsbereich beeinträchtigt und um -2,5% abgewertet.
Die Wohneinheit W12 wird durch die südliche Böschung und im Osten durch den Zugangsweg beeinträchtigt und somit um -5,0% abgewertet.
Die Einheit W13 wird durch die im Süden und Westen angelegte Böschung beeinträchtigt und daher um -5,0% abgewertet.
Lage im letzten Geschoß:
Die Wohnungen im letzten Geschoß (Durch den Geländeverlauf betrifft das beim Haus A das 2. Obergeschoß und beim Haus B das 3.) werden aufgrund der günstigeren Aussichts- und Besonnungsmöglichkeit um 2,5% aufgewertet.
Außer die Wohnung W20: Hier ist durch die gute dreiseitige Orientierung nach Süden, Osten und Westen ein Zuschlag von insgesamt 5,0% gerechtfertigt.
KFZ-Abstellplätze:
Die Stellplätze in der Tiefgarage werden mit 55% des Regelnutzwertes bewertet.
Jene in der Tiefgarage, welche eine Übergröße aufweisen mit 50%.
Die Balkon- und Terrassenflächen werden mit 25% des Regelnutzwertes in Ansatz gebracht.
Hinweis: Einige Wohnungen werden insgesamt um 2,5% auf- bzw. abgewertet. Unter dem Punkt 3.30 Nutzwertberechnung wird dies für die einzelnen Wohnungen nachvollziehbar dargestellt. Hier wird der Faktor auf zwei Stellen gerundet angeschrieben, jedoch richtigerweise mit 97,5% bzw. 102,5% berechnet.
Bemerkung: Nach Rücksprache mit dem Auftraggeber (Freigabe am 29.09.2014) wurden folgende Flächen wie im aktuellen Außenanlagenplan (Eingang 25.09.2014, vom Architekten) dargestellt in Ansatz gebracht:
Die Terrasse W02 wurde nach Westen hin verschoben. Der Garten G02 wurde aufgrund des Fußweges verändert. Die Gärten der Wohnungen W12 und W13 werden in ihrem Flächenausmaß so wie in den Verkaufsunterlagen dargestellt in Ansatz gebracht.
Die Gartenflächen werden mit 5% ihres Flächenausmaßes in Ansatz gebracht.
Die Kellerabteile (Lattenverschlag) werden mit 15% ihrer Fläche berechnet.
X&&j.top4){let H=a.pos-(C-4);for(;a.pos>H;)w=m(S,x,w)}x[--w]=q,x[--w]=ie-S,x[--w]=E-S,x[--w]=j}else C==-3?l=j:C==-4&&(c=j);return w}let g=[],X=[];for(;a.pos>0;)h(O.start||0,O.bufferStart||0,g,X,-1,0);let T=(e=O.length)!==null&&e!==void 0?e:g.length?X[0]+g[0].length:0;return new D(o[O.topID],g.reverse(),X.reverse(),T)}var Ud=new WeakMap;function _n(O,e){if(!O.isAnonymous||e instanceof Kt||e.type!=O)return 1;let t=Ud.get(e);if(t==null){t=1;for(let i of e.children){if(i.type!=O||!(i instanceof D)){t=1;break}t+=_n(O,i)}Ud.set(e,t)}return t}function So(O,e,t,i,r,n,s,a,o){let l=0;for(let u=i;ua&&t.splice(n+1,0,new Ue(a,o.to))):o.to>a?t[n--]=new Ue(a,o.to):t.splice(n--,1))}}return i}function JS(O,e,t,i){let r=0,n=0,s=!1,a=!1,o=-1e9,l=[];for(;;){let c=r==O.length?1e9:s?O[r].to:O[r].from,h=n==e.length?1e9:a?e[n].to:e[n].from;if(s!=a){let f=Math.max(o,t),Q=Math.min(c,h,i);fnew Ue(f.from+i,f.to+i)),h=JS(e,c,o,l);for(let f=0,Q=o;;f++){let u=f==h.length,$=u?l:h[f].from;if($>Q&&t.push(new Vt(Q,$,r.tree,-s,n.from>=Q||n.openStart,n.to<=$||n.openEnd)),u)break;Q=h[f].to}}else t.push(new Vt(o,l,r.tree,-s,n.from>=s||n.openStart,n.to<=a||n.openEnd))}return t}var eX=0,Ne=class O{constructor(e,t,i,r){this.name=e,this.set=t,this.base=i,this.modified=r,this.id=eX++}toString(){let{name:e}=this;for(let t of this.modified)t.name&&(e=`${t.name}(${e})`);return e}static define(e,t){let i=typeof e=="string"?e:"?";if(e instanceof O&&(t=e),t?.base)throw new Error("Can not derive from a modified tag");let r=new O(i,[],null,[]);if(r.set.push(r),t)for(let n of t.set)r.set.push(n);return r}static defineModifier(e){let t=new Cn(e);return i=>i.modified.indexOf(t)>-1?i:Cn.get(i.base||i,i.modified.concat(t).sort((r,n)=>r.id-n.id))}},tX=0,Cn=class O{constructor(e){this.name=e,this.instances=[],this.id=tX++}static get(e,t){if(!t.length)return e;let i=t[0].instances.find(a=>a.base==e&&OX(t,a.modified));if(i)return i;let r=[],n=new Ne(e.name,r,e,t);for(let a of t)a.instances.push(n);let s=iX(t);for(let a of e.set)if(!a.modified.length)for(let o of s)r.push(O.get(a,o));return n}};function OX(O,e){return O.length==e.length&&O.every((t,i)=>t==e[i])}function iX(O){let e=[[]];for(let t=0;t