This is an automated email from the git hooks/post-receive script. New commit to branch feature/7459 in repository tutti. See https://gitlab.nuiton.org/codelutin/tutti.git commit 1a3421d787f401b6a68eb636266b49e2ad2f620e Author: Kevin Morin <morin@codelutin.com> Date: Wed Apr 20 15:34:01 2016 +0200 ajout de la conf du port série du pied a coulisse (refs #7459) --- .../java/fr/ifremer/tutti/TuttiConfiguration.java | 29 +++++++++-------- .../fr/ifremer/tutti/TuttiConfigurationOption.java | 32 +++++++++++-------- .../java/fr/ifremer/tutti/util/SerialPort.java | 12 ++++++++ .../i18n/tutti-persistence_en_GB.properties | 7 +++++ .../i18n/tutti-persistence_fr_FR.properties | 7 +++++ .../swing/content/config/TuttiConfigUIHandler.java | 36 +++++++++++++--------- .../ifremer/tutti/ui/swing/util/SoundEngine.java | 14 ++++----- .../resources/i18n/tutti-ui-swing_en_GB.properties | 9 ++++++ .../resources/i18n/tutti-ui-swing_fr_FR.properties | 9 ++++++ 9 files changed, 110 insertions(+), 45 deletions(-) diff --git a/tutti-persistence/src/main/java/fr/ifremer/tutti/TuttiConfiguration.java b/tutti-persistence/src/main/java/fr/ifremer/tutti/TuttiConfiguration.java index 45bea6e..613b18c 100644 --- a/tutti-persistence/src/main/java/fr/ifremer/tutti/TuttiConfiguration.java +++ b/tutti-persistence/src/main/java/fr/ifremer/tutti/TuttiConfiguration.java @@ -29,6 +29,7 @@ import fr.ifremer.tutti.persistence.entities.data.SampleCategoryModel; import fr.ifremer.tutti.type.CoordinateEditorType; import fr.ifremer.tutti.type.WeightUnit; import fr.ifremer.tutti.util.BeepFrequency; +import fr.ifremer.tutti.util.SerialPort; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.builder.ReflectionToStringBuilder; import org.apache.commons.logging.Log; @@ -732,28 +733,32 @@ public class TuttiConfiguration extends ApplicationConfiguration { return applicationConfig.getOptionAsInt(TuttiConfigurationOption.ICHTYOMETER_MAXIMUM_NUMBER_OF_ATTEMPT_TO_CONNECT.getKey()); } - public Boolean isIchtyometerVoiceEnabled() { - return applicationConfig.getOptionAsBoolean(TuttiConfigurationOption.ICHTYOMETER_VOICE_ENABLED.getKey()); + public SerialPort getCaliperSerialPort() { + return SerialPort.valueOf(applicationConfig.getOption(TuttiConfigurationOption.CALIPER_SERIAL_PORT.getKey())); } - public Boolean isIchtyometerReadsUnit() { - return applicationConfig.getOptionAsBoolean(TuttiConfigurationOption.ICHTYOMETER_READS_UNIT.getKey()); + public Boolean isExternalDevicesVoiceEnabled() { + return applicationConfig.getOptionAsBoolean(TuttiConfigurationOption.EXTERNAL_DEVICES_VOICE_ENABLED.getKey()); } - public Boolean isIchtyometerDataReceptionBeepEnabled() { - return applicationConfig.getOptionAsBoolean(TuttiConfigurationOption.ICHTYOMETER_DATA_RECEPTION_BEEP_ENABLED.getKey()); + public Boolean isExternalDevicesReadsUnit() { + return applicationConfig.getOptionAsBoolean(TuttiConfigurationOption.EXTERNAL_DEVICES_READS_UNIT.getKey()); } - public BeepFrequency getIchtyometerDataReceptionBeepFrequency() { - return BeepFrequency.valueOf(applicationConfig.getOption(TuttiConfigurationOption.ICHTYOMETER_DATA_RECEPTION_BEEP_FREQUENCY.getKey())); + public Boolean isExternalDevicesDataReceptionBeepEnabled() { + return applicationConfig.getOptionAsBoolean(TuttiConfigurationOption.EXTERNAL_DEVICES_DATA_RECEPTION_BEEP_ENABLED.getKey()); } - public Boolean isIchtyometerErrorReceptionBeepEnabled() { - return applicationConfig.getOptionAsBoolean(TuttiConfigurationOption.ICHTYOMETER_ERROR_RECEPTION_BEEP_ENABLED.getKey()); + public BeepFrequency getExternalDevicesDataReceptionBeepFrequency() { + return BeepFrequency.valueOf(applicationConfig.getOption(TuttiConfigurationOption.EXTERNAL_DEVICES_DATA_RECEPTION_BEEP_FREQUENCY.getKey())); } - public BeepFrequency getIchtyometerErrorReceptionBeepFrequency() { - return BeepFrequency.valueOf(applicationConfig.getOption(TuttiConfigurationOption.ICHTYOMETER_ERROR_RECEPTION_BEEP_FREQUENCY.getKey())); + public Boolean isExternalDevicesErrorReceptionBeepEnabled() { + return applicationConfig.getOptionAsBoolean(TuttiConfigurationOption.EXTERNAL_DEVICES_ERROR_RECEPTION_BEEP_ENABLED.getKey()); + } + + public BeepFrequency getExternalDevicesErrorReceptionBeepFrequency() { + return BeepFrequency.valueOf(applicationConfig.getOption(TuttiConfigurationOption.EXTERNAL_DEVICES_ERROR_RECEPTION_BEEP_FREQUENCY.getKey())); } public String getJavaCommandPath() { diff --git a/tutti-persistence/src/main/java/fr/ifremer/tutti/TuttiConfigurationOption.java b/tutti-persistence/src/main/java/fr/ifremer/tutti/TuttiConfigurationOption.java index e989798..a758b60 100644 --- a/tutti-persistence/src/main/java/fr/ifremer/tutti/TuttiConfigurationOption.java +++ b/tutti-persistence/src/main/java/fr/ifremer/tutti/TuttiConfigurationOption.java @@ -26,6 +26,7 @@ import fr.ifremer.tutti.persistence.entities.data.SampleCategoryModel; import fr.ifremer.tutti.type.CoordinateEditorType; import fr.ifremer.tutti.type.WeightUnit; import fr.ifremer.tutti.util.BeepFrequency; +import fr.ifremer.tutti.util.SerialPort; import org.hibernate.dialect.HSQLDialect; import org.hsqldb.jdbcDriver; import org.nuiton.config.ConfigOptionDef; @@ -646,44 +647,51 @@ public enum TuttiConfigurationOption implements ConfigOptionDef { int.class, false ), - ICHTYOMETER_VOICE_ENABLED( + CALIPER_SERIAL_PORT( + "tutti.ichtyometer.caliperSerialPort", + n("tutti.config.option.externalDevices.maximumNumberOfAttemptToConnect.description"), + "COM1", + SerialPort.class, + false + ), + EXTERNAL_DEVICES_VOICE_ENABLED( "tutti.ichtyometer.voice.enabled", - n("tutti.config.option.ichtyometer.voice.enabled.description"), + n("tutti.config.option.externalDevices.voice.enabled.description"), "true", Boolean.class, false ), - ICHTYOMETER_READS_UNIT( + EXTERNAL_DEVICES_READS_UNIT( "tutti.ichtyometer.reads.unit", - n("tutti.config.option.ichtyometer.reads.unit.description"), + n("tutti.config.option.externalDevices.reads.unit.description"), "true", Boolean.class, false ), - ICHTYOMETER_DATA_RECEPTION_BEEP_ENABLED( + EXTERNAL_DEVICES_DATA_RECEPTION_BEEP_ENABLED( "tutti.ichtyometer.beep.data.enabled", - n("tutti.config.option.ichtyometer.beep.data.enabled.description"), + n("tutti.config.option.externalDevices.beep.data.enabled.description"), "true", Boolean.class, false ), - ICHTYOMETER_DATA_RECEPTION_BEEP_FREQUENCY( + EXTERNAL_DEVICES_DATA_RECEPTION_BEEP_FREQUENCY( "tutti.ichtyometer.beep.data.frequency", - n("tutti.config.option.ichtyometer.beep.data.frequency.description"), + n("tutti.config.option.externalDevices.beep.data.frequency.description"), "A2", BeepFrequency.class, false ), - ICHTYOMETER_ERROR_RECEPTION_BEEP_ENABLED( + EXTERNAL_DEVICES_ERROR_RECEPTION_BEEP_ENABLED( "tutti.ichtyometer.beep.error.enabled", - n("tutti.config.option.ichtyometer.beep.error.enabled.description"), + n("tutti.config.option.externalDevices.beep.error.enabled.description"), "true", Boolean.class, false ), - ICHTYOMETER_ERROR_RECEPTION_BEEP_FREQUENCY( + EXTERNAL_DEVICES_ERROR_RECEPTION_BEEP_FREQUENCY( "tutti.ichtyometer.beep.error.frequency", - n("tutti.config.option.ichtyometer.beep.error.frequency.description"), + n("tutti.config.option.externalDevices.beep.error.frequency.description"), "A1", BeepFrequency.class, false diff --git a/tutti-persistence/src/main/java/fr/ifremer/tutti/util/SerialPort.java b/tutti-persistence/src/main/java/fr/ifremer/tutti/util/SerialPort.java new file mode 100644 index 0000000..6cd4ba7 --- /dev/null +++ b/tutti-persistence/src/main/java/fr/ifremer/tutti/util/SerialPort.java @@ -0,0 +1,12 @@ +package fr.ifremer.tutti.util; + +/** + * @author Kevin Morin (Code Lutin) + * @since 4.5 + */ +public enum SerialPort { + + COM1, + COM2, + COM3 +} diff --git a/tutti-persistence/src/main/resources/i18n/tutti-persistence_en_GB.properties b/tutti-persistence/src/main/resources/i18n/tutti-persistence_en_GB.properties index 4878154..e9fd0bc 100644 --- a/tutti-persistence/src/main/resources/i18n/tutti-persistence_en_GB.properties +++ b/tutti-persistence/src/main/resources/i18n/tutti-persistence_en_GB.properties @@ -18,6 +18,13 @@ tutti.config.option.db.import.skipBackup.description= tutti.config.option.errorBeepFrequency.description= tutti.config.option.export.backup.directory.description= tutti.config.option.export.countryId.description= +tutti.config.option.externalDevices.beep.data.enabled.description= +tutti.config.option.externalDevices.beep.data.frequency.description= +tutti.config.option.externalDevices.beep.error.enabled.description= +tutti.config.option.externalDevices.beep.error.frequency.description= +tutti.config.option.externalDevices.maximumNumberOfAttemptToConnect.description= +tutti.config.option.externalDevices.reads.unit.description= +tutti.config.option.externalDevices.voice.enabled.description= tutti.config.option.genericFormat.import.maximumRowsInErrorPerFile.description= tutti.config.option.genericFormat.import.skipBackup.description= tutti.config.option.genericFormat.report.backup.directory.description= diff --git a/tutti-persistence/src/main/resources/i18n/tutti-persistence_fr_FR.properties b/tutti-persistence/src/main/resources/i18n/tutti-persistence_fr_FR.properties index dec1cfb..b64b634 100644 --- a/tutti-persistence/src/main/resources/i18n/tutti-persistence_fr_FR.properties +++ b/tutti-persistence/src/main/resources/i18n/tutti-persistence_fr_FR.properties @@ -11,6 +11,13 @@ tutti.config.option.data.directory.description=Répertoire de données de l'appl tutti.config.option.db.import.skipBackup.description=Pour ne pas effectuer une sauvegarde avant un import de base tutti.config.option.export.backup.directory.description=Répertoire où sont enregistrées les exports génériques tutti.config.option.export.countryId.description=L'id du pays à utiliser pour les exports (il s'agit de la valeur LOCATION.ID). +tutti.config.option.externalDevices.beep.data.enabled.description= +tutti.config.option.externalDevices.beep.data.frequency.description= +tutti.config.option.externalDevices.beep.error.enabled.description= +tutti.config.option.externalDevices.beep.error.frequency.description= +tutti.config.option.externalDevices.maximumNumberOfAttemptToConnect.description= +tutti.config.option.externalDevices.reads.unit.description= +tutti.config.option.externalDevices.voice.enabled.description= tutti.config.option.genericFormat.import.maximumRowsInErrorPerFile.description=Nombre maximum de lignes en erreur possible par fichier lors de la validation de l'import générique tutti.config.option.genericFormat.import.skipBackup.description=Pour ne pas effectuer une sauvegarde avant chaque import générique tutti.config.option.genericFormat.report.backup.directory.description=Répertoire où sont enregistrés les rapports de l'import générique diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/config/TuttiConfigUIHandler.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/config/TuttiConfigUIHandler.java index d60cb57..a43feaf 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/config/TuttiConfigUIHandler.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/config/TuttiConfigUIHandler.java @@ -256,8 +256,10 @@ public class TuttiConfigUIHandler extends AbstractTuttiUIHandler<TuttiUIContext, // ichtyometer category - helper.addCategory(n("tutti.config.category.ichtyometer"), - n("tutti.config.category.ichtyometer.description")) + helper.addCategory(n("tutti.config.category.externalDevices"), + n("tutti.config.category.externalDevices.description")) + + // ichtyometer .addOption(TuttiConfigurationOption.FULL_BLUETOOTH_SCAN) .setOptionShortLabel(t("tutti.config.option.ui.fullBluetoothScan.shortLabel")) @@ -265,24 +267,30 @@ public class TuttiConfigUIHandler extends AbstractTuttiUIHandler<TuttiUIContext, .addOption(TuttiConfigurationOption.ICHTYOMETER_MAXIMUM_NUMBER_OF_ATTEMPT_TO_CONNECT) .setOptionShortLabel(t("tutti.config.option.ui.ichtyometerMaximumNumberOfAttemptToConnect.shortLabel")) - .addOption(TuttiConfigurationOption.ICHTYOMETER_VOICE_ENABLED) - .setOptionShortLabel(t("tutti.config.option.ui.ichtyometerVoiceEnabled.shortLabel")) + // caliper + + .addOption(TuttiConfigurationOption.CALIPER_SERIAL_PORT) + .setOptionShortLabel(t("tutti.config.option.ui.caliperSerialPort.shortLabel")) + + // all devices - .addOption(TuttiConfigurationOption.ICHTYOMETER_READS_UNIT) - .setOptionShortLabel(t("tutti.config.option.ui.ichtyometerReadsUnit.shortLabel")) + .addOption(TuttiConfigurationOption.EXTERNAL_DEVICES_VOICE_ENABLED) + .setOptionShortLabel(t("tutti.config.option.ui.externalDevicesVoiceEnabled.shortLabel")) + .addOption(TuttiConfigurationOption.EXTERNAL_DEVICES_READS_UNIT) + .setOptionShortLabel(t("tutti.config.option.ui.externalDevicesReadsUnit.shortLabel")) - .addOption(TuttiConfigurationOption.ICHTYOMETER_DATA_RECEPTION_BEEP_ENABLED) - .setOptionShortLabel(t("tutti.config.option.ui.ichtyometerDataBeepEnabled.shortLabel")) + .addOption(TuttiConfigurationOption.EXTERNAL_DEVICES_DATA_RECEPTION_BEEP_ENABLED) + .setOptionShortLabel(t("tutti.config.option.ui.externalDevicesDataBeepEnabled.shortLabel")) - .addOption(TuttiConfigurationOption.ICHTYOMETER_DATA_RECEPTION_BEEP_FREQUENCY) - .setOptionShortLabel(t("tutti.config.option.ui.ichtyometerDataBeepFrequency.shortLabel")) + .addOption(TuttiConfigurationOption.EXTERNAL_DEVICES_DATA_RECEPTION_BEEP_FREQUENCY) + .setOptionShortLabel(t("tutti.config.option.ui.externalDevicesDataBeepFrequency.shortLabel")) - .addOption(TuttiConfigurationOption.ICHTYOMETER_ERROR_RECEPTION_BEEP_ENABLED) - .setOptionShortLabel(t("tutti.config.option.ui.ichtyometerErrorBeepEnabled.shortLabel")) + .addOption(TuttiConfigurationOption.EXTERNAL_DEVICES_ERROR_RECEPTION_BEEP_ENABLED) + .setOptionShortLabel(t("tutti.config.option.ui.externalDevicesErrorBeepEnabled.shortLabel")) - .addOption(TuttiConfigurationOption.ICHTYOMETER_ERROR_RECEPTION_BEEP_FREQUENCY) - .setOptionShortLabel(t("tutti.config.option.ui.ichtyometerErrorBeepFrequency.shortLabel")); + .addOption(TuttiConfigurationOption.EXTERNAL_DEVICES_ERROR_RECEPTION_BEEP_FREQUENCY) + .setOptionShortLabel(t("tutti.config.option.ui.externalDevicesErrorBeepFrequency.shortLabel")); // Technical category diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/util/SoundEngine.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/util/SoundEngine.java index a3f150a..2edf69d 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/util/SoundEngine.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/util/SoundEngine.java @@ -67,11 +67,11 @@ public class SoundEngine implements Closeable { public synchronized void beepOnIchtyometerDataReception(String unit, float aroundLengthStep) { - if (configuration.isIchtyometerDataReceptionBeepEnabled()) { - soundsToPlay.add(configuration.getIchtyometerDataReceptionBeepFrequency()); + if (configuration.isExternalDevicesDataReceptionBeepEnabled()) { + soundsToPlay.add(configuration.getExternalDevicesDataReceptionBeepFrequency()); } - if (configuration.isIchtyometerVoiceEnabled()) { + if (configuration.isExternalDevicesVoiceEnabled()) { soundsToPlay.add(new Measure(unit, aroundLengthStep)); } @@ -79,9 +79,9 @@ public class SoundEngine implements Closeable { public synchronized void beepOnIchtyometerErrorReception() { - if (configuration.isIchtyometerErrorReceptionBeepEnabled()) { + if (configuration.isExternalDevicesErrorReceptionBeepEnabled()) { for (int i = 0; i < 3; i++) { - soundsToPlay.add(configuration.getIchtyometerDataReceptionBeepFrequency()); + soundsToPlay.add(configuration.getExternalDevicesDataReceptionBeepFrequency()); } } @@ -136,7 +136,7 @@ public class SoundEngine implements Closeable { log.info("New Measure to say: " + measure); } String unit; - if (configuration.isIchtyometerReadsUnit()) { + if (configuration.isExternalDevicesReadsUnit()) { unit = measure.unit; } else { unit = null; @@ -144,7 +144,7 @@ public class SoundEngine implements Closeable { SoundUtil.readNumber(measure.aroundLengthStep, Optional.fromNullable(unit)); } else if (sound instanceof BeepFrequency) { - SoundUtil.beep(configuration.getIchtyometerErrorReceptionBeepFrequency()); + SoundUtil.beep(configuration.getExternalDevicesErrorReceptionBeepFrequency()); } } diff --git a/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties b/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties index f7e654d..162529f 100644 --- a/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties +++ b/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties @@ -153,6 +153,8 @@ tutti.config.action.reload.application= tutti.config.action.reload.ui= tutti.config.category.applications= tutti.config.category.applications.description= +tutti.config.category.externalDevices= +tutti.config.category.externalDevices.description= tutti.config.category.ichtyometer= tutti.config.category.ichtyometer.description= tutti.config.category.technical= @@ -185,6 +187,7 @@ tutti.config.option.site.url.shortLabel= tutti.config.option.tmp.directory.shortLabel= tutti.config.option.tremieCarousselVessel.shortLabel= tutti.config.option.ui.beepFrequency.shortLabel= +tutti.config.option.ui.caliperSerialPort.shortLabel= tutti.config.option.ui.color.alternateRow.shortLabel= tutti.config.option.ui.color.benthos.shortLabel= tutti.config.option.ui.color.blockingLayer.shortLabel= @@ -205,6 +208,12 @@ tutti.config.option.ui.config.file.shortLabel= tutti.config.option.ui.coordinateEditorType.shortLabel= tutti.config.option.ui.dateFormat.shortLabel= tutti.config.option.ui.db.import.skipBackup.shortLabel= +tutti.config.option.ui.externalDevicesDataBeepEnabled.shortLabel= +tutti.config.option.ui.externalDevicesDataBeepFrequency.shortLabel= +tutti.config.option.ui.externalDevicesErrorBeepEnabled.shortLabel= +tutti.config.option.ui.externalDevicesErrorBeepFrequency.shortLabel= +tutti.config.option.ui.externalDevicesReadsUnit.shortLabel= +tutti.config.option.ui.externalDevicesVoiceEnabled.shortLabel= tutti.config.option.ui.fullBluetoothScan.shortLabel= tutti.config.option.ui.genericFormat.import.maximumRowsInErrorPerFile.shortLabel= tutti.config.option.ui.genericFormat.import.skipBackup.shortLabel= diff --git a/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties b/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties index a99f983..f855570 100644 --- a/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties +++ b/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties @@ -125,6 +125,8 @@ tutti.config.action.reload.application=Recharger l'application tutti.config.action.reload.ui=Recharger l'interface graphique tutti.config.category.applications=Application tutti.config.category.applications.description=Application +tutti.config.category.externalDevices= +tutti.config.category.externalDevices.description= tutti.config.category.ichtyometer=Ichtyomètre tutti.config.category.ichtyometer.description=Ichtyomètre tutti.config.category.technical=Technique @@ -157,6 +159,7 @@ tutti.config.option.site.url.shortLabel=URL du site technique tutti.config.option.tmp.directory.shortLabel=Répertoire temporaire tutti.config.option.tremieCarousselVessel.shortLabel=Navire ayant un carrousel et une trémie tutti.config.option.ui.beepFrequency.shortLabel=Tonalité du bip +tutti.config.option.ui.caliperSerialPort.shortLabel= tutti.config.option.ui.color.alternateRow.shortLabel=Couleur alternée tutti.config.option.ui.color.benthos.shortLabel=Couleur des libellés de benthos (Écran Capture > Résumé) tutti.config.option.ui.color.blockingLayer.shortLabel=Couleur d'attente @@ -177,6 +180,12 @@ tutti.config.option.ui.config.file.shortLabel=Chemin du fichier de confirmation tutti.config.option.ui.coordinateEditorType.shortLabel=Formateur de coordonnées tutti.config.option.ui.dateFormat.shortLabel=Format des dates tutti.config.option.ui.db.import.skipBackup.shortLabel=Ne pas faire de sauvegarde avant un import de base +tutti.config.option.ui.externalDevicesDataBeepEnabled.shortLabel= +tutti.config.option.ui.externalDevicesDataBeepFrequency.shortLabel= +tutti.config.option.ui.externalDevicesErrorBeepEnabled.shortLabel= +tutti.config.option.ui.externalDevicesErrorBeepFrequency.shortLabel= +tutti.config.option.ui.externalDevicesReadsUnit.shortLabel= +tutti.config.option.ui.externalDevicesVoiceEnabled.shortLabel= tutti.config.option.ui.fullBluetoothScan.shortLabel=Recherche complète des périphériques bluetooth tutti.config.option.ui.genericFormat.import.maximumRowsInErrorPerFile.shortLabel=Nombre maximum de lignes en erreur possible par fichier lors de la validation de l'import générique tutti.config.option.ui.genericFormat.import.skipBackup.shortLabel=Ne pas faire de sauvegarde avant un import au format générique -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.