Ejemplo n.º 1
0
class ThesisForm(Form):

    title = fields.TitleField(label=_('Original Thesis Title'),
                              validators=[Required()])
    subtitle = fields.TitleField(label=_('Original Thesis Subtitle'),
                                 recjson_key='title.subtitle')
    author = fields.AuthorField(label=_('Author'), cook_function=add_author)
    supervisor = fields.AuthorField(label=_('Thesis Supervisor'))
    abstract = fields.AbstractField(label=_('Abstract'))

    languages = [("en", _("English")), ("fre", _("French")),
                 ("ger", _("German")), ("dut", _("Dutch")),
                 ("ita", _("Italian")), ("spa", _("Spanish")),
                 ("por", _("Portuguese")), ("gre", _("Greek")),
                 ("slo", _("Slovak")), ("cze", _("Czech")),
                 ("hun", _("Hungarian")), ("pol", _("Polish")),
                 ("nor", _("Norwegian")), ("swe", _("Swedish")),
                 ("fin", _("Finnish")), ("rus", _("Russian"))]
    language = fields.LanguageField(label=_("Language"), choices=languages)
    publisher = fields.PublisherField(label=_('Thesis Publisher'))
    defence_date = fields.Date(label=_('Date of Defence'), widget=date_widget)

    funded_choices = [("yes", _("Yes")), ("no", _("No"))]
    funded = fields.SelectField(label=_(
        "Has your thesis been funded by the CERN Doctoral Student Program?"),
                                choices=funded_choices)

    file_field = fields.FileUploadField(widget=plupload_widget)
    submit = fields.SubmitField(label=_('Submit Thesis'),
                                widget=bootstrap_submit)
    """ Form Configuration variables """
    _title = _("Submit a Thesis")
    _drafting = True  # enable and disable drafting
Ejemplo n.º 2
0
class PreprintForm(Form):

    author = fields.AuthorField(label=_('Author'), validators=[Required()])
    subject_category = fields.TitleField(label=_('Subject category'),
                                         validators=[Required()])
    note = fields.NotesField(label=_('Note'))
    institution = TextField(label=_('Institution'))
    languages = [("en", _("English")), \
                ("fre", _("French")), \
                ("ger", _("German")), \
                ("dut", _("Dutch")), \
                ("ita", _("Italian")), \
                ("spa", _("Spanish")), \
                ("por", _("Portuguese")), \
                ("gre", _("Greek")), \
                ("slo", _("Slovak")), \
                ("cze", _("Czech")), \
                ("hun", _("Hungarian")), \
                ("pol", _("Polish")), \
                ("nor", _("Norwegian")), \
                ("swe", _("Swedish")), \
                ("fin", _("Finnish")), \
                ("rus", _("Russian"))]
    language = fields.LanguageField(label=_("Language"), choices=languages)
    date = fields.Date(label=_('Date'), widget=date_widget)
    file_field = fields.FileUploadField(label=_('File'))
    submit = SubmitField(label=_('Submit Preprint'), widget=bootstrap_submit)
    """ Form Configuration variables """
    _title = _("Submit a Preprint")
    _drafting = True  #enable and disable drafting
Ejemplo n.º 3
0
class PhotoForm(Form):

    title = fields.TitleField(label=_('Photo Title'))
    author = fields.AuthorField(label=_('Photo Author'))
    date = fields.Date(label=_('Photo Date'), widget=date_widget)
    keywords = fields.KeywordsField(label=_('Keywords'))
    notes = fields.NotesField(label=_('Comments or Notes'))
    plupload_file = fields.FileUploadField(label=_('Files'),
                                           widget=plupload_widget)
    submit = SubmitField(label=_('Submit Photo'), widget=bootstrap_submit)

    #configuration variables
    _title = _("Submit a Photo")
    _drafting = True  # enable and disable drafting
Ejemplo n.º 4
0
class PoemForm(Form):

    title = fields.TitleField(label=_('Poem Title'), validators=[Required()])
    author = fields.AuthorField(label=_('Author'), validators=[Required()])
    languages = [("en", _("English")), ("fre", _("French")),
                 ("ger", _("German")), ("dut", _("Dutch")),
                 ("ita", _("Italian")), ("spa", _("Spanish")),
                 ("por", _("Portuguese")), ("gre", _("Greek")),
                 ("slo", _("Slovak")), ("cze", _("Czech")),
                 ("hun", _("Hungarian")), ("pol", _("Polish")),
                 ("nor", _("Norwegian")), ("swe", _("Swedish")),
                 ("fin", _("Finnish")), ("rus", _("Russian"))]
    language = fields.LanguageField(label=_('Language'),
                                    choices=languages,
                                    validators=[Required()])
    year = fields.Date(label=_('Year'), validators=[Required()])
    poem_text = fields.AbstractField(label='Poem Text',
                                     validators=[Required()])
    submit = SubmitField(label=_('Submit Poem'), widget=bootstrap_submit)
    """ Form Configuration variables """
    _title = _('Submit a Poem')
    _drafting = True  # enable and disable drafting
Ejemplo n.º 5
0
class ArticleForm(Form):

    doi = fields.DOIField(label=_('DOI'))
    publisher = fields.PublisherField(label=_('Publisher'),
                                      validators=[Required()])
    journal = fields.JournalField(label=_('Journal Title'),
                                  validators=[Required()])
    issn = fields.ISSNField(label=_('ISSN'))
    title = fields.TitleField(label=_('Document Title'))
    author = fields.AuthorField(label=_('Author'))
    abstract = fields.AbstractField(label=_('Abstract'))
    pagesnum = fields.PagesNumberField(label=_('Number of Pages'))
    languages = [("en", _("English")), ("fre", _("French")),
                 ("ger", _("German")), ("dut", _("Dutch")),
                 ("ita", _("Italian")), ("spa", _("Spanish")),
                 ("por", _("Portuguese")), ("gre", _("Greek")),
                 ("slo", _("Slovak")), ("cze", _("Czech")),
                 ("hun", _("Hungarian")), ("pol", _("Polish")),
                 ("nor", _("Norwegian")), ("swe", _("Swedish")),
                 ("fin", _("Finnish")), ("rus", _("Russian"))]
    language = fields.LanguageField(label=_('Language'), choices=languages)
    date = fields.Date(label=_('Date of Document'), widget=date_widget)
    keywords = fields.KeywordsField(label=_('Keywords'))
    notes = fields.NotesField(label=_('Notes'))
    plupload_file = fields.FileUploadField(widget=plupload_widget)
    submit = SubmitField(label=_('Submit Article'), widget=bootstrap_submit)
    """ Form Configuration variables """
    _title = _('Submit an Article')
    _drafting = True  # enable and disable drafting

    # Group fields in categories

    groups = [('Publisher/Journal', ['doi', 'publisher', 'journal', 'issn'], {
        'description': "Publisher and Journal fields are required.",
        'indication': 'required'
    }), ('Basic Information', ['title', 'author', 'abstract', 'pagesnum']),
              ('Other', ['language', 'date', 'keywords', 'notes'])]
Ejemplo n.º 6
0
 class RelatedDatesForm(WebDepositForm):
     date = fields.Date()
Ejemplo n.º 7
0
class ZenodoForm(WebDepositForm):
    #
    # Fields
    #
    upload_type = fields.UploadTypeField(
        validators=[validators.required()],
        export_key='upload_type.type',
    )
    publication_type = fields.SelectField(
        label='Type of publication',
        choices=[
            ('book', 'Book'),
            ('section', 'Book section'),
            ('conferencepaper', 'Conference paper'),
            ('article', 'Journal article'),
            ('patent', 'Patent'),
            ('preprint', 'Preprint'),
            ('report', 'Report'),
            ('softwaredocumentation', 'Software documentation'),
            ('thesis', 'Thesis'),
            ('technicalnote', 'Technical note'),
            ('workingpaper', 'Working paper'),
            ('other', 'Other'),
        ],
        validators=[
            required_if('upload_type', ['publication']),
            validators.optional()
        ],
        hidden=True,
        disabled=True,
        export_key='upload_type.subtype',
    )
    image_type = fields.SelectField(
        choices=[
            ('figure', 'Figure'),
            ('plot', 'Plot'),
            ('drawing', 'Drawing'),
            ('diagram', 'Diagram'),
            ('photo', 'Photo'),
            ('other', 'Other'),
        ],
        validators=[
            required_if('upload_type', ['image']),
            validators.optional()
        ],
        hidden=True,
        disabled=True,
        export_key='upload_type.subtype',
    )

    #
    # Basic information
    #
    doi = fields.DOIField(
        label="Digital Object Identifier",
        description="Optional. Did your publisher already assign a DOI to your"
        " upload? If not, leave the field empty and we will register a new"
        " DOI for you. A DOI allow others to easily and unambiguously cite"
        " your upload.",
        placeholder="e.g. 10.1234/foo.bar...",
        validators=[
            doi_syntax_validator,
            pre_reserved_doi_validator(
                'prereserve_doi',
                prefix=CFG_DATACITE_DOI_PREFIX
            ),
            invalid_doi_prefix_validator(prefix=CFG_DATACITE_DOI_PREFIX),
        ],
        processors=[
            local_datacite_lookup
        ],
        export_key='doi',
    )
    prereserve_doi = fields.ReserveDOIField(
        label="",
        doi_field="doi",
        doi_creator=create_doi,
        widget=ButtonWidget(
            label=_("Pre-reserve DOI"),
            icon='icon-barcode',
            tooltip=_(
                'Pre-reserve a Digital Object Identifier for your upload. This'
                ' allows you know the DOI before you submit your upload, and'
                ' can thus include it in e.g. publications. The DOI is not'
                ' finally registered until submit your upload.'
            ),
        ),
    )
    publication_date = fields.Date(
        label=_('Publication date'),
        icon='icon-calendar',
        description='Required. Format: YYYY-MM-DD. The date your upload was '
        'made available in case it was already published elsewhere.',
        default=date.today(),
        validators=[validators.required()],
        widget=date_widget,
        widget_classes='input-small',
    )
    title = fields.TitleField(
        validators=[validators.required()],
        description='Required.',
        filters=[
            strip_string,
        ],
        export_key='title',
    )
    creators = fields.DynamicFieldList(
        fields.FormField(
            CreatorForm,
            widget=ExtendedListWidget(
                item_widget=ListItemWidget(with_label=False),
                class_='inline',
            ),
        ),
        label='Authors',
        add_label='Add another author',
        icon='icon-user',
        widget_classes='',
        min_entries=1,
        export_key='authors',
        validators=[validators.required(), list_length(
            min_num=1, element_filter=filter_empty_helper(),
        )],
    )
    description = fields.TextAreaField(
        label="Description",
        description='Required.',
        default='',
        icon='icon-pencil',
        validators=[validators.required(), ],
        widget=CKEditorWidget(
            toolbar=[
                ['PasteText', 'PasteFromWord'],
                ['Bold', 'Italic', 'Strike', '-',
                    'Subscript', 'Superscript', ],
                ['NumberedList', 'BulletedList'],
                ['Undo', 'Redo', '-', 'Find', 'Replace', '-', 'RemoveFormat'],
                ['SpecialChar', 'ScientificChar'], ['Source'], ['Maximize'],
            ],
            disableNativeSpellChecker=False,
            extraPlugins='scientificchar',
            removePlugins='elementspath',
        ),
        filters=[
            sanitize_html,
            strip_string,
        ],
    )
    keywords = fields.DynamicFieldList(
        fields.TextField(
            widget_classes="span5"
        ),
        label='Keywords',
        add_label='Add another keyword',
        icon='icon-tags',
        widget_classes='',
        min_entries=1,
    )
    notes = fields.TextAreaField(
        label="Additional notes",
        description='Optional.',
        default='',
        validators=[validators.optional()],
        filters=[
            strip_string,
        ],
    )

    #
    # Access rights
    #
    access_right = fields.AccessRightField(
        label="Access right",
        description="Required. Open access uploads have considerably higher "
        "visibility on %s." % CFG_SITE_NAME,
        default="open",
        validators=[validators.required()]
    )
    embargo_date = fields.Date(
        label=_('Embargo date'),
        icon='icon-calendar',
        description='Required only for Embargoed Access uploads. Format: '
        'YYYY-MM-DD. The date your upload will be made publicly available '
        'in case it is under an embargo period from your publisher.',
        default=date.today(),
        validators=[
            required_if('access_right', ['embargoed']),
            validators.optional()
        ],
        widget=date_widget,
        widget_classes='input-small',
        hidden=True,
        disabled=True,
    )
    license = fields.LicenseField(
        validators=[
            required_if('access_right', ['embargoed', 'open', ]),
            validators.required()
        ],
        default='cc-zero',
        domain_data=True,
        domain_content=True,
        domain_software=True,
        description='Required. The selected license applies to all of your '
        'files displayed in the bottom of the form. If you want to upload '
        'some files under a different license, please do so in two separate'
        ' uploads. If you think a license missing is in the list, please '
        'inform us at %s.' % CFG_SITE_SUPPORT_EMAIL,
        filters=[
            strip_string,
        ],
        placeholder="Start typing a license name or abbreviation...",
    )

    #
    # Collection
    #
    communities = fields.DynamicFieldList(
        fields.FormField(
            CommunityForm,
            widget=ExtendedListWidget(html_tag=None, item_widget=ItemWidget())
        ),
        validators=[community_validator],
        widget=TagListWidget(template="{{title}}"),
        icon='icon-group',
        export_key='provisional_communities',
    )

    #
    # Funding
    #
    grants = fields.DynamicFieldList(
        fields.FormField(
            GrantForm,
            widget=ExtendedListWidget(html_tag=None, item_widget=ItemWidget()),
            export_key=lambda f: {
                'identifier': f.data['id'],
                'title': "%s - %s (%s)" % (
                    f.data['acronym'], f.data['title'], f.data['id']
                )
            }
        ),
        widget=TagListWidget(template="{{acronym}} - {{title}} ({{id}})"),
        icon='icon-group',
        description="Optional. Note, a human %s curator will validate your"
                    " upload before reporting it to OpenAIRE, and you may "
                    "thus experience a delay before your upload is available "
                    "in OpenAIRE." % CFG_SITE_NAME,
        validators=[grants_validator],
    )

    #
    # Related work
    #
    related_identifiers = fields.DynamicFieldList(
        fields.FormField(
            RelatedIdentifierForm,
            description="Optional. Format: e.g. 10.1234/foo.bar",
            widget=ExtendedListWidget(
                item_widget=ListItemWidget(
                    with_label=False,
                ),
                class_='inline',
            ),
        ),
        label="Related identifiers",
        add_label='Add another related identifier',
        icon='icon-barcode',
        widget_classes='',
        min_entries=1,
    )

    #
    # Journal
    #
    journal_title = fields.TextField(
        label="Journal title",
        description="Optional.",
        validators=[
            required_if(
                'journal_volume', [lambda x: bool(x.strip()), ],  # non-empty
                message="Journal title is required if you specify either "
                        "volume, issue or pages."
            ),
            required_if(
                'journal_issue', [lambda x: bool(x.strip()), ],  # non-empty
                message="Journal title is required if you specify either "
                        "volume, issue or pages."
            ),
            required_if(
                'journal_pages', [lambda x: bool(x.strip()), ],  # non-empty
                message="Journal title is required if you specify either "
                        "volume, issue or pages."
            ),
        ],
        export_key='journal.title',
    )
    journal_volume = fields.TextField(
        label="Volume", description="Optional.", export_key='journal.volume',
    )
    journal_issue = fields.TextField(
        label="Issue", description="Optional.", export_key='journal.issue',
    )
    journal_pages = fields.TextField(
        label="Pages", description="Optional.", export_key='journal.pages',
    )

    #
    # Book/report/chapter
    #
    partof_title = fields.TextField(
        label="Book title",
        description="Optional. "
                    "Title of the book or report which this "
                    "upload is part of.",
        export_key='part_of.title',
    )
    partof_pages = fields.TextField(
        label="Pages",
        description="Optional.",
        export_key='part_of.pages',
    )

    imprint_isbn = fields.TextField(
        label="ISBN",
        description="Optional.",
        placeholder="e.g 0-06-251587-X",
        export_key='isbn',
    )
    imprint_publisher = fields.TextField(
        label="Publisher",
        description="Optional.",
        export_key='imprint.publisher',
    )
    imprint_place = fields.TextField(
        label="Place",
        description="Optional.",
        placeholder="e.g city, country...",
        export_key='imprint.place',
    )

    #
    # Thesis
    #
    thesis_supervisors = fields.DynamicFieldList(
        fields.FormField(
            CreatorForm,
            widget=ExtendedListWidget(
                item_widget=ListItemWidget(with_label=False),
                class_='inline',
            ),
        ),
        label='Supervisors',
        add_label='Add another supervisor',
        icon='icon-user',
        widget_classes='',
        min_entries=1,
    )
    thesis_university = fields.TextField(
        description="Optional.",
        label='Awarding University',
        validators=[validators.optional()],
        icon='icon-building',
    )

    #
    # Conference
    #
    conference_title = fields.TextField(
        label="Conference title",
        description="Optional.",
        validators=[
            not_required_if('conference_acronym', [lambda x: bool(x.strip())]),
            required_if(
                'conference_dates', [lambda x: bool(x.strip()), ],  # non-empty
                message="Conference title or acronym is required if you "
                        "specify either dates or place."
            ),
            required_if(
                'conference_place', [lambda x: bool(x.strip()), ],  # non-empty
                message="Conference title or acronym is required if you "
                        "specify either dates or place."
            ),
        ],
        export_key="meetings.title"
    )
    conference_acronym = fields.TextField(
        label="Acronym",
        description="Optional.",
        validators=[
            not_required_if('conference_title', [lambda x: bool(x.strip())]),
            required_if(
                'conference_dates', [lambda x: bool(x.strip()), ],  # non-empty
                message="Conference title or acronym is required if you "
                        "specify either dates or place."
            ),
            required_if(
                'conference_place', [lambda x: bool(x.strip()), ],  # non-empty
                message="Conference title or acronym is required if you "
                        "specify either dates or place."
            ),
        ],
        export_key="meetings.acronym",
    )
    conference_dates = fields.TextField(
        label="Dates", description="Optional.",
        placeholder="e.g 21-22 November 2012...",
        export_key="meetings.dates",
    )
    conference_place = fields.TextField(
        label="Place",
        description="Optional.",
        placeholder="e.g city, country...",
        export_key="meetings.place",
    )
    conference_url = fields.TextField(
        label="Website",
        description="Optional. E.g. http://zenodo.org",
        validators=[validators.optional(), validators.URL()]
    )

    #
    # File upload field
    #
    plupload_file = fields.FileUploadField(
        label="",
        widget=plupload_widget,
        export_key=False
    )

    def validate_plupload_file(form, field):
        """ Ensure minimum one file is attached. """
        if not getattr(request, 'is_api_request', False):
            # Tested in API by a separate workflow task.
            if len(form.files) == 0:
                raise ValidationError("You must provide minimum one file.")


    #
    # Form configuration
    #
    _title = _('New upload')
    _drafting = True   # enable and disable drafting

    #
    # Grouping of fields
    #
    groups = [
        ('Type of file(s)',
            ['upload_type', 'publication_type', 'image_type', ],
            {'indication': 'required'}),
        ('Basic information', [
            'doi', 'prereserve_doi', 'publication_date', 'title',  'creators', 'description',
            'keywords', 'notes',
        ], {'indication': 'required', }),
        ('License', [
            'access_right', 'embargo_date', 'license',
        ], {
            'indication': 'required',
            #'description': 'Unless you explicitly specify the license conditions below for Open Access and Embargoed Access uploads,'
            #' you agree to release your data files under the terms of the Creative Commons Zero (CC0) waiver.'
            #' All authors of the data and publications have agreed to the terms of this waiver and license.'
        }),
        ('Communities', [
            'communities',
        ], {
            'indication': 'recommended',
            'description': Markup('Any user can create a community collection on %(CFG_SITE_NAME)s (<a href="/communities/">browse communities</a>). Specify communities which you wish your upload to appear in. The owner of the community will be notified, and can either accept or reject your request.' % {'CFG_SITE_NAME': CFG_SITE_NAME})
        }),
        ('Funding', [
            'grants',
        ], {
            'indication': 'recommended',
            'description': '%s is integrated into reporting lines for research funded by the European Commission via OpenAIRE (http://www.openaire.eu). Specify grants which have funded your research, and we will let your funding agency know!' % CFG_SITE_NAME,
        }),
        ('Related datasets/publications', [
            'related_identifiers',
        ], {
            'classes': '',
            'indication': 'recommended',
            'description': 'Specify identifiers of related publications and datasets. Supported identifiers include: DOI, Handle, ARK, PURL, ISSN, ISBN, PubMed ID, PubMed Central ID, ADS Bibliographic Code, arXiv, Life Science Identifiers (LSID), EAN-13, ISTC, URNs and URLs.'
        }),
        ('Journal', [
            'journal_title', 'journal_volume', 'journal_issue',
            'journal_pages',
        ], {
            'classes': '',
            'indication': 'optional',
        }),
        ('Conference', [
            'conference_title', 'conference_acronym', 'conference_dates',
            'conference_place', 'conference_url',
        ], {
            'classes': '',
            'indication': 'optional',
        }),
        ('Book/Report/Chapter', [
            'imprint_publisher',  'imprint_place', 'imprint_isbn', '-',
            'partof_title', 'partof_pages',
        ], {'classes': '', 'indication': 'optional', }),
        ('Thesis', [
            'thesis_university', 'thesis_supervisors',
        ], {
            'classes': '',
            'indication': 'optional',
        }),
    ]
Ejemplo n.º 8
0
class ArticleForm(WebDepositForm):

    doi = fields.DOIField(label=_('DOI'), recjson_key='publication_info.DOI')
    publisher = fields.PublisherField(label=_('Publisher'),
                                      validators=[Required()],
                                      recjson_key='imprint.publisher_name')
    journal = fields.JournalField(label=_('Journal Title'),
                                  validators=[Required()])
    issn = fields.ISSNField(label=_('ISSN'), recjson_key='issn')
    title = fields.TitleField(label=_('Document Title'),
                              recjson_key='title.title')
    authors = fields.DynamicFieldList(fields.FormField(
        AuthorForm,
        widget=ExtendedListWidget(
            item_widget=ListItemWidget(with_label=False),
            class_='inline',
        ),
    ),
                                      label='Authors',
                                      add_label='Add another author',
                                      icon='icon-user',
                                      widget_classes='',
                                      min_entries=1,
                                      recjson_key='authors')

    abstract = fields.AbstractField(label=_('Abstract'),
                                    recjson_key='abstract.summary',
                                    widget=ckeditor_widget)
    pagesnum = fields.PagesNumberField(label=_('Number of Pages'))
    languages = [("en", _("English")), ("fre", _("French")),
                 ("ger", _("German")), ("dut", _("Dutch")),
                 ("ita", _("Italian")), ("spa", _("Spanish")),
                 ("por", _("Portuguese")), ("gre", _("Greek")),
                 ("slo", _("Slovak")), ("cze", _("Czech")),
                 ("hun", _("Hungarian")), ("pol", _("Polish")),
                 ("nor", _("Norwegian")), ("swe", _("Swedish")),
                 ("fin", _("Finnish")), ("rus", _("Russian"))]
    language = fields.LanguageField(label=_('Language'), choices=languages)
    date = fields.Date(label=_('Date of Document'),
                       widget=date_widget,
                       recjson_key='imprint.date')
    authors = fields.DynamicFieldList(fields.FormField(
        AuthorForm,
        widget=ExtendedListWidget(
            item_widget=ListItemWidget(with_label=False),
            class_='inline',
        ),
    ),
                                      label='Authors',
                                      add_label='Add another author',
                                      icon='icon-user',
                                      widget_classes='',
                                      min_entries=1,
                                      recjson_key='authors')
    keywords = fields.DynamicFieldList(
        fields.TextField(placeholder="Start typing a keyword...",
                         autocomplete=keywords_autocomplete,
                         widget=TagInput()),
        widget=TagListWidget(template="{{value}}"),
        icon='icon-tags',
    )
    notes = fields.NotesField(label=_('Notes'), recjson_key='comment')
    plupload_file = fields.FileUploadField(widget=plupload_widget, label="")
    """ Form Configuration variables """
    _title = _('Submit an Article')
    _subtitle = 'Instructions: (i) Press "Save" to save your upload for '\
                'editing later, as many times you like. (ii) Upload or remove'\
                ' extra files in the bottom of the form. (iii) When ready, '\
                'press "Submit" to finalize your upload.'
    _drafting = True  # enable and disable drafting

    # Group fields in categories

    groups = [('Publisher/Journal', ['doi', 'publisher', 'journal', 'issn'], {
        'description': "Publisher and Journal fields are required.",
        'indication': 'required'
    }), ('Basic Information', ['title', 'authors', 'abstract', 'pagesnum']),
              ('Other', ['language', 'date', 'keywords', 'notes'])]