diff --git a/poppler/Rendition.h b/poppler/Rendition.h index 75bfeff..fcf9741 100644 --- a/poppler/Rendition.h +++ b/poppler/Rendition.h @@ -120,15 +120,15 @@ class MediaRendition { MediaRendition(Object *obj); ~MediaRendition(); - GBool isOk () { return ok; } + GBool isOk () const { return ok; } MediaParameters* getMHParameters() { return &MH; } MediaParameters* getBEParameters() { return &BE; } - GooString* getContentType() { return contentType; } - GooString* getFileName() { return fileName; } + GooString* getContentType() const { return contentType; } + GooString* getFileName() const { return fileName; } - GBool getIsEmbedded() { return isEmbedded; } + GBool getIsEmbedded() const { return isEmbedded; } Stream* getEmbbededStream() { return embeddedStream; } // write embedded stream to file void outputToFile(FILE*); diff --git a/qt4/src/CMakeLists.txt b/qt4/src/CMakeLists.txt index c958379..d90be45 100644 --- a/qt4/src/CMakeLists.txt +++ b/qt4/src/CMakeLists.txt @@ -15,6 +15,7 @@ set(poppler_qt4_SRCS poppler-link.cc poppler-link-extractor.cc poppler-movie.cc + poppler-screen.cc poppler-objectreference.cc poppler-optcontent.cc poppler-page.cc @@ -26,6 +27,8 @@ set(poppler_qt4_SRCS poppler-sound.cc poppler-textbox.cc poppler-page-transition.cc + poppler-streamsequentialdevice.cc + poppler-media.cc ${CMAKE_SOURCE_DIR}/poppler/ArthurOutputDev.cc ) qt4_automoc(${poppler_qt4_SRCS}) @@ -45,5 +48,6 @@ install(FILES poppler-optcontent.h poppler-export.h poppler-page-transition.h + poppler-media.h DESTINATION include/poppler/qt4) diff --git a/qt4/src/poppler-annotation.cc b/qt4/src/poppler-annotation.cc index 0905ee3..83355ff 100644 --- a/qt4/src/poppler-annotation.cc +++ b/qt4/src/poppler-annotation.cc @@ -1616,6 +1616,11 @@ void LinkAnnotation::store( QDomNode & node, QDomDocument & document ) const hyperlinkElement.setAttribute( "type", "Movie" ); break; } + case Poppler::Link::Rendition: + { + hyperlinkElement.setAttribute( "type", "Rendition" ); + break; + } case Poppler::Link::Sound: { // FIXME: implement me @@ -2037,6 +2042,66 @@ void MovieAnnotation::setMovieTitle( const QString &title ) d->title = title; } +/** ScreenAnnotation [Annotation] */ +class ScreenAnnotationPrivate : public AnnotationPrivate +{ + public: + ScreenAnnotationPrivate(); + ~ScreenAnnotationPrivate(); + + // data fields + ScreenObject *screen; + QString title; +}; + +ScreenAnnotationPrivate::ScreenAnnotationPrivate() + : AnnotationPrivate(), screen( 0 ) +{ +} + +ScreenAnnotationPrivate::~ScreenAnnotationPrivate() +{ + delete screen; +} + +ScreenAnnotation::ScreenAnnotation() + : Annotation( *new ScreenAnnotationPrivate() ) +{ +} + +ScreenAnnotation::~ScreenAnnotation() +{ +} + +Annotation::SubType ScreenAnnotation::subType() const +{ + return AScreen; +} + +ScreenObject* ScreenAnnotation::screen() const +{ + Q_D( const ScreenAnnotation ); + return d->screen; +} + +void ScreenAnnotation::setScreen( ScreenObject *screen ) +{ + Q_D( ScreenAnnotation ); + d->screen = screen; +} + +QString ScreenAnnotation::screenTitle() const +{ + Q_D( const ScreenAnnotation ); + return d->title; +} + +void ScreenAnnotation::setScreenTitle( const QString &title ) +{ + Q_D( ScreenAnnotation ); + d->title = title; +} + //BEGIN utility annotation functions QColor convertAnnotColor( AnnotColor *color ) { diff --git a/qt4/src/poppler-annotation.h b/qt4/src/poppler-annotation.h index 4124c74..53082b0 100644 --- a/qt4/src/poppler-annotation.h +++ b/qt4/src/poppler-annotation.h @@ -50,10 +50,12 @@ class CaretAnnotationPrivate; class FileAttachmentAnnotationPrivate; class SoundAnnotationPrivate; class MovieAnnotationPrivate; +class ScreenAnnotationPrivate; class EmbeddedFile; class Link; class SoundObject; class MovieObject; +class ScreenObject; /** * \short Helper class for (recursive) Annotation retrieval/storage. @@ -102,7 +104,7 @@ class POPPLER_QT4_EXPORT Annotation // WARNING!!! oKular uses that very same values so if you change them notify the author! enum SubType { AText = 1, ALine = 2, AGeom = 3, AHighlight = 4, AStamp = 5, AInk = 6, ALink = 7, ACaret = 8, AFileAttachment = 9, ASound = 10, - AMovie = 11, A_BASE = 0 }; + AMovie = 11, AScreen = 12, A_BASE = 0 }; enum Flag { Hidden = 1, FixedSize = 2, FixedRotation = 4, DenyPrint = 8, DenyWrite = 16, DenyDelete = 32, ToggleHidingOnMouse = 64, External = 128 }; enum LineStyle { Solid = 1, Dashed = 2, Beveled = 4, Inset = 8, Underline = 16 }; @@ -685,6 +687,48 @@ class POPPLER_QT4_EXPORT MovieAnnotation : public Annotation Q_DISABLE_COPY( MovieAnnotation ) }; +/** + * \short Screen annotation. + * + * The screen annotation represents a screen to be played when activated. + * + * \since 0.20 + */ +class POPPLER_QT4_EXPORT ScreenAnnotation : public Annotation +{ + public: + ScreenAnnotation(); + virtual ~ScreenAnnotation(); + + virtual SubType subType() const; + + /** + * Returns the ScreenObject of this annotation. + */ + ScreenObject* screen() const; + + /** + * Sets a new ScreenObject for this annotation. + * + * \note ScreenAnnotation takes ownership of the object + */ + void setScreen( ScreenObject *screen ); + + /** + * Returns the title of the screen of this annotation. + */ + QString screenTitle() const; + + /** + * Sets a new title for the screen of this annotation. + */ + void setScreenTitle( const QString &title ); + + private: + Q_DECLARE_PRIVATE( ScreenAnnotation ) + Q_DISABLE_COPY( ScreenAnnotation ) +}; + } #endif diff --git a/qt4/src/poppler-link.cc b/qt4/src/poppler-link.cc index 81ba39f..e62a4cf 100644 --- a/qt4/src/poppler-link.cc +++ b/qt4/src/poppler-link.cc @@ -158,6 +158,20 @@ class LinkSoundPrivate : public LinkPrivate delete sound; } +class LinkRenditionPrivate : public LinkPrivate +{ + public: + LinkRenditionPrivate( const QRectF &area, MediaRendition *rendition ); + + MediaRendition *rendition; +}; + + LinkRenditionPrivate::LinkRenditionPrivate( const QRectF &area, MediaRendition *r ) + : LinkPrivate( area ) + , rendition( r ) + { + } + class LinkJavaScriptPrivate : public LinkPrivate { public: @@ -550,6 +564,27 @@ class LinkMoviePrivate : public LinkPrivate return d->sound; } + // LinkRendition + LinkRendition::LinkRendition( const QRectF &linkArea, MediaRendition *rendition ) + : Link( *new LinkRenditionPrivate( linkArea, rendition ) ) + { + } + + LinkRendition::~LinkRendition() + { + } + + Link::LinkType LinkRendition::linkType() const + { + return Rendition; + } + + MediaRendition * LinkRendition::rendition() const + { + Q_D( const LinkRendition ); + return d->rendition; + } + // LinkJavaScript LinkJavaScript::LinkJavaScript( const QRectF &linkArea, const QString &js ) : Link( *new LinkJavaScriptPrivate( linkArea ) ) diff --git a/qt4/src/poppler-link.h b/qt4/src/poppler-link.h index b12ce8b..a0e3659 100644 --- a/qt4/src/poppler-link.h +++ b/qt4/src/poppler-link.h @@ -41,8 +41,10 @@ class LinkJavaScriptPrivate; class LinkMoviePrivate; class LinkDestinationData; class LinkDestinationPrivate; +class LinkRenditionPrivate; class ObjectReference; class SoundObject; +class MediaRendition; /** * \short A destination. @@ -185,6 +187,7 @@ class POPPLER_QT4_EXPORT Link Action, ///< A "standard" action to be executed in the viewer Sound, ///< A link representing a sound to be played Movie, ///< An action to be executed on a movie + Rendition, ///< A rendition link \since 0.20 JavaScript ///< A JavaScript code to be interpreted \since 0.10 }; @@ -442,6 +445,38 @@ class POPPLER_QT4_EXPORT LinkSound : public Link }; /** + * Rendition: Rendition link. + * + * \since 0.20 + */ +class POPPLER_QT4_EXPORT LinkRendition : public Link +{ + public: + /** + * Create a new media rendition link. + * + * \param linkArea the active area of the link + * \param rendition + */ + LinkRendition( const QRectF &linkArea, MediaRendition *rendition ); + /** + * Destructor. + */ + virtual ~LinkRendition(); + + LinkType linkType() const; + + /** + * + */ + MediaRendition *rendition() const; + + private: + Q_DECLARE_PRIVATE( LinkRendition ) + Q_DISABLE_COPY( LinkRendition ) +}; + +/** * JavaScript: a JavaScript code to be interpreted. * * \since 0.10 diff --git a/qt4/src/poppler-media.cc b/qt4/src/poppler-media.cc new file mode 100644 index 0000000..0750ad5 --- /dev/null +++ b/qt4/src/poppler-media.cc @@ -0,0 +1,164 @@ +/* poppler-media.cc: qt interface to poppler + * Copyright (C) 2012 Guillermo A. Amaral B. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "poppler-media.h" + +#include "Rendition.h" + +#include "poppler-private.h" +#include "poppler-streamsequentialdevice-private.h" + +namespace Poppler +{ + +class MediaRenditionPrivate +{ +public: + + MediaRenditionPrivate(::MediaRendition *rendition) + : rendition(rendition), device(0) + { + } + + ::MediaRendition *rendition; + QIODevice *device; +}; + +MediaRendition::MediaRendition(::MediaRendition *rendition) + : d_ptr(new MediaRenditionPrivate(rendition)) +{ + Q_D( MediaRendition ); + + if (d->rendition) + d->device = new StreamSequentialDevice(d->rendition->getEmbbededStream()); +} + +MediaRendition::~MediaRendition() +{ + delete d_ptr; +} + +bool +MediaRendition::isValid() const +{ + Q_D( const MediaRendition ); + return d->rendition && d->rendition->isOk(); +} + +MediaParameters* +MediaRendition::getMHParameters() +{ + Q_ASSERT(isValid() && "Invalid media rendition."); + Q_D( MediaRendition ); + return d->rendition->getMHParameters(); +} + +MediaParameters* +MediaRendition::getBEParameters() +{ + Q_ASSERT(isValid() && "Invalid media rendition."); + Q_D( MediaRendition ); + return d->rendition->getBEParameters(); +} + +QString +MediaRendition::contentType() +{ + Q_ASSERT(isValid() && "Invalid media rendition."); + Q_D( MediaRendition ); + return UnicodeParsedString(d->rendition->getContentType()); +} + +QString +MediaRendition::fileName() +{ + Q_ASSERT(isValid() && "Invalid media rendition."); + Q_D( MediaRendition ); + return UnicodeParsedString(d->rendition->getFileName()); +} + +bool +MediaRendition::isEmbedded() const +{ + Q_ASSERT(isValid() && "Invalid media rendition."); + Q_D( const MediaRendition ); + return d->rendition->getIsEmbedded(); +} + +QIODevice * +MediaRendition::streamDevice() const +{ + Q_D( const MediaRendition ); + return d->device; +} + +bool +MediaRendition::autoPlay() const +{ + Q_D( const MediaRendition ); + if (d->rendition->getBEParameters()) { + return d->rendition->getBEParameters()->autoPlay; + } else if (d->rendition->getMHParameters()) { + return d->rendition->getMHParameters()->autoPlay; + } else qDebug("No BE or MH paremeters to reference!"); + return false; +} + +bool +MediaRendition::showControls() const +{ + Q_D( const MediaRendition ); + if (d->rendition->getBEParameters()) { + return d->rendition->getBEParameters()->showControls; + } else if (d->rendition->getMHParameters()) { + return d->rendition->getMHParameters()->showControls; + } else qDebug("No BE or MH paremeters to reference!"); + return false; +} + +float +MediaRendition::repeatCount() const +{ + Q_D( const MediaRendition ); + if (d->rendition->getBEParameters()) { + return d->rendition->getBEParameters()->repeatCount; + } else if (d->rendition->getMHParameters()) { + return d->rendition->getMHParameters()->repeatCount; + } else qDebug("No BE or MH paremeters to reference!"); + return 1.f; +} + +QSize +MediaRendition::size() const +{ + Q_D( const MediaRendition ); + MediaParameters *mp = 0; + + if (d->rendition->getBEParameters()) + mp = d->rendition->getBEParameters(); + else if (d->rendition->getMHParameters()) + mp = d->rendition->getMHParameters(); + else qDebug("No BE or MH paremeters to reference!"); + + if (mp) + return QSize(mp->windowParams.width, mp->windowParams.height); + return QSize(); +} + +} + diff --git a/qt4/src/poppler-media.h b/qt4/src/poppler-media.h new file mode 100644 index 0000000..f58c1d3 --- /dev/null +++ b/qt4/src/poppler-media.h @@ -0,0 +1,106 @@ +/* poppler-media.h: qt interface to poppler + * Copyright (C) 2012 Guillermo A. Amaral B. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __POPPLER_MEDIARENDITION_H__ +#define __POPPLER_MEDIARENDITION_H__ + +#include +#include + +class MediaRendition; +class QIODevice; + +struct MediaParameters; + +namespace Poppler +{ + class MediaRenditionPrivate; + + /** + Qt wrapper for MediaRendition. + + \since 0.20 + */ + class MediaRendition { + public: + MediaRendition(::MediaRendition *rendition); + ~MediaRendition(); + + /** + Check if wrapper is holding a valid rendition object. + */ + bool isValid() const ; + + /** + Returns content type. + */ + QString contentType(); + + /** + Returns file name. + */ + QString fileName(); + + /** + Returns true if media is embedded. + */ + bool isEmbedded() const; + + /** + Returns data stream device. + */ + QIODevice *streamDevice() const; + + /** + Convenience accessor for auto-play parameter. + */ + bool autoPlay() const; + + /** + Convenience accessor for show controls parameter. + */ + bool showControls() const; + + /** + Convenience accessor for repeat count parameter. + */ + float repeatCount() const; + + /** + Convenience accessor for size parameter. + */ + QSize size() const; + + /** + Convenience accessor for "Must Honor" parameters. + */ + MediaParameters* getMHParameters(); + + /** + Convenience accessor for "Best Effort" parameters. + */ + MediaParameters* getBEParameters(); + + private: + Q_DECLARE_PRIVATE( MediaRendition ) + MediaRenditionPrivate *d_ptr; + Q_DISABLE_COPY( MediaRendition ) + }; +} + +#endif /* __POPPLER_MEDIARENDITION_H__ */ diff --git a/qt4/src/poppler-page.cc b/qt4/src/poppler-page.cc index 34d8e5e..d5f1b01 100644 --- a/qt4/src/poppler-page.cc +++ b/qt4/src/poppler-page.cc @@ -45,6 +45,7 @@ #include #include #include +#include #if defined(HAVE_SPLASH) #include #include @@ -57,6 +58,8 @@ #include "poppler-annotation-helper.h" #include "poppler-annotation-private.h" #include "poppler-form.h" +#include "poppler-media.h" +#include "poppler-streamsequentialdevice-private.h" namespace Poppler { @@ -200,6 +203,13 @@ Link* PageData::convertLinkActionToLink(::LinkAction * a, DocumentData *parentDo } break; + case actionRendition: + { + ::LinkRendition *lrn = (::LinkRendition *)a; + popplerLink = new LinkRendition( linkArea, new MediaRendition(lrn->getMedia()) ); + } + break; + case actionUnknown: break; } @@ -994,6 +1004,28 @@ QList Page::annotations() const break; } + case Annot::typeScreen: + { + AnnotScreen * screenann = static_cast< AnnotScreen * >( ann ); + + if (!screenann->getAction()) + continue; + + ScreenAnnotation * s = new ScreenAnnotation(); + annotation = s; + + // -> screen + ScreenObject *screen = + new ScreenObject( static_cast(m_page->convertLinkActionToLink( screenann->getAction(), QRectF() ) ) ); + s->setScreen( screen ); + + // -> screenTitle + GooString * screentitle = screenann->getTitle(); + if ( screentitle ) + s->setScreenTitle( UnicodeParsedString( screentitle ) ); + + break; + } // special case for ignoring unknwon annotations case Annot::typeUnknown: continue; diff --git a/qt4/src/poppler-qt4.h b/qt4/src/poppler-qt4.h index 4ba27ed..2c752da 100644 --- a/qt4/src/poppler-qt4.h +++ b/qt4/src/poppler-qt4.h @@ -42,6 +42,7 @@ class EmbFile; class Sound; class AnnotMovie; +class AnnotScreen; /** The %Poppler Qt4 binding. @@ -1718,6 +1719,32 @@ height = dummy.height(); MovieData *m_movieData; }; + class ScreenObjectPrivate; + /** + Container class for a screen object in a PDF document. + + \since 0.20 + */ + class POPPLER_QT4_EXPORT ScreenObject { + friend class Page; + public: + ~ScreenObject(); + + /** + Link action + */ + LinkRendition *action() const; + + private: + /// \cond PRIVATE + ScreenObject( LinkRendition *action ); + /// \endcond + + Q_DISABLE_COPY(ScreenObject) + Q_DECLARE_PRIVATE(ScreenObject); + ScreenObjectPrivate *d_ptr; + }; + } Q_DECLARE_OPERATORS_FOR_FLAGS(Poppler::Page::PainterFlags) diff --git a/qt4/src/poppler-screen.cc b/qt4/src/poppler-screen.cc new file mode 100644 index 0000000..c2ee918 --- /dev/null +++ b/qt4/src/poppler-screen.cc @@ -0,0 +1,57 @@ +/* poppler-screen.cc: qt interface to poppler + * Copyright (C) 2008, 2010, Pino Toscano + * Copyright (C) 2008, Albert Astals Cid + * Copyright (C) 2010, Carlos Garcia Campos + * Copyright (C) 2012, Guillermo A. Amaral B. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "poppler-qt4.h" + +#include "Object.h" +#include "Annot.h" + +namespace Poppler +{ + +class ScreenObjectPrivate +{ +public: + ScreenObjectPrivate( LinkRendition *act ) + : action( act ) + { + } + + LinkRendition *action; +}; + +ScreenObject::ScreenObject( LinkRendition *action ) + : d_ptr( new ScreenObjectPrivate( action ) ) +{ +} + +ScreenObject::~ScreenObject() +{ + delete d_ptr; +} + +LinkRendition *ScreenObject::action() const +{ + Q_D(const ScreenObject); + return d->action; +} + +} diff --git a/qt4/src/poppler-streamsequentialdevice-private.h b/qt4/src/poppler-streamsequentialdevice-private.h new file mode 100644 index 0000000..cb69f25 --- /dev/null +++ b/qt4/src/poppler-streamsequentialdevice-private.h @@ -0,0 +1,51 @@ +/* poppler-streamdevice-private.h: Qt4 interface to poppler + * Copyright (C) 2012, Guiillermo A. Amaral B. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef POPPLER_STREAMSEQUENTIALDEVICE_PRIVATE_H +#define POPPLER_STREAMSEQUENTIALDEVICE_PRIVATE_H + +#include + +class Stream; + +namespace Poppler { + +class StreamSequentialDevice : public QIODevice +{ + public: + StreamSequentialDevice(Stream *stream, QObject *parent = 0); + virtual ~StreamSequentialDevice(); + + virtual void close(); + + virtual bool isSequential() const + { return true; } + + protected: + virtual qint64 readData(char *data, qint64 maxSize); + inline virtual qint64 writeData(const char *, qint64) + { return 0; } + + private: + Q_DISABLE_COPY(StreamSequentialDevice); + Stream *m_stream; +}; + +} + +#endif diff --git a/qt4/src/poppler-streamsequentialdevice.cc b/qt4/src/poppler-streamsequentialdevice.cc new file mode 100644 index 0000000..1e0c2a6 --- /dev/null +++ b/qt4/src/poppler-streamsequentialdevice.cc @@ -0,0 +1,56 @@ +/* poppler-streamdevice.cc: Qt4 interface to poppler + * Copyright (C) 2012, Guiillermo A. Amaral B. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "poppler-streamsequentialdevice-private.h" + +#include "Object.h" +#include "Stream.h" + +namespace Poppler { + +StreamSequentialDevice::StreamSequentialDevice(Stream *stream, QObject *parent) + : QIODevice(parent) + , m_stream(stream) +{ + Q_ASSERT(m_stream && "Invalid stream assigned."); + m_stream->incRef(); + m_stream->reset(); + open(QIODevice::ReadOnly); +} + +StreamSequentialDevice::~StreamSequentialDevice() +{ + m_stream->decRef(); + m_stream = 0; +} + +void +StreamSequentialDevice::close() +{ + m_stream->close(); + QIODevice::close(); +} + +qint64 +StreamSequentialDevice::readData(char *data, qint64 maxSize) +{ + return m_stream->doGetChars(maxSize, reinterpret_cast(data)); +} + +} +