wagtail-enap-designsystem 1.2.1.141__py3-none-any.whl → 1.2.1.142__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,52 @@
1
+ # Generated by Django 5.1.6 on 2025-09-16 16:36
2
+
3
+ import django.db.models.deletion
4
+ import wagtail.fields
5
+ from django.db import migrations, models
6
+
7
+
8
+ class Migration(migrations.Migration):
9
+
10
+ dependencies = [
11
+ (
12
+ "enap_designsystem",
13
+ "0413_showcasecomponentespage_alter_areaaluno_body_and_more",
14
+ ),
15
+ ("wagtailcore", "0094_alter_page_locale"),
16
+ ]
17
+
18
+ operations = [
19
+ migrations.CreateModel(
20
+ name="ShowcaseComponentesDireto",
21
+ fields=[
22
+ (
23
+ "page_ptr",
24
+ models.OneToOneField(
25
+ auto_created=True,
26
+ on_delete=django.db.models.deletion.CASCADE,
27
+ parent_link=True,
28
+ primary_key=True,
29
+ serialize=False,
30
+ to="wagtailcore.page",
31
+ ),
32
+ ),
33
+ (
34
+ "description",
35
+ wagtail.fields.RichTextField(
36
+ blank=True,
37
+ default="Showcase com renderização direta dos componentes usando valores padrão",
38
+ help_text="Descrição da biblioteca de componentes",
39
+ verbose_name="Descrição",
40
+ ),
41
+ ),
42
+ ],
43
+ options={
44
+ "verbose_name": "Showcase Direto de Componentes",
45
+ "verbose_name_plural": "Showcases Diretos de Componentes",
46
+ },
47
+ bases=("wagtailcore.page",),
48
+ ),
49
+ migrations.DeleteModel(
50
+ name="ShowcaseComponentesPage",
51
+ ),
52
+ ]
@@ -5020,4 +5020,239 @@ class SistemaVotacaoPage(Page):
5020
5020
 
5021
5021
  if self.data_fim and now > self.data_fim:
5022
5022
  return False
5023
- return True
5023
+ return True
5024
+
5025
+
5026
+
5027
+
5028
+
5029
+
5030
+
5031
+ from wagtail.models import Page
5032
+ from wagtail.fields import RichTextField, StreamField
5033
+ from wagtail.admin.panels import FieldPanel
5034
+
5035
+ from .blocks import LAYOUT_STREAMBLOCKS
5036
+
5037
+ class ShowcaseComponentesDireto(Page):
5038
+ """
5039
+ Showcase que renderiza componentes diretamente no template
5040
+ usando valores padrão dos componentes
5041
+ """
5042
+
5043
+ description = RichTextField(
5044
+ verbose_name="Descrição",
5045
+ help_text="Descrição da biblioteca de componentes",
5046
+ blank=True,
5047
+ default="Showcase com renderização direta dos componentes usando valores padrão"
5048
+ )
5049
+
5050
+ content_panels = Page.content_panels + [
5051
+ FieldPanel('description'),
5052
+ ]
5053
+
5054
+ template = 'enap_designsystem/pages/showcase_components.html'
5055
+
5056
+ class Meta:
5057
+ verbose_name = "Showcase Direto de Componentes"
5058
+ verbose_name_plural = "Showcases Diretos de Componentes"
5059
+
5060
+ def get_context(self, request):
5061
+ context = super().get_context(request)
5062
+
5063
+ try:
5064
+ # Organizar componentes por categoria
5065
+ categories_with_components = self.get_rendered_categories()
5066
+
5067
+ context.update({
5068
+ 'categories_with_components': categories_with_components,
5069
+ 'total_components': sum(len(cat['rendered_components']) for cat in categories_with_components.values()),
5070
+ 'total_categories': len(categories_with_components),
5071
+ 'page_title': 'Showcase Direto - Componentes ENAP',
5072
+ 'page_description': 'Visualização direta dos componentes com valores padrão'
5073
+ })
5074
+ except Exception as e:
5075
+ context.update({
5076
+ 'error_message': f'Erro ao carregar componentes: {str(e)}',
5077
+ 'categories_with_components': {},
5078
+ 'total_components': 0,
5079
+ 'total_categories': 0,
5080
+ })
5081
+
5082
+ return context
5083
+
5084
+ def get_rendered_categories(self):
5085
+ """Retorna categorias com componentes já renderizados"""
5086
+ categories = {}
5087
+ layout_streamblocks = LAYOUT_STREAMBLOCKS
5088
+
5089
+ # Mapeamento de ícones
5090
+ category_icons = {
5091
+ 'banners': 'image',
5092
+ 'galerias': 'images',
5093
+ 'carousels': 'arrows-up-down',
5094
+ 'dashboards': 'bar-chart',
5095
+ 'formularios': 'form',
5096
+ 'cursos': 'graduation-cap',
5097
+ 'eventos': 'calendar',
5098
+ 'navegacao': 'bars',
5099
+ 'menus': 'list-ul',
5100
+ 'botoes': 'mouse-pointer',
5101
+ 'conteudo': 'file-text',
5102
+ 'secoes': 'th-large',
5103
+ 'cards': 'clone',
5104
+ 'interativos': 'cogs',
5105
+ 'midia': 'play-circle',
5106
+ 'especialidades': 'puzzle-piece',
5107
+ }
5108
+
5109
+ # Descrições das categorias
5110
+ category_descriptions = {
5111
+ 'banners': 'Componentes para banners, heroes e seções de destaque visual',
5112
+ 'galerias': 'Componentes para exibição de imagens, galerias e portfolios',
5113
+ 'carousels': 'Componentes de carrosséis, sliders e apresentações rotativas',
5114
+ 'dashboards': 'Componentes para dashboards, KPIs, métricas e visualização de dados',
5115
+ 'formularios': 'Componentes de formulários, campos de entrada e interação',
5116
+ 'cursos': 'Componentes específicos para cursos, educação e capacitação',
5117
+ 'eventos': 'Componentes para eventos, cronogramas, timelines e agenda',
5118
+ 'navegacao': 'Componentes de navegação, menus e estrutura de site',
5119
+ 'menus': 'Componentes de menu e navegação',
5120
+ 'botoes': 'Componentes de botões, call-to-actions e elementos clicáveis',
5121
+ 'conteudo': 'Componentes de conteúdo, texto rico, citações e mídia',
5122
+ 'secoes': 'Componentes de seções, containers e estruturas de layout',
5123
+ 'cards': 'Componentes de cards, grids e elementos organizacionais',
5124
+ 'interativos': 'Componentes interativos, acordeões, modais e elementos dinâmicos',
5125
+ 'midia': 'Componentes de vídeo, áudio, podcasts e conteúdo multimídia',
5126
+ 'especialidades': 'Componentes especializados e funcionalidades específicas da ENAP',
5127
+ }
5128
+
5129
+ for stream_name, stream_block in layout_streamblocks:
5130
+ # Pular categorias complexas
5131
+ if stream_name in ['enap_section', 'recaptcha']:
5132
+ continue
5133
+
5134
+ if not hasattr(stream_block, 'child_blocks'):
5135
+ continue
5136
+
5137
+ category_info = {
5138
+ 'name': stream_name,
5139
+ 'display_name': self.get_category_display_name(stream_block, stream_name),
5140
+ 'icon': category_icons.get(stream_name, 'cube'),
5141
+ 'description': category_descriptions.get(stream_name, f'Componentes da categoria {stream_name}'),
5142
+ 'rendered_components': []
5143
+ }
5144
+
5145
+ # Renderizar cada componente da categoria
5146
+ for component_name, component_block in stream_block.child_blocks.items():
5147
+ rendered_component = self.render_component_with_defaults(
5148
+ component_name, component_block, stream_name
5149
+ )
5150
+ if rendered_component:
5151
+ category_info['rendered_components'].append(rendered_component)
5152
+
5153
+ # Só adicionar categoria se tiver componentes renderizados
5154
+ if category_info['rendered_components']:
5155
+ categories[stream_name] = category_info
5156
+
5157
+ return categories
5158
+
5159
+ def get_category_display_name(self, stream_block, stream_name):
5160
+ """Obtém nome de exibição da categoria"""
5161
+ try:
5162
+ category_meta = getattr(stream_block.__class__, 'Meta', None)
5163
+ if category_meta and hasattr(category_meta, 'label'):
5164
+ return category_meta.label
5165
+ except:
5166
+ pass
5167
+
5168
+ return stream_name.replace('_', ' ').title()
5169
+
5170
+ def render_component_with_defaults(self, component_name, component_block, category_name):
5171
+ """Renderiza um componente usando valores padrão"""
5172
+ try:
5173
+ # Gerar dados padrão inteligentes
5174
+ default_data = self.get_smart_defaults(component_name, component_block)
5175
+
5176
+ # Tentar renderizar
5177
+ try:
5178
+ rendered_html = component_block.render(default_data)
5179
+ except Exception as render_error:
5180
+ # Se falhar com dados padrão, tentar sem dados
5181
+ try:
5182
+ rendered_html = component_block.render({})
5183
+ except:
5184
+ # Se ainda falhar, criar um placeholder
5185
+ rendered_html = f'<div style="padding: 1rem; background: #f3f4f6; border-radius: 8px; text-align: center; color: #6b7280;"><p>Componente {component_name}</p><small>Erro na renderização: {str(render_error)}</small></div>'
5186
+
5187
+ return {
5188
+ 'name': component_name,
5189
+ 'display_name': self.get_component_display_name(component_block),
5190
+ 'class_name': component_block.__class__.__name__,
5191
+ 'rendered_html': rendered_html,
5192
+ 'category_name': category_name,
5193
+ 'has_error': 'Erro na renderização' in rendered_html,
5194
+ 'field_count': len(getattr(component_block, 'child_blocks', {}))
5195
+ }
5196
+
5197
+ except Exception as e:
5198
+ print(f"Erro ao processar componente {component_name}: {e}")
5199
+ return None
5200
+
5201
+ def get_component_display_name(self, component_block):
5202
+ """Obtém nome de exibição do componente"""
5203
+ if hasattr(component_block, 'label') and component_block.label:
5204
+ label = component_block.label
5205
+ # Remove emojis do início
5206
+ if any(label.startswith(emoji) for emoji in ['🎯', '🎨', '🏢', '🚀', '🔍', '📑', '🖼️', '⭐', '🎬']):
5207
+ parts = label.split(' ', 1)
5208
+ if len(parts) > 1:
5209
+ return parts[1]
5210
+ return label
5211
+
5212
+ return component_block.__class__.__name__.replace('Block', '').replace('_', ' ')
5213
+
5214
+ def get_smart_defaults(self, component_name, component_block):
5215
+ """Gera valores padrão inteligentes para o componente"""
5216
+ defaults = {}
5217
+
5218
+ if not hasattr(component_block, 'child_blocks'):
5219
+ return defaults
5220
+
5221
+ for field_name, field_block in component_block.child_blocks.items():
5222
+ field_type = field_block.__class__.__name__
5223
+
5224
+ # Usar valor padrão do campo se existir
5225
+ if hasattr(field_block, 'default') and field_block.default is not None:
5226
+ defaults[field_name] = field_block.default
5227
+ continue
5228
+
5229
+ # Gerar valores contextuais baseados no nome do campo
5230
+ field_lower = field_name.lower()
5231
+
5232
+ if 'title' in field_lower or 'titulo' in field_lower:
5233
+ defaults[field_name] = 'Escola Nacional de Administração Pública'
5234
+ elif 'subtitle' in field_lower or 'subtitulo' in field_lower:
5235
+ defaults[field_name] = 'Excelência em capacitação para o serviço público'
5236
+ elif 'text' in field_lower or 'texto' in field_lower:
5237
+ defaults[field_name] = 'A ENAP é responsável pela capacitação de servidores públicos federais, contribuindo para a modernização da administração pública.'
5238
+ elif 'description' in field_lower or 'descricao' in field_lower:
5239
+ defaults[field_name] = 'Componente do Design System ENAP para construção de interfaces modernas.'
5240
+ elif 'button' in field_lower or 'botao' in field_lower:
5241
+ defaults[field_name] = 'Saiba Mais'
5242
+ elif 'url' in field_lower or 'link' in field_lower:
5243
+ defaults[field_name] = 'https://www.enap.gov.br'
5244
+ elif 'email' in field_lower:
5245
+ defaults[field_name] = 'contato@enap.gov.br'
5246
+ elif field_type == 'BooleanBlock':
5247
+ defaults[field_name] = True
5248
+ elif field_type in ['IntegerBlock', 'FloatBlock']:
5249
+ defaults[field_name] = 42
5250
+ elif field_type == 'DateBlock':
5251
+ defaults[field_name] = '2024-03-15'
5252
+ elif field_type == 'RichTextBlock':
5253
+ defaults[field_name] = '<p>Conteúdo de <strong>exemplo</strong> para demonstração do componente.</p>'
5254
+ else:
5255
+ # Valor genérico baseado no nome do campo
5256
+ defaults[field_name] = f'Exemplo {field_name}'
5257
+
5258
+ return defaults
@@ -42,7 +42,6 @@
42
42
 
43
43
  p {
44
44
  font-weight: 400;
45
- color: #434A54;
46
45
  line-height: 150%;
47
46
  font-size: 16px;
48
47
  word-wrap: break-word;
@@ -9,7 +9,15 @@
9
9
  <meta name="author" content="ENAP - Escola Nacional de Administração Pública">
10
10
  <meta name="theme-color" content="#0066cc">
11
11
  {% block metadata %}{% endblock %}
12
-
12
+
13
+ <!-- Google Tag Manager -->
14
+ <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
15
+ new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
16
+ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
17
+ 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
18
+ })(window,document,'script','dataLayer','GTM-WR2M7N2F');</script>
19
+ <!-- End Google Tag Manager -->
20
+
13
21
  {% block title %}
14
22
  <title>{% if page.page_title and page.page_title|length > 0 %}{{ page.page_title }}{% else %}ENAP - Escola Nacional de Administração Pública{% endif %}</title>
15
23
  {% endblock %}
@@ -148,6 +156,11 @@
148
156
  </head>
149
157
 
150
158
  <body>
159
+ <!-- Google Tag Manager (noscript) -->
160
+ <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-WR2M7N2F"
161
+ height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
162
+ <!-- End Google Tag Manager (noscript) -->
163
+
151
164
  <a class="visually-hidden-focusable" href="#main-content">Pular para o conteúdo principal</a>
152
165
 
153
166
  <section class="page-wrapper">
@@ -1,109 +1,5 @@
1
1
  <!-- enap_designsystem/blocks/cards_titles.html -->
2
2
  {% load wagtailcore_tags wagtailimages_tags %}
3
- <section class="secao-apresentacao-cards">
4
- <!-- Background com imagem se fornecida -->
5
- <div class="secao-background"
6
- {% if value.background_image_fundo_bg %}
7
- style="background-image: url('{{ value.background_image_fundo_bg.url }}'); background-size: cover; background-position: center; background-repeat: no-repeat;"
8
- {% else %}
9
- style="background: {{ value.cor_fundo }};"
10
- {% endif %}>
11
-
12
- <!-- Overlay para garantir legibilidade -->
13
- <div class="secao-overlay">
14
-
15
- <!-- Container principal -->
16
- <div class="container titulo-cards mx-auto px-4 py-16 lg:py-24">
17
-
18
- <!-- Título centralizado -->
19
- {% if value.titulo %}
20
- <div class="text-center mb-12 lg:mb-16">
21
- <h2 class="titulo-secao"
22
- style="color: {{ value.cor_titulo|default:'#FFFFFF' }};">
23
- {{ value.titulo }}
24
- </h2>
25
- </div>
26
- {% endif %}
27
-
28
- <!-- Grid de Cards -->
29
- {% if value.cards %}
30
- <div class="cards-container {{ value.layout_cards|default:'cards-3-colunas' }}">
31
- {% for card in value.cards %}
32
- {% if card.block_type == 'card' %}
33
- <div class="card-item">
34
- <div class="card-apresentacao" style="background: {{ value.cor_fundo_cards }}">
35
-
36
- <!-- Imagem do card -->
37
- {% if card.value.image %}
38
- <div class="card-imagem">
39
- {% image card.value.image width-400 as card_img %}
40
- <img src="{{ card_img.url }}"
41
- alt="{{ card.value.title|default:'Card' }}"
42
- class="card-img">
43
- </div>
44
- {% endif %}
45
-
46
- <!-- Conteúdo do card -->
47
- <div class="card-conteudo">
48
-
49
- <!-- Subtítulo/Cargo -->
50
- {% if card.value.subtitle %}
51
- <p class="card-subtitulo" style="color: {{ value.cor_texto_cards }};">
52
- {{ card.value.subtitle }}
53
- </p>
54
- {% endif %}
55
-
56
- <!-- Título -->
57
- {% if card.value.title %}
58
- <h3 class="card-titulo" style="color: {{ value.cor_titulo_cards }};">
59
- {{ card.value.title }}
60
- </h3>
61
- {% endif %}
62
-
63
- <!-- Descrição -->
64
- {% if card.value.description %}
65
- <div class="card-descricao" style="color: {{ value.cor_texto_cards }};">
66
- {{ card.value.description|richtext }}
67
- </div>
68
- {% endif %}
69
-
70
- <!-- Link/Botão -->
71
- {% if card.value.link_url %}
72
- <div class="card-acao">
73
- <a href="{{ card.value.link_url }}"
74
- class="card-link" style="color: {{ value.cor_titulo_cards }};"
75
- {% if card.value.link_target %}target="{{ card.value.link_target }}"{% endif %}>
76
- {{ card.value.link_text|default:'Saiba mais' }}
77
- <svg class="link-arrow" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
78
- <path d="M5 12h14M12 5l7 7-7 7"/>
79
- </svg>
80
- </a>
81
- </div>
82
- {% endif %}
83
-
84
- </div>
85
-
86
- </div>
87
- </div>
88
- {% endif %}
89
- {% endfor %}
90
- </div>
91
- {% endif %}
92
-
93
- {% if value.link_url %}
94
- <div class="card-acao" style="text-align: center;">
95
- <a href="{{ value.link_url }}"
96
- class="card-link" style="color: {{ value.cor_botao_texto }}; background: {{ value.cor_botao }}; padding: 12px 42px; border-radius: 32px;"
97
- {% if value.link_target %}target="{{ value.link_target }}"{% endif %}>
98
- {{ value.link_text|default:'Saiba mais' }}
99
- </a>
100
- </div>
101
- {% endif %}
102
- </div>
103
- </div>
104
- </div>
105
- </section>
106
-
107
3
  <style>
108
4
  .secao-apresentacao-cards {
109
5
  position: relative;
@@ -150,11 +46,19 @@
150
46
  margin-bottom: 0;
151
47
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
152
48
  font-weight: 500;
153
- font-style: Medium;
154
49
  font-size: 48px;
155
50
  letter-spacing: 0px;
156
51
  }
157
52
 
53
+ .subtitulo-secao p {
54
+ text-align: center;
55
+ font-family: Georama;
56
+ font-weight: 400;
57
+ font-size: 21px;
58
+ line-height: 160%;
59
+ letter-spacing: 0px;
60
+ }
61
+
158
62
  .cards-container {
159
63
  display: grid;
160
64
  gap: 2rem;
@@ -338,5 +242,118 @@
338
242
  justify-content: center;
339
243
  gap: 48px;
340
244
  }
341
- </style></document_content>
245
+ </style>
246
+
247
+ <section class="secao-apresentacao-cards">
248
+ <!-- Background com imagem se fornecida -->
249
+ <div class="secao-background"
250
+ {% if value.background_image_fundo_bg %}
251
+ style="background-image: url('{{ value.background_image_fundo_bg.url }}'); background-size: cover; background-position: center; background-repeat: no-repeat;"
252
+ {% else %}
253
+ style="background: {{ value.cor_fundo }};"
254
+ {% endif %}>
255
+
256
+ <!-- Overlay para garantir legibilidade -->
257
+ <div class="secao-overlay">
258
+
259
+ <!-- Container principal -->
260
+ <div class="container titulo-cards mx-auto px-4 py-16 lg:py-24">
261
+
262
+ <!-- Título centralizado -->
263
+ {% if value.titulo %}
264
+ <div class="text-center mb-12 lg:mb-16">
265
+ <h2 class="titulo-secao"
266
+ style="color: {{ value.cor_titulo|default:'#FFFFFF' }};">
267
+ {{ value.titulo }}
268
+ </h2>
269
+ </div>
270
+ {% endif %}
271
+
272
+ <!-- Subtítulo centralizado -->
273
+ {% if value.subtitulo %}
274
+ <div class="mb-12 lg:mb-16">
275
+ <span class="subtitulo-secao" style="color: {{ value.cor_titulo|default:'#FFFFFF' }};">{{ value.subtitulo|richtext }}</span>
276
+ </div>
277
+ {% endif %}
278
+
279
+ <!-- Grid de Cards -->
280
+ {% if value.cards %}
281
+ <div class="cards-container {{ value.layout_cards|default:'cards-3-colunas' }}">
282
+ {% for card in value.cards %}
283
+ {% if card.block_type == 'card' %}
284
+ <div class="card-item">
285
+ <div class="card-apresentacao" style="background: {{ value.cor_fundo_cards }}">
286
+
287
+ <!-- Imagem do card -->
288
+ {% if card.value.image %}
289
+ <div class="card-imagem">
290
+ {% image card.value.image width-400 as card_img %}
291
+ <img src="{{ card_img.url }}"
292
+ alt="{{ card.value.title|default:'Card' }}"
293
+ class="card-img">
294
+ </div>
295
+ {% endif %}
296
+
297
+ <!-- Conteúdo do card -->
298
+ <div class="card-conteudo">
299
+
300
+ <!-- Subtítulo/Cargo -->
301
+ {% if card.value.subtitle %}
302
+ <p class="card-subtitulo" style="color: {{ value.cor_texto_cards }};">
303
+ {{ card.value.subtitle }}
304
+ </p>
305
+ {% endif %}
306
+
307
+ <!-- Título -->
308
+ {% if card.value.title %}
309
+ <h3 class="card-titulo" style="color: {{ value.cor_titulo_cards }};">
310
+ {{ card.value.title }}
311
+ </h3>
312
+ {% endif %}
313
+
314
+ <!-- Descrição -->
315
+ {% if card.value.description %}
316
+ <div class="card-descricao" style="color: {{ value.cor_texto_cards }};">
317
+ {{ card.value.description|richtext }}
318
+ </div>
319
+ {% endif %}
320
+
321
+ <!-- Link/Botão -->
322
+ {% if card.value.link_url %}
323
+ <div class="card-acao">
324
+ <a href="{{ card.value.link_url }}"
325
+ class="card-link" style="color: {{ value.cor_titulo_cards }};"
326
+ {% if card.value.link_target %}target="{{ card.value.link_target }}"{% endif %}>
327
+ {{ card.value.link_text|default:'Saiba mais' }}
328
+ <svg class="link-arrow" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
329
+ <path d="M5 12h14M12 5l7 7-7 7"/>
330
+ </svg>
331
+ </a>
332
+ </div>
333
+ {% endif %}
334
+
335
+ </div>
336
+
337
+ </div>
338
+ </div>
339
+ {% endif %}
340
+ {% endfor %}
341
+ </div>
342
+ {% endif %}
343
+
344
+ {% if value.link_url %}
345
+ <div class="card-acao" style="text-align: center;">
346
+ <a href="{{ value.link_url }}"
347
+ class="card-link" style="color: {{ value.cor_botao_texto }}; background: {{ value.cor_botao }}; padding: 12px 42px; border-radius: 32px;"
348
+ {% if value.link_target %}target="{{ value.link_target }}"{% endif %}>
349
+ {{ value.link_text|default:'Saiba mais' }}
350
+ </a>
351
+ </div>
352
+ {% endif %}
353
+ </div>
354
+ </div>
355
+ </div>
356
+ </section>
357
+
358
+ </document_content>
342
359
  </invoke>