@@ -65,18 +65,17 @@ using NeutronsMC = soa::Join<aod::ZDCNMCCollRefs, aod::ZDCNeutrons>;
6565
6666using CascMCCoresFull = soa::Join<aod::CascMCCores, aod::CascMCCollRefs>;
6767
68- using StraCollisonsFull = soa::Join<aod::StraCollisions, aod::StraCents, aod::StraEvSels, aod::StraStamps>;
69- using StraCollisonFull = soa::Join<aod::StraCollisions, aod::StraCents, aod::StraEvSels, aod::StraStamps>::iterator;
68+ using StraCollisonsFull = soa::Join<aod::StraCollisions, aod::StraCents, aod::StraEvSels, aod::StraEvSelExtras, aod:: StraStamps>;
69+ using StraCollisonFull = soa::Join<aod::StraCollisions, aod::StraCents, aod::StraEvSels, aod::StraEvSelExtras, aod:: StraStamps>::iterator;
7070
71- using StraCollisonsFullMC = soa::Join<aod::StraCollisions, aod::StraCents, aod::StraEvSels, aod::StraStamps, aod::StraCollLabels>;
72- using StraCollisonFullMC = soa::Join<aod::StraCollisions, aod::StraCents, aod::StraEvSels, aod::StraStamps, aod::StraCollLabels>::iterator;
71+ using StraCollisonsFullMC = soa::Join<aod::StraCollisions, aod::StraCents, aod::StraEvSels, aod::StraEvSelExtras, aod:: StraStamps, aod::StraCollLabels>;
72+ using StraCollisonFullMC = soa::Join<aod::StraCollisions, aod::StraCents, aod::StraEvSels, aod::StraEvSelExtras, aod:: StraStamps, aod::StraCollLabels>::iterator;
7373
7474using StraMCCollisionsFull = soa::Join<aod::StraMCCollisions, aod::StraMCCollMults>;
7575using V0MCCoresFull = soa::Join<aod::V0MCCores, aod::V0MCCollRefs>;
7676
7777struct Derivedupcanalysis {
7878 HistogramRegistry histos{" Histos" , {}, OutputObjHandlingPolicy::AnalysisObject};
79-
8079 // master analysis switches
8180 Configurable<bool > analyseK0Short{" analyseK0Short" , true , " process K0Short-like candidates" };
8281 Configurable<bool > analyseLambda{" analyseLambda" , true , " process Lambda-like candidates" };
@@ -168,6 +167,13 @@ struct Derivedupcanalysis {
168167 Configurable<float > ft0a{" ft0a" , 100 ., " FT0A threshold" };
169168 Configurable<float > ft0c{" ft0c" , 50 ., " FT0C threshold" };
170169 Configurable<float > zdc{" zdc" , 1 ., " ZDC threshold" };
170+ Configurable<float > fddaTimeCut{" fddaTimeCut" , -1 ., " FDDA timing cut (ns); negative: no cut" };
171+ Configurable<float > fddcTimeCut{" fddcTimeCut" , -1 ., " FDDC timing cut (ns); negative: no cut" };
172+ Configurable<float > fv0aTimeCut{" fv0aTimeCut" , -1 ., " FV0A timing cut (ns); negative: no cut" };
173+ Configurable<float > ft0aTimeCut{" ft0aTimeCut" , -1 ., " FT0A timing cut (ns); negative: no cut" };
174+ Configurable<float > ft0cTimeCut{" ft0cTimeCut" , -1 ., " FT0C timing cut (ns); negative: no cut" };
175+ Configurable<float > zdcTimeCut{" zdcTimeCut" , 2 ., " ZDC timing cut (ns)" };
176+ Configurable<bool > requireZDCTiming{" requireZDCTiming" , true , " require valid ZDC timing for gap-side selection" };
171177 Configurable<int > genGapSide{" genGapSide" , 0 , " 0 -- A, 1 -- C, 2 -- double" };
172178 } upcCuts;
173179
@@ -213,6 +219,8 @@ struct Derivedupcanalysis {
213219 ConfigurableAxis axisFDDCampl{" axisFDDCampl" , {100 , 0 .0f , 2000 .0f }, " FDDCamplitude" };
214220 ConfigurableAxis axisZNAampl{" axisZNAampl" , {100 , 0 .0f , 250 .0f }, " ZNAamplitude" };
215221 ConfigurableAxis axisZNCampl{" axisZNCampl" , {100 , 0 .0f , 250 .0f }, " ZNCamplitude" };
222+ ConfigurableAxis axisFitTime{" axisFitTime" , {166 , -42 .5f , 40 .5f }, " FIT time (ns)" };
223+ ConfigurableAxis axisZdcTime{" axisZdcTime" , {110 , -12 .5f , 10 .0f }, " ZDC time (ns)" };
216224 } axisDetectors;
217225
218226 // for MC
@@ -268,7 +276,7 @@ struct Derivedupcanalysis {
268276 ConfigurableAxis axisOccupancy{" axisOccupancy" , {VARIABLE_WIDTH , 0 .0f , 250 .0f , 500 .0f , 750 .0f , 1000 .0f , 1500 .0f , 2000 .0f , 3000 .0f , 4500 .0f , 6000 .0f , 8000 .0f , 10000 .0f , 50000 .0f }, " Occupancy" };
269277
270278 // UPC axes
271- ConfigurableAxis axisSelGap{" axisSelGap" , {4 , -1.5 , 2 .5 }, " Gap side" };
279+ ConfigurableAxis axisSelGap{" axisSelGap" , {7 , -1.5 , 5 .5 }, " Gap side" };
272280
273281 // AP plot axes
274282 ConfigurableAxis axisAPAlpha{" axisAPAlpha" , {220 , -1 .1f , 1 .1f }, " V0 AP alpha" };
@@ -297,6 +305,8 @@ struct Derivedupcanalysis {
297305 ConfigurableAxis axisCtau{" axisCtau" , {200 , 0 .0f , 20 .0f }, " c x tau (cm)" };
298306
299307 static constexpr std::string_view kParticlenames [] = {" K0Short" , " Lambda" , " AntiLambda" , " Xi" , " AntiXi" , " Omega" , " AntiOmega" };
308+ static constexpr uint8_t kFT0TriggerBitIsActiveA = 5 ;
309+ static constexpr uint8_t kFT0TriggerBitIsActiveC = 6 ;
300310
301311 void setBits (std::bitset<kSelNum >& mask, std::initializer_list<int > selections)
302312 {
@@ -931,6 +941,22 @@ struct Derivedupcanalysis {
931941 histos.add (" eventQA/hFT0" , " hFT0" , kTH3D , {axisDetectors.axisFT0Aampl , axisDetectors.axisFT0Campl , axisSelGap});
932942 histos.add (" eventQA/hFDD" , " hFDD" , kTH3D , {axisDetectors.axisFDDAampl , axisDetectors.axisFDDCampl , axisSelGap});
933943 histos.add (" eventQA/hZN" , " hZN" , kTH3D , {axisDetectors.axisZNAampl , axisDetectors.axisZNCampl , axisSelGap});
944+ histos.add (" eventQA/hTimeFT0A" , " hTimeFT0A" , kTH2D , {axisDetectors.axisFitTime , axisSelGap});
945+ histos.add (" eventQA/hTimeFT0C" , " hTimeFT0C" , kTH2D , {axisDetectors.axisFitTime , axisSelGap});
946+ histos.add (" eventQA/hTimeFV0A" , " hTimeFV0A" , kTH2D , {axisDetectors.axisFitTime , axisSelGap});
947+ histos.add (" eventQA/hTimeFDDA" , " hTimeFDDA" , kTH2D , {axisDetectors.axisFitTime , axisSelGap});
948+ histos.add (" eventQA/hTimeFDDC" , " hTimeFDDC" , kTH2D , {axisDetectors.axisFitTime , axisSelGap});
949+ histos.add (" eventQA/hTimeFT0APreSel" , " hTimeFT0APreSel" , kTH1D , {axisDetectors.axisFitTime });
950+ histos.add (" eventQA/hTimeFT0CPreSel" , " hTimeFT0CPreSel" , kTH1D , {axisDetectors.axisFitTime });
951+ histos.add (" eventQA/hTimeFV0APreSel" , " hTimeFV0APreSel" , kTH1D , {axisDetectors.axisFitTime });
952+ histos.add (" eventQA/hTimeFDDAPreSel" , " hTimeFDDAPreSel" , kTH1D , {axisDetectors.axisFitTime });
953+ histos.add (" eventQA/hTimeFDDCPreSel" , " hTimeFDDCPreSel" , kTH1D , {axisDetectors.axisFitTime });
954+ histos.add (" eventQA/hFT0Time" , " hFT0Time" , kTH3D , {axisDetectors.axisFitTime , axisDetectors.axisFitTime , axisSelGap});
955+ histos.add (" eventQA/hFDDTime" , " hFDDTime" , kTH3D , {axisDetectors.axisFitTime , axisDetectors.axisFitTime , axisSelGap});
956+ histos.add (" eventQA/hZNTime" , " hZNTime" , kTH3D , {axisDetectors.axisZdcTime , axisDetectors.axisZdcTime , axisSelGap});
957+ histos.add (" eventQA/hFT0TimePreSel" , " hFT0TimePreSel" , kTH2D , {axisDetectors.axisFitTime , axisDetectors.axisFitTime });
958+ histos.add (" eventQA/hFDDTimePreSel" , " hFDDTimePreSel" , kTH2D , {axisDetectors.axisFitTime , axisDetectors.axisFitTime });
959+ histos.add (" eventQA/hZNTimePreSel" , " hZNTimePreSel" , kTH2D , {axisDetectors.axisZdcTime , axisDetectors.axisZdcTime });
934960
935961 if (doprocessGenerated) {
936962 histos.add (" eventQA/mc/hEventSelectionMC" , " hEventSelectionMC" , kTH3D , {{3 , -0.5 , 2.5 }, axisNTracksPVeta1, axisGeneratorIds});
@@ -955,7 +981,7 @@ struct Derivedupcanalysis {
955981 histos.add (" eventQA/mc/hNTracksPVeta1vsMCNParticlesEta10rec" , " hNTracksPVeta1vsMCNParticlesEta10rec" , kTH2D , {axisNTracksPVeta1, axisNTracksPVeta1});
956982 histos.add (" eventQA/mc/hNTracksGlobalvstotalMultMCParticles" , " hNTracksGlobalvstotalMultMCParticles" , kTH2D , {axisNTracksGlobal, axisNchInvMass});
957983 histos.add (" eventQA/mc/hNTracksPVeta1vstotalMultMCParticles" , " hNTracksPVeta1vstotalMultMCParticles" , kTH2D , {axisNTracksPVeta1, axisNchInvMass});
958- histos.add (" eventQA/hSelGapSideNoNeutrons" , " Selected gap side (no n); Entries" , kTH1D , {{ 5 , - 0.5 , 4.5 } });
984+ histos.add (" eventQA/hSelGapSideNoNeutrons" , " Selected gap side (no n); Entries" , kTH1D , {axisSelGap });
959985 }
960986
961987 if (doprocessV0sMC) {
@@ -1050,12 +1076,164 @@ struct Derivedupcanalysis {
10501076 }
10511077
10521078 template <typename TCollision>
1053- int getGapSide (TCollision const & collision)
1079+ int applyZDCTiming (int selGapSide, TCollision const & collision)
1080+ {
1081+ if (!upcCuts.requireZDCTiming ) {
1082+ return selGapSide;
1083+ }
1084+ if (selGapSide == o2::aod::sgselector::SingleGapA ||
1085+ selGapSide == o2::aod::sgselector::SingleGapC ||
1086+ selGapSide == o2::aod::sgselector::DoubleGap) {
1087+
1088+ const float timeZNA = collision.timeZNA ();
1089+ const float timeZNC = collision.timeZNC ();
1090+ const float cut = upcCuts.zdcTimeCut ;
1091+
1092+ auto isInvalidTime = [](float time) {
1093+ return !std::isfinite (time) || (std::abs (time) == 999 .f );
1094+ };
1095+
1096+ const bool gapA = isInvalidTime (timeZNA) || (std::abs (timeZNA) > cut);
1097+ const bool gapC = isInvalidTime (timeZNC) || (std::abs (timeZNC) > cut);
1098+ const bool neutronA = !isInvalidTime (timeZNA) && (std::abs (timeZNA) < cut);
1099+ const bool neutronC = !isInvalidTime (timeZNC) && (std::abs (timeZNC) < cut);
1100+
1101+ if (selGapSide == o2::aod::sgselector::SingleGapA) { // 0nXn
1102+ if (!(gapA && neutronC)) {
1103+ selGapSide = o2::aod::sgselector::NoGap;
1104+ }
1105+ } else if (selGapSide == o2::aod::sgselector::SingleGapC) { // Xn0n
1106+ if (!(neutronA && gapC)) {
1107+ selGapSide = o2::aod::sgselector::NoGap;
1108+ }
1109+ } else if (selGapSide == o2::aod::sgselector::DoubleGap) {
1110+ if (!(gapA && gapC)) {
1111+ selGapSide = o2::aod::sgselector::NoGap;
1112+ }
1113+ }
1114+ }
1115+
1116+ return selGapSide;
1117+ }
1118+
1119+ bool isInvalidTime (float time) const
1120+ {
1121+ return !std::isfinite (time) || (std::abs (time) >= 998 .f );
1122+ }
1123+
1124+ bool isTimingCutEnabled (float cut) const
1125+ {
1126+ return cut >= 0 .f ;
1127+ }
1128+
1129+ bool isTimingGap (float time, float cut) const
1130+ {
1131+ return isInvalidTime (time) || (std::abs (time) > cut);
1132+ }
1133+
1134+ bool isTimingActivity (float time, float cut) const
1135+ {
1136+ return !isInvalidTime (time) && (std::abs (time) < cut);
1137+ }
1138+
1139+ bool hasFT0Activity (uint8_t triggerMask, uint8_t bit) const
10541140 {
1055- int selGapSide = sgSelector.trueGap (collision, upcCuts.fv0a , upcCuts.ft0a , upcCuts.ft0c , upcCuts.zdc );
1141+ return (triggerMask & (static_cast <uint8_t >(1u ) << bit)) != 0 ;
1142+ }
1143+
1144+ template <typename TCollision>
1145+ int applyFITTiming (int selGapSide, TCollision const & collision)
1146+ {
1147+ if (selGapSide != o2::aod::sgselector::SingleGapA &&
1148+ selGapSide != o2::aod::sgselector::SingleGapC &&
1149+ selGapSide != o2::aod::sgselector::DoubleGap) {
1150+ return selGapSide;
1151+ }
1152+
1153+ const bool useFDDA = isTimingCutEnabled (upcCuts.fddaTimeCut );
1154+ const bool useFDDC = isTimingCutEnabled (upcCuts.fddcTimeCut );
1155+ const bool useFV0A = isTimingCutEnabled (upcCuts.fv0aTimeCut );
1156+ const bool useFT0A = isTimingCutEnabled (upcCuts.ft0aTimeCut );
1157+ const bool useFT0C = isTimingCutEnabled (upcCuts.ft0cTimeCut );
1158+
1159+ if (!(useFDDA || useFDDC || useFV0A || useFT0A || useFT0C)) {
1160+ return selGapSide;
1161+ }
1162+
1163+ const bool ft0ActiveA = hasFT0Activity (collision.triggerMaskFT0 (), kFT0TriggerBitIsActiveA );
1164+ const bool ft0ActiveC = hasFT0Activity (collision.triggerMaskFT0 (), kFT0TriggerBitIsActiveC );
1165+
1166+ const bool gapFDDA = !useFDDA || isTimingGap (collision.timeFDDA (), upcCuts.fddaTimeCut );
1167+ const bool actFDDA = !useFDDA || isTimingActivity (collision.timeFDDA (), upcCuts.fddaTimeCut );
1168+ const bool gapFDDC = !useFDDC || isTimingGap (collision.timeFDDC (), upcCuts.fddcTimeCut );
1169+ const bool actFDDC = !useFDDC || isTimingActivity (collision.timeFDDC (), upcCuts.fddcTimeCut );
1170+ const bool gapFV0A = !useFV0A || isTimingGap (collision.timeFV0A (), upcCuts.fv0aTimeCut );
1171+ const bool actFV0A = !useFV0A || isTimingActivity (collision.timeFV0A (), upcCuts.fv0aTimeCut );
1172+ const bool gapFT0A = !useFT0A || !ft0ActiveA || isTimingGap (collision.timeFT0A (), upcCuts.ft0aTimeCut );
1173+ const bool actFT0A = !useFT0A || (ft0ActiveA && isTimingActivity (collision.timeFT0A (), upcCuts.ft0aTimeCut ));
1174+ const bool gapFT0C = !useFT0C || !ft0ActiveC || isTimingGap (collision.timeFT0C (), upcCuts.ft0cTimeCut );
1175+ const bool actFT0C = !useFT0C || (ft0ActiveC && isTimingActivity (collision.timeFT0C (), upcCuts.ft0cTimeCut ));
1176+
1177+ if (selGapSide == o2::aod::sgselector::SingleGapA) {
1178+ if (!(gapFV0A && gapFDDA && gapFT0A && actFDDC && actFT0C)) {
1179+ selGapSide = o2::aod::sgselector::NoGap;
1180+ }
1181+ } else if (selGapSide == o2::aod::sgselector::SingleGapC) {
1182+ if (!(actFV0A && actFDDA && actFT0A && gapFDDC && gapFT0C)) {
1183+ selGapSide = o2::aod::sgselector::NoGap;
1184+ }
1185+ } else if (selGapSide == o2::aod::sgselector::DoubleGap) {
1186+ if (!(gapFV0A && gapFDDA && gapFT0A && gapFDDC && gapFT0C)) {
1187+ selGapSide = o2::aod::sgselector::NoGap;
1188+ }
1189+ }
1190+
10561191 return selGapSide;
10571192 }
10581193
1194+ template <typename TCollision>
1195+ int getGapSide (TCollision const & collision)
1196+ {
1197+ int selGapSide = o2::aod::sgselector::NoGap;
1198+ selGapSide = sgSelector.trueGap (collision, upcCuts.fv0a , upcCuts.ft0a , upcCuts.ft0c , upcCuts.zdc );
1199+ selGapSide = applyZDCTiming (selGapSide, collision);
1200+ return applyFITTiming (selGapSide, collision);
1201+ }
1202+ float sanitizeZdcTime (float time) const
1203+ {
1204+ if (!std::isfinite (time)) {
1205+ return -12 .f ;
1206+ }
1207+ if (std::abs (time) >= 998 .f ) {
1208+ return -11 .f ;
1209+ }
1210+ return time;
1211+ }
1212+
1213+ float sanitizeFITTime (float time) const
1214+ {
1215+ if (!std::isfinite (time)) {
1216+ return -42 .f ;
1217+ }
1218+ if (std::abs (time) >= 998 .f ) {
1219+ return -41 .f ;
1220+ }
1221+ return time;
1222+ }
1223+
1224+ template <typename TCollision>
1225+ void fillPreSelTimingHistograms (TCollision const & collision)
1226+ {
1227+ histos.fill (HIST (" eventQA/hFT0TimePreSel" ), sanitizeFITTime (collision.timeFT0A ()), sanitizeFITTime (collision.timeFT0C ()));
1228+ histos.fill (HIST (" eventQA/hFDDTimePreSel" ), sanitizeFITTime (collision.timeFDDA ()), sanitizeFITTime (collision.timeFDDC ()));
1229+ histos.fill (HIST (" eventQA/hZNTimePreSel" ), sanitizeZdcTime (collision.timeZNA ()), sanitizeZdcTime (collision.timeZNC ()));
1230+ histos.fill (HIST (" eventQA/hTimeFT0APreSel" ), sanitizeFITTime (collision.timeFT0A ()));
1231+ histos.fill (HIST (" eventQA/hTimeFT0CPreSel" ), sanitizeFITTime (collision.timeFT0C ()));
1232+ histos.fill (HIST (" eventQA/hTimeFV0APreSel" ), sanitizeFITTime (collision.timeFV0A ()));
1233+ histos.fill (HIST (" eventQA/hTimeFDDAPreSel" ), sanitizeFITTime (collision.timeFDDA ()));
1234+ histos.fill (HIST (" eventQA/hTimeFDDCPreSel" ), sanitizeFITTime (collision.timeFDDC ()));
1235+ }
1236+
10591237 template <typename TCollision>
10601238 void fillHistogramsQA (TCollision const & collision, int const & gap)
10611239 {
@@ -1099,6 +1277,18 @@ struct Derivedupcanalysis {
10991277 histos.fill (HIST (" eventQA/hZN" ), -2 , -2 , gap);
11001278 else if (zna == -999 || znc == -999 )
11011279 LOG (warning) << " Only one ZDC signal is -999" ;
1280+ else {
1281+ histos.fill (HIST (" eventQA/hZN" ), zna, znc, gap);
1282+ }
1283+
1284+ histos.fill (HIST (" eventQA/hFT0Time" ), sanitizeFITTime (collision.timeFT0A ()), sanitizeFITTime (collision.timeFT0C ()), gap);
1285+ histos.fill (HIST (" eventQA/hFDDTime" ), sanitizeFITTime (collision.timeFDDA ()), sanitizeFITTime (collision.timeFDDC ()), gap);
1286+ histos.fill (HIST (" eventQA/hZNTime" ), sanitizeZdcTime (collision.timeZNA ()), sanitizeZdcTime (collision.timeZNC ()), gap);
1287+ histos.fill (HIST (" eventQA/hTimeFT0A" ), sanitizeFITTime (collision.timeFT0A ()), gap);
1288+ histos.fill (HIST (" eventQA/hTimeFT0C" ), sanitizeFITTime (collision.timeFT0C ()), gap);
1289+ histos.fill (HIST (" eventQA/hTimeFV0A" ), sanitizeFITTime (collision.timeFV0A ()), gap);
1290+ histos.fill (HIST (" eventQA/hTimeFDDA" ), sanitizeFITTime (collision.timeFDDA ()), gap);
1291+ histos.fill (HIST (" eventQA/hTimeFDDC" ), sanitizeFITTime (collision.timeFDDC ()), gap);
11021292 }
11031293
11041294 template <typename TCollision>
@@ -1868,13 +2058,13 @@ struct Derivedupcanalysis {
18682058 }
18692059 }
18702060
1871- if ( evSels.studyUPConly && (selGapSide != static_cast <int >(upcCuts.genGapSide )))
1872- continue ;
1873-
1874- ++nCollisions ;
1875- atLeastOne = true ;
2061+ const bool passStd = ! evSels.studyUPConly || (selGapSide == static_cast <int >(upcCuts.genGapSide ));
2062+ if (passStd) {
2063+ ++nCollisions;
2064+ atLeastOne = true ;
2065+ }
18762066
1877- if (biggestNContribs < collision.multPVTotalContributors ()) {
2067+ if (passStd && biggestNContribs < collision.multPVTotalContributors ()) {
18782068 biggestNContribs = collision.multPVTotalContributors ();
18792069 if (static_cast <int >(upcCuts.genGapSide ) == 0 ) {
18802070 ft0ampl = collision.totalFT0AmplitudeC ();
@@ -1946,6 +2136,9 @@ struct Derivedupcanalysis {
19462136 continue ;
19472137 } // event is accepted
19482138
2139+ if (collision.isUPC ()) {
2140+ fillPreSelTimingHistograms (collision);
2141+ }
19492142 histos.fill (HIST (" eventQA/hRawGapSide" ), collision.gapSide ());
19502143
19512144 int selGapSide = collision.isUPC () ? getGapSide (collision) : -1 ;
@@ -2002,6 +2195,9 @@ struct Derivedupcanalysis {
20022195 continue ;
20032196 } // event is accepted
20042197
2198+ if (collision.isUPC ()) {
2199+ fillPreSelTimingHistograms (collision);
2200+ }
20052201 histos.fill (HIST (" eventQA/hRawGapSide" ), collision.gapSide ());
20062202
20072203 int selGapSide = collision.isUPC () ? getGapSide (collision) : -1 ;
@@ -2087,6 +2283,9 @@ struct Derivedupcanalysis {
20872283 continue ;
20882284 } // event is accepted
20892285
2286+ if (collision.isUPC ()) {
2287+ fillPreSelTimingHistograms (collision);
2288+ }
20902289 histos.fill (HIST (" eventQA/hRawGapSide" ), collision.gapSide ());
20912290
20922291 int selGapSide = collision.isUPC () ? getGapSide (collision) : -1 ;
@@ -2139,6 +2338,9 @@ struct Derivedupcanalysis {
21392338 continue ;
21402339 } // event is accepted
21412340
2341+ if (collision.isUPC ()) {
2342+ fillPreSelTimingHistograms (collision);
2343+ }
21422344 histos.fill (HIST (" eventQA/hRawGapSide" ), collision.gapSide ());
21432345
21442346 int selGapSide = collision.isUPC () ? getGapSide (collision) : -1 ;
0 commit comments