shuup.simple_cms package

Submodules

shuup.simple_cms.layout module

class shuup.simple_cms.layout.PageLayout(theme, placeholder_name, rows=None)[source]

Bases: shuup.xtheme.layout._base.Layout

Parameters:
  • placeholder_name (str|None) – The name of the placeholder. Could be None.
  • rows (Iterable[LayoutRow]|None) – Optional iterable of LayoutRows to populate this Layout with.
identifier = 'simple-cms-page-layout'
help_text = 'Content in this placeholder is shown for this page only.'
get_help_text(context)[source]
is_valid_context(context)[source]
get_layout_data_suffix(context)[source]

shuup.simple_cms.models module

class shuup.simple_cms.models.PageOpenGraphType[source]

Bases: enumfields.enums.Enum

An enumeration.

Website = 'website'
Article = 'article'
class shuup.simple_cms.models.PageQuerySet(*args, **kwargs)[source]

Bases: parler.managers.TranslatableQuerySet

not_deleted()[source]
visible(shop, dt=None, user=None)[source]

Get pages that should be publicly visible.

This does not do permission checking.

Parameters:dt (datetime.datetime) – Datetime for visibility check.
Returns:QuerySet of pages.
Return type:QuerySet[Page]
for_user(user)[source]

Get pages that should be visible for the given user.

for_shop(shop)[source]
class shuup.simple_cms.models.Page(id, shop, supplier, available_from, available_to, created_by, modified_by, created_on, modified_on, identifier, visible_in_menu, parent, list_children_on_page, show_child_timestamps, deleted, template_name, render_title)[source]

Bases: mptt.models.MPTTModel, parler.models.TranslatableModel

Parameters:
  • id (AutoField) – Id
  • shop (ForeignKey to shuup.core.models.Shop) – Shop
  • supplier (ForeignKey to shuup.core.models.Supplier) – Supplier
  • available_from (DateTimeField) – Set an available date to restrict the page to be available only after a certain date and time. This is useful for pages describing sales campaigns or other time-sensitive pages.
  • available_to (DateTimeField) – Set an available date to restrict the page to be available only until a certain date and time. This is useful for pages describing sales campaigns or other time-sensitive pages.
  • created_by (ForeignKey to django.contrib.auth.models.User) – Created by
  • modified_by (ForeignKey to django.contrib.auth.models.User) – Modified by
  • created_on (DateTimeField) – Created on
  • modified_on (DateTimeField) – Modified on
  • identifier (InternalIdentifierField) – This identifier can be used in templates to create URLs
  • visible_in_menu (BooleanField) – Enable this if this page should have a visible link in the top menu of the store front.
  • parent (TreeForeignKey to shuup.simple_cms.models.Page) – Set this to a parent page if this page should be subcategorized (sub-menu) under another page.
  • list_children_on_page (BooleanField) – Enable this if this page should display all of its children pages.
  • show_child_timestamps (BooleanField) – Enable this if you want to show timestamps on the child pages. Please note, that this requires the children to be listed on the page as well.
  • deleted (BooleanField) – Deleted
  • template_name (TextField) – Template path
  • render_title (BooleanField) – Enable this if this page should have a visible title.
  • lft (PositiveIntegerField) – Lft
  • rght (PositiveIntegerField) – Rght
  • tree_id (PositiveIntegerField) – Tree id
  • level (PositiveIntegerField) – Level
  • available_permission_groups (ManyToManyField to django.contrib.auth.models.Group) – Select the permission groups that can have access to this page.
  • title (CharField) – (Translatable) The page title. This is shown anywhere links to your page are shown.
  • url (CharField) – (Translatable) The page url. Choose a descriptive url so that search engines can rank your page higher. Often the best url is simply the page title with spaces replaced with dashes.
  • content (TextField) – (Translatable) The page content. This is the text that is displayed when customers click on your page link.You can leave this empty and add all page content through placeholder editor in shop front.To edit the style of the page you can use the Snippet plugin which is in shop front editor.
translations

ManyToOneRel to shuup.simple_cms.models.PageTranslation

children

ManyToOneRel to shuup.simple_cms.models.Page

open_graph

OneToOneRel to shuup.simple_cms.models.PageOpenGraph

log_entries

ManyToOneRel to shuup.simple_cms.models.PageLogEntry

gdprsettings_set

ManyToOneRel to shuup.gdpr.models.GDPRSettings

gdpruserconsentdocument_set

ManyToOneRel to shuup.gdpr.models.GDPRUserConsentDocument

shop

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

supplier

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

available_from

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

available_to

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

available_permission_groups

Accessor to the related objects manager on the forward and reverse sides of a many-to-many relation.

In the example:

class Pizza(Model):
    toppings = ManyToManyField(Topping, related_name='pizzas')

Pizza.toppings and Topping.pizzas are ManyToManyDescriptor instances.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

created_by

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

modified_by

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

created_on

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

modified_on

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

identifier

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

visible_in_menu

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

parent

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

list_children_on_page

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

show_child_timestamps

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

deleted

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

translations

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

template_name

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

render_title

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

objects = <django.db.models.manager.TreeManagerFromPageQuerySet object>
delete(using=None)[source]
soft_delete(user=None)[source]
clean()[source]
is_visible(dt=None)[source]
save(*args, **kwargs)[source]
get_html()[source]
classmethod create_initial_revision(page)[source]
exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

add_log_entry(message, identifier=None, kind=<LogEntryKind.OTHER: 0>, user=None, extra=None, save=True)
children

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

consent_settings

Accessor to the related objects manager on the forward and reverse sides of a many-to-many relation.

In the example:

class Pizza(Model):
    toppings = ManyToManyField(Topping, related_name='pizzas')

Pizza.toppings and Topping.pizzas are ManyToManyDescriptor instances.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

content

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

created_by_id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

gdprsettings_set

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

gdpruserconsentdocument_set

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

get_next_by_created_on(*, field=<django.db.models.fields.DateTimeField: created_on>, is_next=True, **kwargs)
get_next_by_modified_on(*, field=<django.db.models.fields.DateTimeField: modified_on>, is_next=True, **kwargs)
get_previous_by_created_on(*, field=<django.db.models.fields.DateTimeField: created_on>, is_next=False, **kwargs)
get_previous_by_modified_on(*, field=<django.db.models.fields.DateTimeField: modified_on>, is_next=False, **kwargs)
id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

level

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

lft

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

log_entries

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

modified_by_id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

open_graph

Accessor to the related object on the reverse side of a one-to-one relation.

In the example:

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Place.restaurant is a ReverseOneToOneDescriptor instance.

parent_id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

rght

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

shop_id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

supplier_id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

title

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

tree_id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

url

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

class shuup.simple_cms.models.PageOpenGraph(*args, **kwargs)[source]

Bases: parler.models.TranslatableModel

Object that describes Open Graph extra meta attributes.

Parameters:
  • id (AutoField) – Id
  • page (OneToOneField to shuup.simple_cms.models.Page) – Page
  • image (FilerImageField to filer.models.imagemodels.Image) – The image of your object.
  • og_type (EnumField) – Type
  • title (CharField) – (Translatable) The title of your object as it should appear within the graph, e.g. The Rock.
  • description (TextField) – (Translatable) A one to two sentence description of your object.
  • section (CharField) – (Translatable) A high-level section name, e.g. Technology. Only applicable when type is Article.
  • tags (CharField) – (Translatable) Tag words associated with this article. Only applicable when type is Article.
  • article_author (CharField) – (Translatable) The name of the author for the article. Only applicable when type is Article.
translations

ManyToOneRel to shuup.simple_cms.models.PageOpenGraphTranslation

page

Accessor to the related object on the forward side of a one-to-one relation.

In the example:

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Restaurant.place is a ForwardOneToOneDescriptor instance.

image

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

og_type

A property descriptor which ensures that field.to_python() is called on _every_ assignment to the field.

This used to be provided by the django.db.models.subclassing.Creator class, which in turn was used by the deprecated-in-Django-1.10 SubfieldBase class, hence the reimplementation here.

translations

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

article_author

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

description

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

get_og_type_display(*, field=<enumfields.fields.EnumField: og_type>)
id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

image_id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

page_id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

section

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

tags

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

title

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

class shuup.simple_cms.models.PageLogEntry(id, created_on, user, message, identifier, kind, extra, target)

Bases: shuup.utils.analog.BaseLogEntry

Parameters:
  • id (AutoField) – Id
  • created_on (DateTimeField) – Created on
  • user (ForeignKey to django.contrib.auth.models.User) – User
  • message (CharField) – Message
  • identifier (CharField) – Identifier
  • kind (EnumIntegerField) – Log entry kind
  • extra (JSONField) – Extra data
  • target (ForeignKey to shuup.simple_cms.models.Page) – Target
exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

extra

A placeholder class that provides a way to set the attribute on the model.

get_next_by_created_on(*, field=<django.db.models.fields.DateTimeField: created_on>, is_next=True, **kwargs)
get_previous_by_created_on(*, field=<django.db.models.fields.DateTimeField: created_on>, is_next=False, **kwargs)
id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

kind

A property descriptor which ensures that field.to_python() is called on _every_ assignment to the field.

This used to be provided by the django.db.models.subclassing.Creator class, which in turn was used by the deprecated-in-Django-1.10 SubfieldBase class, hence the reimplementation here.

logged_model

alias of Page

objects = <django.db.models.manager.Manager object>
target

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

target_id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

user

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

class shuup.simple_cms.models.PageOpenGraphTranslation(id, language_code, title, description, section, tags, article_author, master)

Bases: parler.models.TranslatedFieldsModel

Parameters:
  • id (AutoField) – Id
  • language_code (HideChoicesCharField) – Language
  • title (CharField) – The title of your object as it should appear within the graph, e.g. The Rock.
  • description (TextField) – A one to two sentence description of your object.
  • section (CharField) – A high-level section name, e.g. Technology. Only applicable when type is Article.
  • tags (CharField) – Tag words associated with this article. Only applicable when type is Article.
  • article_author (CharField) – The name of the author for the article. Only applicable when type is Article.
  • master (TranslationsForeignKey to shuup.simple_cms.models.PageOpenGraph) – Master
exception DoesNotExist

Bases: parler.models.TranslationDoesNotExist, shuup.simple_cms.models.DoesNotExist, shuup.simple_cms.models.DoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

article_author

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

description

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

master

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

master_id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

objects = <django.db.models.manager.Manager object>
section

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

tags

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

title

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

class shuup.simple_cms.models.PageTranslation(id, language_code, title, url, content, master)

Bases: parler.models.TranslatedFieldsModel

Parameters:
  • id (AutoField) – Id
  • language_code (HideChoicesCharField) – Language
  • title (CharField) – The page title. This is shown anywhere links to your page are shown.
  • url (CharField) – The page url. Choose a descriptive url so that search engines can rank your page higher. Often the best url is simply the page title with spaces replaced with dashes.
  • content (TextField) – The page content. This is the text that is displayed when customers click on your page link.You can leave this empty and add all page content through placeholder editor in shop front.To edit the style of the page you can use the Snippet plugin which is in shop front editor.
  • master (TranslationsForeignKey to shuup.simple_cms.models.Page) – Master
exception DoesNotExist

Bases: parler.models.TranslationDoesNotExist, shuup.simple_cms.models.DoesNotExist, shuup.simple_cms.models.DoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

content

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

master

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

master_id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

objects = <django.db.models.manager.Manager object>
title

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

url

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

shuup.simple_cms.plugins module

class shuup.simple_cms.plugins.OrderedModelMultipleChoiceField(queryset, required=True, widget=None, label=None, initial=None, help_text='', *args, **kwargs)[source]

Bases: django.forms.models.ModelMultipleChoiceField

class shuup.simple_cms.plugins.PageLinksConfigForm(**kwargs)[source]

Bases: shuup.xtheme.plugins.forms.GenericPluginForm

A configuration for the PageLinksPlugin

populate()[source]

A custom populate method to display page choices

clean()[source]

A custom clean method to save page configuration information in a serializable form

base_fields = OrderedDict()
declared_fields = OrderedDict()
media
class shuup.simple_cms.plugins.PageLinksPlugin(config)[source]

Bases: shuup.xtheme.TemplatedPlugin

A plugin for displaying links to visible CMS pages in the shop front

Instantiate a Plugin with the given config dictionary.

Parameters:config (dict) – Dictionary of freeform configuration data
identifier = 'simple_cms.page_links'
name = 'CMS Page Links'
template_name = 'shuup/simple_cms/plugins/page_links.jinja'
cacheable = True
editor_form_class

alias of PageLinksConfigForm

fields = [('title', <shuup.xtheme.plugins.forms.TranslatableField object>), ('show_all_pages', <django.forms.fields.BooleanField object>), ('hide_expired', <django.forms.fields.BooleanField object>), 'pages']
get_cache_key(context, **kwargs) → str[source]
get_context_data(context)[source]

A custom get_context_data method to return pages, possibly filtering expired pages based on the plugin’s hide_expired setting

shuup.simple_cms.settings module

shuup.simple_cms.settings.SHUUP_SIMPLE_CMS_DEFAULT_TEMPLATE = 'shuup/simple_cms/page.jinja'

Defines the default and fallback template to be used when rendering CMS pages

shuup.simple_cms.template_helpers module

class shuup.simple_cms.template_helpers.SimpleCMSTemplateHelpers[source]

Bases: object

name = 'simple_cms'
get_page_by_identifier(context, identifier)[source]
get_visible_pages(context)[source]

shuup.simple_cms.templates module

class shuup.simple_cms.templates.SimpleCMSDefaultTemplate[source]

Bases: object

name = 'Default Page'
template_path = 'shuup/simple_cms/page.jinja'
class shuup.simple_cms.templates.SimpleCMSTemplateSidebar[source]

Bases: object

name = 'Page with sidebar'
template_path = 'shuup/simple_cms/page_sidebar.jinja'

shuup.simple_cms.urls module

shuup.simple_cms.utils module

shuup.simple_cms.utils.order_query_by_values(queryset, values)[source]

shuup.simple_cms.views module

class shuup.simple_cms.views.PageView(**kwargs)[source]

Bases: django.views.generic.detail.DetailView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Page

slug_field = 'translations__url'
slug_url_kwarg = 'url'
template_name = 'shuup/simple_cms/page.jinja'
context_object_name = 'page'
get(request, *args, **kwargs)[source]

Override normal get method to return correct page based on the active language and slug

Cases:
  1. Page is not found: raise Http404() like django would.
  2. No translation in active language for the page: raise Http404().
  3. Translation was found for active language, but the url doesn’t match given url:
    return HttpResponseRedirect to the active languages url.
  4. If none of the upper matches: render page normally.
get_template_names()[source]
get_queryset()[source]

Module contents

class shuup.simple_cms.AppConfig(*args, **kwargs)[source]

Bases: shuup.apps.AppConfig

name = 'shuup.simple_cms'
verbose_name = 'Content Pages'
label = 'shuup_simple_cms'
provides = {'front_urls_post': ['shuup.simple_cms.urls:urlpatterns'], 'admin_module': ['shuup.simple_cms.admin_module:SimpleCMSAdminModule'], 'front_template_helper_namespace': ['shuup.simple_cms.template_helpers:SimpleCMSTemplateHelpers'], 'xtheme_layout': ['shuup.simple_cms.layout:PageLayout'], 'xtheme_plugin': ['shuup.simple_cms.plugins:PageLinksPlugin'], 'simple_cms_template': ['shuup.simple_cms.templates:SimpleCMSDefaultTemplate', 'shuup.simple_cms.templates:SimpleCMSTemplateSidebar'], 'admin_page_form_part': ['shuup.simple_cms.admin_module.form_parts:CMSOpenGraphFormPart']}
ready()[source]