#15899: support multi-staff parts with figured bass elements
This commit is contained in:
parent
f1147b836e
commit
8218c97e6a
6 changed files with 399 additions and 42 deletions
|
@ -757,6 +757,7 @@ void MusicXml::import(Score* s)
|
||||||
harmony = 0;
|
harmony = 0;
|
||||||
tremStart = 0;
|
tremStart = 0;
|
||||||
hairpin = 0;
|
hairpin = 0;
|
||||||
|
figBass = 0;
|
||||||
|
|
||||||
// TODO only if multi-measure rests used ???
|
// TODO only if multi-measure rests used ???
|
||||||
// score->style()->set(ST_createMultiMeasureRests, true);
|
// score->style()->set(ST_createMultiMeasureRests, true);
|
||||||
|
@ -2105,38 +2106,6 @@ void MusicXml::xmlPart(QDomElement e, QString id)
|
||||||
delete drumset;
|
delete drumset;
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------
|
|
||||||
// fixupFiguredBass
|
|
||||||
//
|
|
||||||
// set correct ticks and (TODO ?) onNote value for the
|
|
||||||
// FiguredBass elements in this measure and staff
|
|
||||||
// note: FiguredBass element already has a valid track value
|
|
||||||
//---------------------------------------------------------
|
|
||||||
|
|
||||||
static void fixupFiguredBass(Part* part, Measure* measure)
|
|
||||||
{
|
|
||||||
for (Segment* seg = measure->first(Segment::SegChordRest); seg; seg = seg->next(Segment::SegChordRest)) {
|
|
||||||
foreach(Element* e, seg->annotations()) {
|
|
||||||
if (e->type() == Element::FIGURED_BASS) {
|
|
||||||
FiguredBass* fb = static_cast<FiguredBass*>(e);
|
|
||||||
if (fb->ticks() <= 0) {
|
|
||||||
// Found FiguredBass w/o valid ticks value
|
|
||||||
// Find chord to attach to in same staff and copy ticks
|
|
||||||
for (int tr = fb->track(); tr < fb->track() + VOICES; ++tr) {
|
|
||||||
Element* el = seg->element(tr);
|
|
||||||
if (el && el->type() == Element::CHORD) {
|
|
||||||
// found chord
|
|
||||||
Chord* ch = static_cast<Chord*>(el);
|
|
||||||
fb->setTicks(ch->actualTicks());
|
|
||||||
break; // use the first chord found
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// xmlMeasure
|
// xmlMeasure
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
@ -2393,21 +2362,19 @@ Measure* MusicXml::xmlMeasure(Part* part, QDomElement e, int number, int measure
|
||||||
else if (e.tagName() == "harmony")
|
else if (e.tagName() == "harmony")
|
||||||
xmlHarmony(e, tick, measure, staff);
|
xmlHarmony(e, tick, measure, staff);
|
||||||
else if (e.tagName() == "figured-bass") {
|
else if (e.tagName() == "figured-bass") {
|
||||||
FiguredBass* fb = new FiguredBass(score);
|
if (figBass) {
|
||||||
fb->setTrack(staff * VOICES);
|
qDebug("more than one figured bass element on note not supported");
|
||||||
fb->readMusicXML(e, divisions);
|
}
|
||||||
Segment* s = measure->getSegment(Segment::SegChordRest, tick);
|
else {
|
||||||
// TODO: use addelement() instead of Segment::add() ?
|
// read figured bass element to attach to next note
|
||||||
// or FiguredBass::addFiguredBassToSegment() ?
|
figBass = new FiguredBass(score);
|
||||||
// TODO: set correct onNote value
|
figBass->readMusicXML(e, divisions);
|
||||||
s->add(fb);
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
domError(e);
|
domError(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
fixupFiguredBass(part, measure);
|
|
||||||
|
|
||||||
#ifdef DEBUG_TICK
|
#ifdef DEBUG_TICK
|
||||||
qDebug("end_of_measure measure->tick()=%d maxtick=%d lastMeasureLen=%d measureLen=%d tsig=%d(%s)",
|
qDebug("end_of_measure measure->tick()=%d maxtick=%d lastMeasureLen=%d measureLen=%d tsig=%d(%s)",
|
||||||
measure->tick(), maxtick, lastMeasureLen, measureLen,
|
measure->tick(), maxtick, lastMeasureLen, measureLen,
|
||||||
|
@ -5070,6 +5037,18 @@ void MusicXml::xmlNote(Measure* measure, int staff, const QString& partId, QDomE
|
||||||
// add lyrics found by xmlLyric
|
// add lyrics found by xmlLyric
|
||||||
addLyrics(cr, numberedLyrics, defaultyLyrics, unNumberedLyrics);
|
addLyrics(cr, numberedLyrics, defaultyLyrics, unNumberedLyrics);
|
||||||
|
|
||||||
|
// add figured bass element
|
||||||
|
if (figBass) {
|
||||||
|
qDebug("add figured bass %p at tick %d ticks %d trk %d", figBass, tick, ticks, trk);
|
||||||
|
figBass->setTrack(trk);
|
||||||
|
figBass->setTicks(ticks);
|
||||||
|
// TODO: set correct onNote value
|
||||||
|
Segment* s = measure->getSegment(Segment::SegChordRest, tick);
|
||||||
|
// TODO: use addelement() instead of Segment::add() ?
|
||||||
|
s->add(figBass);
|
||||||
|
figBass = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!chord)
|
if (!chord)
|
||||||
prevtick = tick; // remember tick where last chordrest was inserted
|
prevtick = tick; // remember tick where last chordrest was inserted
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@ class Spanner;
|
||||||
class Lyrics;
|
class Lyrics;
|
||||||
class ChordRest;
|
class ChordRest;
|
||||||
class Beam;
|
class Beam;
|
||||||
|
class FiguredBass;
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// MusicXmlWedge
|
// MusicXmlWedge
|
||||||
|
@ -236,6 +237,7 @@ class MusicXml {
|
||||||
Harmony* harmony; ///< Current harmony
|
Harmony* harmony; ///< Current harmony
|
||||||
Hairpin* hairpin; ///< Current hairpin (obsoletes wedgelist)
|
Hairpin* hairpin; ///< Current hairpin (obsoletes wedgelist)
|
||||||
Chord* tremStart; ///< Starting chord for current tremolo
|
Chord* tremStart; ///< Starting chord for current tremolo
|
||||||
|
FiguredBass* figBass; ///< Current figured bass element (to attach to next note)
|
||||||
BeamMode beamMode; ///< Current beam mode
|
BeamMode beamMode; ///< Current beam mode
|
||||||
Beam* beam; ///< Current beam mode
|
Beam* beam; ///< Current beam mode
|
||||||
|
|
||||||
|
|
187
mtest/musicxml/io/testFiguredBass2.xml
Normal file
187
mtest/musicxml/io/testFiguredBass2.xml
Normal file
|
@ -0,0 +1,187 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 2.0 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
|
||||||
|
<score-partwise>
|
||||||
|
<work>
|
||||||
|
<work-number>MuseScore testfile</work-number>
|
||||||
|
<work-title>Figured bass 2</work-title>
|
||||||
|
</work>
|
||||||
|
<identification>
|
||||||
|
<creator type="composer">Leon Vinken</creator>
|
||||||
|
<encoding>
|
||||||
|
<software>MuseScore 0.7.0</software>
|
||||||
|
<encoding-date>2007-09-10</encoding-date>
|
||||||
|
</encoding>
|
||||||
|
</identification>
|
||||||
|
<part-list>
|
||||||
|
<score-part id="P1">
|
||||||
|
<part-name>Flute</part-name>
|
||||||
|
<part-abbreviation>Fl.</part-abbreviation>
|
||||||
|
<score-instrument id="P1-I3">
|
||||||
|
<instrument-name>Flute</instrument-name>
|
||||||
|
</score-instrument>
|
||||||
|
<midi-instrument id="P1-I3">
|
||||||
|
<midi-channel>1</midi-channel>
|
||||||
|
<midi-program>74</midi-program>
|
||||||
|
<volume>78.7402</volume>
|
||||||
|
<pan>0</pan>
|
||||||
|
</midi-instrument>
|
||||||
|
</score-part>
|
||||||
|
<score-part id="P2">
|
||||||
|
<part-name>Harpsichord</part-name>
|
||||||
|
<part-abbreviation>Hch.</part-abbreviation>
|
||||||
|
<score-instrument id="P2-I3">
|
||||||
|
<instrument-name>Harpsichord</instrument-name>
|
||||||
|
</score-instrument>
|
||||||
|
<midi-instrument id="P2-I3">
|
||||||
|
<midi-channel>2</midi-channel>
|
||||||
|
<midi-program>7</midi-program>
|
||||||
|
<volume>78.7402</volume>
|
||||||
|
<pan>0</pan>
|
||||||
|
</midi-instrument>
|
||||||
|
</score-part>
|
||||||
|
</part-list>
|
||||||
|
<part id="P1">
|
||||||
|
<measure number="1">
|
||||||
|
<attributes>
|
||||||
|
<divisions>1</divisions>
|
||||||
|
<key>
|
||||||
|
<fifths>0</fifths>
|
||||||
|
<mode>major</mode>
|
||||||
|
</key>
|
||||||
|
<time>
|
||||||
|
<beats>4</beats>
|
||||||
|
<beat-type>4</beat-type>
|
||||||
|
</time>
|
||||||
|
<clef>
|
||||||
|
<sign>G</sign>
|
||||||
|
<line>2</line>
|
||||||
|
</clef>
|
||||||
|
</attributes>
|
||||||
|
<figured-bass>
|
||||||
|
<figure>
|
||||||
|
<figure-number>1</figure-number>
|
||||||
|
</figure>
|
||||||
|
</figured-bass>
|
||||||
|
<note>
|
||||||
|
<pitch>
|
||||||
|
<step>G</step>
|
||||||
|
<octave>4</octave>
|
||||||
|
</pitch>
|
||||||
|
<duration>4</duration>
|
||||||
|
<voice>1</voice>
|
||||||
|
<type>whole</type>
|
||||||
|
</note>
|
||||||
|
</measure>
|
||||||
|
<measure number="2">
|
||||||
|
<note>
|
||||||
|
<rest/>
|
||||||
|
<duration>4</duration>
|
||||||
|
<voice>1</voice>
|
||||||
|
</note>
|
||||||
|
</measure>
|
||||||
|
<measure number="3">
|
||||||
|
<note>
|
||||||
|
<rest/>
|
||||||
|
<duration>4</duration>
|
||||||
|
<voice>1</voice>
|
||||||
|
</note>
|
||||||
|
<barline location="right">
|
||||||
|
<bar-style>light-heavy</bar-style>
|
||||||
|
</barline>
|
||||||
|
</measure>
|
||||||
|
</part>
|
||||||
|
<part id="P2">
|
||||||
|
<measure number="1">
|
||||||
|
<attributes>
|
||||||
|
<divisions>1</divisions>
|
||||||
|
<key>
|
||||||
|
<fifths>0</fifths>
|
||||||
|
<mode>major</mode>
|
||||||
|
</key>
|
||||||
|
<time>
|
||||||
|
<beats>4</beats>
|
||||||
|
<beat-type>4</beat-type>
|
||||||
|
</time>
|
||||||
|
<staves>2</staves>
|
||||||
|
<clef number="1">
|
||||||
|
<sign>G</sign>
|
||||||
|
<line>2</line>
|
||||||
|
</clef>
|
||||||
|
<clef number="2">
|
||||||
|
<sign>F</sign>
|
||||||
|
<line>4</line>
|
||||||
|
</clef>
|
||||||
|
</attributes>
|
||||||
|
<note>
|
||||||
|
<rest/>
|
||||||
|
<duration>4</duration>
|
||||||
|
<voice>1</voice>
|
||||||
|
<staff>1</staff>
|
||||||
|
</note>
|
||||||
|
<backup>
|
||||||
|
<duration>4</duration>
|
||||||
|
</backup>
|
||||||
|
<note>
|
||||||
|
<rest/>
|
||||||
|
<duration>4</duration>
|
||||||
|
<voice>5</voice>
|
||||||
|
<staff>2</staff>
|
||||||
|
</note>
|
||||||
|
</measure>
|
||||||
|
<measure number="2">
|
||||||
|
<figured-bass>
|
||||||
|
<figure>
|
||||||
|
<figure-number>2</figure-number>
|
||||||
|
</figure>
|
||||||
|
</figured-bass>
|
||||||
|
<note>
|
||||||
|
<pitch>
|
||||||
|
<step>A</step>
|
||||||
|
<octave>4</octave>
|
||||||
|
</pitch>
|
||||||
|
<duration>4</duration>
|
||||||
|
<voice>1</voice>
|
||||||
|
<type>whole</type>
|
||||||
|
<staff>1</staff>
|
||||||
|
</note>
|
||||||
|
<backup>
|
||||||
|
<duration>4</duration>
|
||||||
|
</backup>
|
||||||
|
<note>
|
||||||
|
<rest/>
|
||||||
|
<duration>4</duration>
|
||||||
|
<voice>5</voice>
|
||||||
|
<staff>2</staff>
|
||||||
|
</note>
|
||||||
|
</measure>
|
||||||
|
<measure number="3">
|
||||||
|
<note>
|
||||||
|
<rest/>
|
||||||
|
<duration>4</duration>
|
||||||
|
<voice>1</voice>
|
||||||
|
<staff>1</staff>
|
||||||
|
</note>
|
||||||
|
<backup>
|
||||||
|
<duration>4</duration>
|
||||||
|
</backup>
|
||||||
|
<figured-bass>
|
||||||
|
<figure>
|
||||||
|
<figure-number>3</figure-number>
|
||||||
|
</figure>
|
||||||
|
</figured-bass>
|
||||||
|
<note>
|
||||||
|
<pitch>
|
||||||
|
<step>B</step>
|
||||||
|
<octave>2</octave>
|
||||||
|
</pitch>
|
||||||
|
<duration>4</duration>
|
||||||
|
<voice>5</voice>
|
||||||
|
<type>whole</type>
|
||||||
|
<staff>2</staff>
|
||||||
|
</note>
|
||||||
|
<barline location="right">
|
||||||
|
<bar-style>light-heavy</bar-style>
|
||||||
|
</barline>
|
||||||
|
</measure>
|
||||||
|
</part>
|
||||||
|
</score-partwise>
|
|
@ -66,6 +66,7 @@ private slots:
|
||||||
void emptyMeasure() { mxmlIoTestRef("testEmptyMeasure"); }
|
void emptyMeasure() { mxmlIoTestRef("testEmptyMeasure"); }
|
||||||
void emptyVoice1() { mxmlIoTestRef("testEmptyVoice1"); }
|
void emptyVoice1() { mxmlIoTestRef("testEmptyVoice1"); }
|
||||||
void figuredBass1() { mxmlIoTest("testFiguredBass1"); }
|
void figuredBass1() { mxmlIoTest("testFiguredBass1"); }
|
||||||
|
void figuredBass2() { mxmlIoTest("testFiguredBass2"); }
|
||||||
void grace1() { mxmlIoTest("testGrace1"); }
|
void grace1() { mxmlIoTest("testGrace1"); }
|
||||||
void grace2() { mxmlIoTest("testGrace2"); }
|
void grace2() { mxmlIoTest("testGrace2"); }
|
||||||
void harmony1() { mxmlIoTest("testHarmony1"); }
|
void harmony1() { mxmlIoTest("testHarmony1"); }
|
||||||
|
|
187
test/musicxml/testFiguredBass2.xml
Normal file
187
test/musicxml/testFiguredBass2.xml
Normal file
|
@ -0,0 +1,187 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 2.0 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
|
||||||
|
<score-partwise>
|
||||||
|
<work>
|
||||||
|
<work-number>MuseScore testfile</work-number>
|
||||||
|
<work-title>Figured bass 2</work-title>
|
||||||
|
</work>
|
||||||
|
<identification>
|
||||||
|
<creator type="composer">Leon Vinken</creator>
|
||||||
|
<encoding>
|
||||||
|
<software>MuseScore 0.7.0</software>
|
||||||
|
<encoding-date>2007-09-10</encoding-date>
|
||||||
|
</encoding>
|
||||||
|
</identification>
|
||||||
|
<part-list>
|
||||||
|
<score-part id="P1">
|
||||||
|
<part-name>Flute</part-name>
|
||||||
|
<part-abbreviation>Fl.</part-abbreviation>
|
||||||
|
<score-instrument id="P1-I3">
|
||||||
|
<instrument-name>Flute</instrument-name>
|
||||||
|
</score-instrument>
|
||||||
|
<midi-instrument id="P1-I3">
|
||||||
|
<midi-channel>1</midi-channel>
|
||||||
|
<midi-program>74</midi-program>
|
||||||
|
<volume>78.7402</volume>
|
||||||
|
<pan>0</pan>
|
||||||
|
</midi-instrument>
|
||||||
|
</score-part>
|
||||||
|
<score-part id="P2">
|
||||||
|
<part-name>Harpsichord</part-name>
|
||||||
|
<part-abbreviation>Hch.</part-abbreviation>
|
||||||
|
<score-instrument id="P2-I3">
|
||||||
|
<instrument-name>Harpsichord</instrument-name>
|
||||||
|
</score-instrument>
|
||||||
|
<midi-instrument id="P2-I3">
|
||||||
|
<midi-channel>2</midi-channel>
|
||||||
|
<midi-program>7</midi-program>
|
||||||
|
<volume>78.7402</volume>
|
||||||
|
<pan>0</pan>
|
||||||
|
</midi-instrument>
|
||||||
|
</score-part>
|
||||||
|
</part-list>
|
||||||
|
<part id="P1">
|
||||||
|
<measure number="1">
|
||||||
|
<attributes>
|
||||||
|
<divisions>1</divisions>
|
||||||
|
<key>
|
||||||
|
<fifths>0</fifths>
|
||||||
|
<mode>major</mode>
|
||||||
|
</key>
|
||||||
|
<time>
|
||||||
|
<beats>4</beats>
|
||||||
|
<beat-type>4</beat-type>
|
||||||
|
</time>
|
||||||
|
<clef>
|
||||||
|
<sign>G</sign>
|
||||||
|
<line>2</line>
|
||||||
|
</clef>
|
||||||
|
</attributes>
|
||||||
|
<figured-bass>
|
||||||
|
<figure>
|
||||||
|
<figure-number>1</figure-number>
|
||||||
|
</figure>
|
||||||
|
</figured-bass>
|
||||||
|
<note>
|
||||||
|
<pitch>
|
||||||
|
<step>G</step>
|
||||||
|
<octave>4</octave>
|
||||||
|
</pitch>
|
||||||
|
<duration>4</duration>
|
||||||
|
<voice>1</voice>
|
||||||
|
<type>whole</type>
|
||||||
|
</note>
|
||||||
|
</measure>
|
||||||
|
<measure number="2">
|
||||||
|
<note>
|
||||||
|
<rest/>
|
||||||
|
<duration>4</duration>
|
||||||
|
<voice>1</voice>
|
||||||
|
</note>
|
||||||
|
</measure>
|
||||||
|
<measure number="3">
|
||||||
|
<note>
|
||||||
|
<rest/>
|
||||||
|
<duration>4</duration>
|
||||||
|
<voice>1</voice>
|
||||||
|
</note>
|
||||||
|
<barline location="right">
|
||||||
|
<bar-style>light-heavy</bar-style>
|
||||||
|
</barline>
|
||||||
|
</measure>
|
||||||
|
</part>
|
||||||
|
<part id="P2">
|
||||||
|
<measure number="1">
|
||||||
|
<attributes>
|
||||||
|
<divisions>1</divisions>
|
||||||
|
<key>
|
||||||
|
<fifths>0</fifths>
|
||||||
|
<mode>major</mode>
|
||||||
|
</key>
|
||||||
|
<time>
|
||||||
|
<beats>4</beats>
|
||||||
|
<beat-type>4</beat-type>
|
||||||
|
</time>
|
||||||
|
<staves>2</staves>
|
||||||
|
<clef number="1">
|
||||||
|
<sign>G</sign>
|
||||||
|
<line>2</line>
|
||||||
|
</clef>
|
||||||
|
<clef number="2">
|
||||||
|
<sign>F</sign>
|
||||||
|
<line>4</line>
|
||||||
|
</clef>
|
||||||
|
</attributes>
|
||||||
|
<note>
|
||||||
|
<rest/>
|
||||||
|
<duration>4</duration>
|
||||||
|
<voice>1</voice>
|
||||||
|
<staff>1</staff>
|
||||||
|
</note>
|
||||||
|
<backup>
|
||||||
|
<duration>4</duration>
|
||||||
|
</backup>
|
||||||
|
<note>
|
||||||
|
<rest/>
|
||||||
|
<duration>4</duration>
|
||||||
|
<voice>5</voice>
|
||||||
|
<staff>2</staff>
|
||||||
|
</note>
|
||||||
|
</measure>
|
||||||
|
<measure number="2">
|
||||||
|
<figured-bass>
|
||||||
|
<figure>
|
||||||
|
<figure-number>2</figure-number>
|
||||||
|
</figure>
|
||||||
|
</figured-bass>
|
||||||
|
<note>
|
||||||
|
<pitch>
|
||||||
|
<step>A</step>
|
||||||
|
<octave>4</octave>
|
||||||
|
</pitch>
|
||||||
|
<duration>4</duration>
|
||||||
|
<voice>1</voice>
|
||||||
|
<type>whole</type>
|
||||||
|
<staff>1</staff>
|
||||||
|
</note>
|
||||||
|
<backup>
|
||||||
|
<duration>4</duration>
|
||||||
|
</backup>
|
||||||
|
<note>
|
||||||
|
<rest/>
|
||||||
|
<duration>4</duration>
|
||||||
|
<voice>5</voice>
|
||||||
|
<staff>2</staff>
|
||||||
|
</note>
|
||||||
|
</measure>
|
||||||
|
<measure number="3">
|
||||||
|
<note>
|
||||||
|
<rest/>
|
||||||
|
<duration>4</duration>
|
||||||
|
<voice>1</voice>
|
||||||
|
<staff>1</staff>
|
||||||
|
</note>
|
||||||
|
<backup>
|
||||||
|
<duration>4</duration>
|
||||||
|
</backup>
|
||||||
|
<figured-bass>
|
||||||
|
<figure>
|
||||||
|
<figure-number>3</figure-number>
|
||||||
|
</figure>
|
||||||
|
</figured-bass>
|
||||||
|
<note>
|
||||||
|
<pitch>
|
||||||
|
<step>B</step>
|
||||||
|
<octave>2</octave>
|
||||||
|
</pitch>
|
||||||
|
<duration>4</duration>
|
||||||
|
<voice>5</voice>
|
||||||
|
<type>whole</type>
|
||||||
|
<staff>2</staff>
|
||||||
|
</note>
|
||||||
|
<barline location="right">
|
||||||
|
<bar-style>light-heavy</bar-style>
|
||||||
|
</barline>
|
||||||
|
</measure>
|
||||||
|
</part>
|
||||||
|
</score-partwise>
|
|
@ -14,6 +14,7 @@ testDrumset2.xml
|
||||||
testDynamics1.xml
|
testDynamics1.xml
|
||||||
testDynamics2.xml
|
testDynamics2.xml
|
||||||
testFiguredBass1.xml
|
testFiguredBass1.xml
|
||||||
|
testFiguredBass2.xml
|
||||||
testGrace1.xml
|
testGrace1.xml
|
||||||
testGrace2.xml
|
testGrace2.xml
|
||||||
testHarmony1.xml
|
testHarmony1.xml
|
||||||
|
|
Loading…
Reference in a new issue