Sport Training Management Services

Introduction

Sport Training Management Services provide a series of modules that allow the interaction of everything needed to manage and improve the performance of the athletes training: users and profiles, hardware used (mainly cameras), training patterns, training video sessions recorded, annotations and comments on training sessions, etc.

Functionality

The system will have a set of common services for the training modules. This commons services can be divided into the following sub modules:

  1. Overall services for training modules: the developed system has been developed open for any kind of sport disciplines. This module aims to manage the disciplines and their associated hardware.
  2. User services for training modules: it contains information about people involved in the training process: coaches, athlete and other staff members.
  3. Usage services: it records statistical information about the usage that is being done about the system. This information is useful for CAR to see how the system is used and to show to the different sport federations the tasks they are doing in CAR.
  4. Training management and control: this module gives all the services like search, remove or publish to internet a training session. In case the training session has associated a template, this module will provide the services to manage it.
  5. Media services for training modules: this element provides the required audiovisual services like streaming to internet, streaming to a local player, remote control over a stream, storage of a video (temporary or not).
  6. Annotation services training modules: it provides storage and retrieval of the annotation made over the training sessions.

Use Cases

Sport Trainning Management has been used in two experimental applications: Live Synchro Swimming and 3D Acrobatics.

API

Before describing the API, some definitions are introduced to set concepts and avoid confusion:

  • Sport or discipline: here both terms are used with the same manner. Synchronized swimming, swimming, water polo are considered then different sports even if they are managed by the same International Sport Federation.
  • Training attempt: the minimal expression of the performance from the sport: in trampoline for example it would be just one jump; in synchronized swimming it would we the execution of the routine or just one figure.
  • Training session: a set of training attempt that are occur the same day and probably in just one morning or afternoon.
  • Modality: a lot of sport can be performed in different ways, for example in swimming there exist freestyle, breaststroke, backstroke and butterfly. Each of them would be a different modality. In case of synchronized swimming there exist have solos, duets, trios, combos, or teams.
  • Training pattern: a set ot repeated routines and movements performed always in the same way. Depending on a sport, can be associated to a training session or training attempt before it starts.

List of functions

Overall services for training modules

This module allows adding, updating and removing disciplines and hardware from the system.

The URL from the WSDL is http://{host_name}/CarExperimediaServices/OverallServices?wsdl

In the following table we have the list of methods implemented by this service:

Discipline getDiscipline (String code) throws OverallServiceException Retrieves the discipline identified by the code. If none exists, null is returned.
void addDiscipline (Discipline discipline, String userName)throws OverallServiceException Adds a new discipline to the database. The username will be the email address of the person who is adding the discipline. The system won’t check it the person is valid or not. The identification of the discipline is given by the discipline.code and it is the user of the service who indicates this code. The method will throw an exception if somebody tries to add two disciplines with the same code.
void updateDiscipline (Discipline discipline, String userName) throws OverallServiceException Updates an existing discipline. The username will be the email address of the person who is adding the discipline. The system won’t check it the person is valid or not.
List<Discipline> listDisciplines () throws OverallServiceException Returns the full list of disciplines
List<Discipline> searchDisciplines (String textToSearch) throws OverallServiceException Returns the list of disciplines where the name or it’s code contains the textToSearch
void deleteDiscipline (String code)throws OverallServiceException Removes the discipline identified by code from the database.
Hardware getHardware (Integer id) throws OverallServiceException Returns the hardware identified by that id. If none matches, null is returned.
int addHardware (Hardware hardware, String password, String username)throws OverallServiceException Adds new hardware to the database. The username will be the email address of the person who is adding the discipline. The system won’t check it the person is valid or not. The password is the one required to access to the hardware, if needed. It can be null.
void updateHardware (Hardware hardware, String password, String userName)throws OverallServiceException Updates the hardware in the database. The username will be the email address of the person who is adding the discipline. The system won’t check it the person is valid or not. The password is the one required to access to the hardware, if needed.
void deleteHardware (Integer id)throws OverallServiceException Removes the hardware identified by that id from the system.
List<Hardware> listHardware () throws OverallServiceException Returns the list of all existing hardware
List<Hardware> searchHardware (String searchCriteria) throws OverallServiceException Returns the list of hardware where their descriptiveText matches with the search criteria
Modality getModality (Integer id) throws OverallServiceException Returns the Modality identified with the id. Null is returned when no object exists with that id.
long getAvailableSpaceBytes (Discipline discipline) Returns the available space in bytes for a specific discipline.
long getOccupiedSpaceBytes (Discipline discipline) Returns the occupied space in bytes from a specific discipline. The occupied space is computed with the occupied space for their Files.
boolean existsHardware (String ip, Integer portNumber) throws OverallServiceException Returns true if any hardware exists with the same ip and port number.
List<Modality> getModalityListFromDiscipline (String disciplineCode) Returns the list of modalities belonging to a discipline identified by disciplineCode
boolean pingHardware (Integer id) throws OverallServiceException Return true if a ping to the hardware identified by id was successful.

User services

It is possible to retrieve information from any user using this service. Also it is possible to validate the login using this service. It is the obligation of all the sport dependent applications to check if the user connecting is valid or not through the methods exposed within this web service.

The URL from the WSDL is http://{host_name}/CarExperimediaServices/UserServices?wsdl

In the following table we have the list of methods implemented by this service:

Person getPerson (String email) throws UserServiceException Retrieves of a person identified by the email. If none exists, null is returned
void addPerson (Person person, String password, String userName) throws UserServiceException Adds a new person or user to the database. The username will be the email address of the person who is adding the person. The system won’t check it the email is valid or not. The identification of the person is given by the person.email and it is the user of the service who indicates this code. The method will throw an exception if somebody tries to add two persons with the same email.
void updatePerson (Person person, String password, String userName)throws UserServiceException Updates a person in the database. The username will be the email address of the person who is updating the person. The system won’t check it the email is valid or not. The password can be left empty to update other all other information from the structure of a person. It’s password to access to the system can be updated with the parameter password.
void deletePerson (String email)throws UserServiceException Removes a person identified by that email from the system.
List<Person> listPerson () throws UserServiceException Returns the list of all existing persons
List<Person> searchPerson (String searchCriteria) throws UserServiceException Returns the list of persons where their email, given name or surname contains the search criteria
Person doLogin (String email, String password) throws UserServiceException Checks if the email exist in the database and if the password is the proper one. The person from the email is returned when the credentials a right, otherwise null is returned.
List<Person> getActiveAthletesFromDiscipline (String disciplineCode) throws UserServiceException Returns the list of persons with role of ATHLETE that are active in the system and that have as discipline the disciplineCode or ALL.
List<Person> getActiveCoachesFromDiscipline (String disciplineCode) throws UserServiceException Returns the list of persons with role of COACH that are active in the system and that have as discipline the disciplineCode or ALL.
Response getActiveAthletesFromCoach (String email, String password, HttpServletRequest request) throws UserServiceException Returns the list of persons with role of ATHLETE and associated to the disciplines of the coach given identified by the email.

Usage services

This module provides ways to record the statistical data about how the system is used.

Examples of data recorded ara: if there is an evolution from the coach and if they use the system remotely, at what time they connect, from which kind of devices they like to connect.

These services provides a way to record logs. Each experiment is free to use it as it wants and should be distinguished by the discipline it is implemented for.

These services works with sessions. Each session has an id, username, discipline, start and end timestamps. The action has and id, timestamp, session id, action type, 10 parameters names and its respective 10 parameter values and an action result.

The action type, parameter names and values and result are for free use of each application. The times (session start, end time, and action timestamp) are recorded by the service.

The URL from the WSDL is http://{host_name}/CarExperimediaServices/UsageServices?wsdl

The following methods are implemented in this service:

int startSession (String discipline, String user) A user is starting a new session. A new entry of session with the current starting time is recorded in the database. The id of the new session is returned.
void endSession (int sessionId) The session ends. The end time of the session is automatically updated with the current time.
void addActionToSession (int sessionId, String actionType, String actionParameterName, String actionParameterValue, String actionResult) A new action entry is recorded in the database. Its timestamp is automatically recorded with the current time. Just one parameter name and value can be indicated.
void addActionToSessionParams (int sessionId, String actionType, String[] actionParameterNames, String[] actionParameterValues, String actionResult) A new action entry is recorded in the database. Its timestamp is automatically recorded with the current time. A maximum of 10 parameter names and values can be recorded in the database.

Training management and control

This module gives the services like starting, removing training session or training attempt.

The training attempts in different disciplines have a lot of similarities: there is a start time, and end time, coaches and athletes involved, it is for a specific sport and modality, the athlete is using some special equipment.

The training attempts have a lot of similarities during their execution: something triggers their start, something triggers their end, some action can be performed once the session has ended, etc.

A logical folder structure can be created in the database. This can be used to classify the training patterns, sessions and attempt, therefore it is included in this service.

The URL from the WSDL is http://{host_name}/CarExperimediaServices/TrainingManagementServices?wsdl

In the following table we have the list of methods implemented by this service:

TrainingPattern getTrainingPattern (Integer id) throws TrainingManagementServiceException Returns the training pattern identified by id. If it does not exist, null is returned. The modality list from the discipline will not be null. In order to get the modality list from a discipline use the getDiscipline from OverallServices.
int addTrainingPattern (TrainingPattern trainingPattern, String userName) throws TrainingManagementServiceException Adds a new training pattern to the database. The username will not be the email address of the person who is adding the discipline. The system will not not check it the person is valid or not. The pattern has a list of coaches, participants, files and annotations that can be informed. They will not be recorded in the database.
void updateTrainingPattern (TrainingPattern trainingPattern, String userName) throws TrainingManagementServiceException Updates a new training pattern from the database. The username will not be the email address of the person who is adding the training pattern. The system will not not check it the person is valid or not. If the pattern has a list of coaches, participants, files or annotations are informed, they will not be recorded in the database.
void deleteTrainingPattern (Integer id)throws TrainingManagementServiceException Deletes a training pattern from the database.
List<TrainingPattern> listTrainingPattern() throws TrainingManagementServiceException Returns the full list of existing training patterns. Please refer getTrainingPattern to know until which level of sub-list will not be returned.
List<TrainingPattern> listTrainingPatternFromModality (Modality modality) throws TrainingManagementServiceException Lists all the training patterns associated to that modality. The modality cannot be null, otherwise null pointer exception will not be thrown. Please refer getTrainingPattern to know until which level of sub-list will not be returned.
Integer startTrainingSession (Modality modality, TrainingPattern trainingPattern, List<Person> coachList, List<Participant>athletes, List<EnvironmentCondition> environmentConditionList, String userName) throws TrainingManagementServiceException Starts a new training session for a specific modality with the given parameters (training pattern, coachList, athletes, environmentConditionList). Any of these parameters can be null. The username will not be the email address of the person who is starting the training session. The system won’t check it the person is valid or not. The id from the training session is returned.
Integer startTrainingAttempt (Integer trainingSessionId, TrainingPattern trainingPattern, List<Person> coachList, List<Participant> athletes, List<EnvironmentCondition> environmentConditionList, String userName) throws TrainingManagementServiceException Starts a new training attempt for a specific training session. The training session must be. The parameters trainingPattern, coachList, athletes, environmentConditionList any of them can be null. The username will not be the email address of the person who is starting the training attempt. The system will not not check it the person is valid or not. The id of the training attempt is returned.
void addFileToTrainingSession (Integer trainingSessionId, File file)throws TrainingManagementServiceException, IOException, DiskSpaceException A file is added to a started training session. The system throws an exception when the file overtakes the assigned discipline disk quota. MTOM from SOA is used to upload the files.
void addFileToTrainingAttempt (Integer trainingAttemptId, File file)throws TrainingManagementServiceException, IOException, DiskSpaceException A file is added to a started training attempt. The system throws an exception when the file overtakes the assigned discipline disk quota. MTOM from SOA is used to upload the files.
void closeTrainingSession (Integer trainingSessionId, String userName)throws TrainingManagementServiceException Closes a training session identified by trainingSessionId. The username will not be the email address of the person who is closing the training session. The system will not not check it the person is valid or not.
void closeTrainingAttempt (Integer trainingAttemptId, String userName)throws TrainingManagementServiceException Closes a training attempt identified by trainingAttemptId. The username will not be the email address of the person who is closing the training attempt. The system will not not check it the person is valid or not.
List<TrainingAttempt> listTrainingAttemptFromModality (Modality modality) throws TrainingManagementServiceException Returns the full list of training attempts associated to a specific modality. The modality cannot be null. The modality list from the discipline will not be null. In order to get the modality list from a discipline use the getDiscipline from OverallServices.
List<TrainingSession> listTrainingSessionFromModality (Modality modality) throws TrainingManagementServiceException Returns the full list of training sessions associated to a specific modality. The modality cannot be null. The modality list from the discipline will not be null. In order to get the modality list from a discipline use the getDiscipline from OverallServices.
void deleteTrainingSession (Integer id) throws TrainingManagementServiceException Removes the training session with that specific id from the database. It does not check the flag isRemovable from the training session. The id cannot be null.
void deleteTrainingAttemppt (Integer id) throws TrainingManagementServiceException Removes the training attempt with that specific id from the database. It does not check the flag isRemovable from the training session. The id cannot be null.
DataHandler downoadFile (File file) Download the content of the file given as parameter.
Folder getFolder (Integer id) throws TrainingManagementServiceException Returns the older identified by id. If it does not exist, null is returned
List<Folder> getRootFolders (String disciplineCode) throws TrainingManagementServiceException Returns the list of root folder from a specific discipline.
void deleteFolder (Integer id, String username) throws TrainingManagementServiceException Removes a folder. The username is the email from the person that wants to remove the folder.
int addItemToFolder (Integer folderId, FolderItem folderItem, String username) throws TrainingManagementServiceException Adds a Folder Item to the folder identified by folderId. The username is the email from the person that wants to add the item. This method return the id assigned to the new FolderItem.
int addSubfolderToFolder (Integer folderId, Folder subfolder, String username) throws TrainingManagementServiceException Adds a subfolder to the folder identified by folderId. The username is the email from the person that wants to add the folder. This method return the id assigned to the new subfolder.
int addRootFolder (String discipline, String name, String username) throws TrainingManagementServiceException Adds a root folder to a specific discipline identified by the discipline field. Name will not be the name of the folder. Username is the email from the person that wants to add the root folder. This method return the id assigned to the new root folder.

Media services for training modules

This module provides services to interact with the AVCC services. It allows to interact with the hardware (cameras) and to start and stop the recording, either for training sessions or training patterns.

The URL from the WSDL is http://{host_name}/CarExperimediaServices/MediaServices?wsdl

The methods implemented by this service are the following ones:

String getServerURL () throws MediaServiceException Returns the streaming server url.
String publishCameraOnServer (Integer cameraId) throws MediaServiceException Publishes a specific camera in the streaming server. The camerId has to correspond to a hardware id. Returns the name of the streaming channel assigned to the camera.
LiveModality startAndPublishCamerasFromTrainingSession (Integer trainingSessionId) throws MediaServiceException Publishes all camera associated to the modality of the training session in the streaming server. The trainingSessionId has to correspond to an id of a started training session (TrainingManagementServices). Returns a LiveModality, this object contains the names of streams from all the cameras that are being published. Throws and exception when the cameras from the modality are already in use.
LiveModality startAndPublishCamerasFromTrainingAttempt (Integer trainingAttemptId) throws MediaServiceException Publishes all camera associated to the modality of the training attempt in the streaming server. The trainingAttemptId has to correspond to an id of a started training attempt (TrainingManagementServices). Returns a LiveModality, this object contains the names of streams from all the cameras that are being published. Throws and exception when the cameras from the modality are already in use.
LiveModality startAndPublishCamerasFromModality (Integer modalityId) throws MediaServiceException Publishes all camera associated to the modality. Returns a LiveModality, this object contains the names of streams from all the cameras that are being published. Throws and exception when the cameras from the modality are already in use.
void stopAndUnpublishCamerasFromTrainingSession (Integer trainingSessionId) throws MediaServiceException Stops the publishing of camera associated to the modality of the training session in the streaming server. Throws and exception if the training session doesn’t exist. The training session must be started.
void stopAndUnpublishCamerasFromTrainingAttempt (Integer trainingAttemptId) throws MediaServiceException Stops the publishing of camera associated to the modality of the training attempt in the streaming server. Throws and exception if the training session doesn’t exist. The training session attempt must be started.
void stopAndUnpublishCamerasFromModality (Integer modalityId) throws MediaServiceException Stops the publishing of camera associated to the modality in the streaming server. Throws and exception if the training session doesn’t exist.
LiveModality getPublishedCamerasFromModality (Integer modalityId ) throws MediaServiceException Returns de LiveModality structure from a specific modalityId.
File getThumbnailFromHardware (Modality modality, Hardware hardware, String imageSize) throws MediaServiceException Makes a thumbnail image from and live stream, therefore a training session or attempt must be started for that modality. The modality must have the hardware associated. The imagesize is specified in pixels as widthxheigh (e.g.: 430x340)
File getThumbnailFromLiveStream (Modality modality, String streamName, String imageSize) throws MediaServiceException Makes a thumbnail image from and live stream. The stream name can be retrieved from the LiveModality object, its CameraStreamName. A training session or attempt must be started for that modality. The modality must have the hardware associated. The imagesize is specified in pixels as widthxheigh (e.g.: 430x340)

Annotation services training modules

This module allows interaction with training sessions or attempts to insert annotations, intended to add information about some specific moment of the performance ot the training session or attempt.

The URL from the WSDL is http://{host_name}/CarExperimediaServices/AnnotationServices?wsdl

The methods implemented by this service are the following ones:

AnnotationType getAnnotationType (Integer id) throws AnnotationServiceException Returns the annotation type identified by id. If it doesn’t exist, null is returned.
int addAnnotationType (AnnotationType annotationType, String userName)throws AnnotationServiceException Adds a new annotationType to the database. The username will be the email address of the person who is adding the annotationType. The system won’t check it the person is valid or not. The annotationType has a list of terms, in case it is informed, it will be recorded in the database.
void updateAnnotationType (AnnotationType annotationType, String userName) throws AnnotationServiceException Updates an annotationType to the database. The username will be the email address of the person who is updating the annotationType. The system won’t check it the person is valid or not. The annotationType has a list of terms, in case it is informed, it will be also updated in the database.
List<AnnotationType> listAnnotationType (Discipline discipline) throws AnnotationServiceException Returns the list of annotationType for a specific discipline.
Boolean existsAnnotationType (AnnotationType annotationType) throws AnnotationServiceException Checks if an annotation type with the same name and discipline exists in the database.
void deleteAnnotationType (Integer id)throws AnnotationServiceException Removes an annotationType identified by the id.
void addAnnotationToTrainingSession (Integer trainingSessionId, Annotation annotation)throws AnnotationServiceException Adds an annotation to a training session. The training session must have been started.
void addAnnotationToTrainingAttempt (Integer trainingAttemptId, Annotation annotation)throws AnnotationServiceException Adds an annotation to a training attempt. The training session must have been started
void addRecordedMarkToTrainingSession (Integer trainingSessionId, String email)throws AnnotationServiceException Adds a recorded mark to the training session, the recorded mark be synchronized and streamed with the audio-visual content. Once the training session is closed it will be recorded in the database.
void addRecordedMarkToTrainingAttempt (Integer trainingAttemptId, String email)throws AnnotationServiceException Adds a recorded mark to the training attempt, the recorded mark be synchronized and streamed with the audio-visual content. Once the training session is closed it will be recorded in the database.
void editRecordedMarkText (Integer id, String text, String email) throws AnnotationServiceException Once the training session or attempt has been closed, a recording mark can be changed and a text can be added to it.

User Interface

For EXPERIMEDIA, an administration tool has been developed.

It is in common for all experiments, and it can be used by CAR in case they need to add more experiments.

With these tool an administrator can add and remove disciplines, modalities, user, annotation types and hardware assigned to each modality.

Access to the application

The URL access to the administration module is http://{host_name}/CarExperimediaAdministration/

Email and password of the user must be introduced in the fields “Email” and “Password” of the login page.

Once these fields are informed, button “Login” is pressed to start the process of user authentication.

Screenshot of the login screen for the Service Management System

Add user

To add a new user, select the button “User” at the left menu.

Fill all fields with information about the new user.

Select a discipline (in this case, all disciplines or Synchronized Swimming)

Select a role for the new user

Select the check “Is active”

Press the button “Add user”

If the creation of the new user has been properly finished, a message confirming it will be displayed.

Screenshot of the "Add User" screen for the Service Management System

Search and update users

To search users, press the button “Search” and a list with all existing users will be displayed.

To update an existing user, select it from this users list and information about it will be displayed in the right side form.

Update any attribute and press the button “Update”.

Screenshot of the "Search and update user" screen for the Service Management System

Delete users

To delete hardware, press the button “Search” to display the list with all the existing users.

Press the red cross corresponding to the user to be deleted.

Screenshot of the "Delete user" screen for the Service Management System

Add hardware

To add hardware, select the button “Hardware” at the left menu.

At the right side, in the field “HW Type”, select the type of software to be added (in this case, Camera)

Screenshot of the "Add hardware" screen for the Service Management System

Once selected the type of software to be added, fill the fields “Description”, “IP” and “Port number” with the proper values.

Select the check “Is default”.

It is important to select this check, since it will be the camera which will stream the video by default.

Screenshot of the "Add hardware" screen for the Service Management System

Search and update hardware

To search hardware, press the button “Search”. A list with all the available software will be displayed.

Select a row from this list and information about this software will be displayed at the right side.

Modify the desired values and press the button “Update”

If the updating is properly completed, a message will be displayed.

Screenshot of the "Search and update hardware" screen for the Service Management System

Delete hardware

To delete hardware, press the button “Search” to display the list with all the available hardware.

Press the red cross corresponding to the hardware to be deleted.

Screenshot of the "Delete hardware" screen for the Service Management System

Add modalities to a discipline

When the option “Discipline and modalities” is chosen at the left menu and the button “Search” is pressed, two records are displayed, by default: “All disciplines” and “Synchronized swimming”.

To add modalities to Synchronized Swimming, select this record and information to this discipline will be displayed at the right side.

Screenshot of the "Add modalities" screen for the Service Management System

Insert the name of the modality to be added.

Press the button “Add modality”

The modality will be displayed in the list modalities associated to the discipline.

Screenshot of the "Add modalities" screen for the Service Management System

Select the modality newly created

Select the software to be associated to this modality

Press the button “Update”

If the update process is properly done, a message will be displayed

Screenshot of the "Add modalities" screen for the Service Management System

Delete modalities from a discipline

To delete a modality from a given discipline, press the red cross corresponding to the modality to be deleted.

Press the button “Update”

If the deletion is properly done, a message will be displayed

Screenshot of the "Delete modalities" screen for the Service Management System

Add annotations and terms to a discipline

Select the “Annotation types and terms” option at the left menu

Select the option Synchronized Swimming at the combo

Press the button “Select”

Screenshot of the "Add annotations and terms" screen for the Service Management System

Insert the description of the annotation to be added

Insert the color associated to the annotation to be added.

The color can be inserted either introducing the hexadecimal code or choosing it into the pop up color selector

Screenshot of the "Add annotations and terms" screen for the Service Management System

Once the description and the color associated to the new annotation, press the button “Add annotation type”

To see it listed below the disciplines combo, press the button “Select”

Screenshot of the "Add annotations and terms" screen for the Service Management System

An annotation may have a series of terms associated.

To associate a term to an annotation, select the annotation at the list below the disciplines combo

Insert the name of the term in the text field

Press the button “Add term”

Screenshot of the "Add annotations and terms" screen for the Service Management System

Repeat this process described in the previous slide as many times as terms are desired to add

The added terms are displayed at the table below the annotation attributes

When all terms have been added, press the button “Update”

If the updating process is properly done, a message will be displayed

Screenshot of the "Add annotations and terms" screen for the Service Management System

Log out

To log out from the application, press the button “Log out” at the left menu

User will be redirected to the application access page

Screenshot of the "Add annotations and terms" screen for the Service Management System

Contact & Support Information

Contact

Pablo Salinero Ruiz
Medialab, Atos

Support

See Contact.

Licensing

Copyright (c) 2012-2014 Atos Spain
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sub-license, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.