Library: rectify confusingly named function on the Grid API
The APIs for time quantisation were drafted in an early stage of the project and then never followed-up. Especially Grid::gridAlign has no real-world usage yet, and is only massaged in some tests. When looking at QuantiserBasics_test, I was puzzled and led astray, since this function suggests to materialise a continuous time into a quantised time -- which it doesn't (there is another dedicated function Quantiser::materialise() to that end); so, without engaging into the discussion if this function is of any use, I'll hereby choose a name better reflecting what it does.
This commit is contained in:
parent
50c602ec3f
commit
13adc56f34
7 changed files with 118 additions and 90 deletions
|
|
@ -111,7 +111,7 @@ int64_t
|
|||
lumiera_quantise_frames_fps (gavl_time_t time, gavl_time_t origin, uint framerate);
|
||||
|
||||
/**
|
||||
* Similar to #lumiera_quantise_frames, but returns a grid aligned \em time value
|
||||
* Similar to #lumiera_quantise_frames, but returns a grid aligned _relative time._
|
||||
* @return time of start of the grid interval containing the given time,
|
||||
* but measured relative to the origin
|
||||
* @warning because the resulting value needs to be limited to fit into a 64bit long,
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ namespace time {
|
|||
|
||||
|
||||
virtual FrameCnt gridPoint (TimeValue const& raw) const =0;
|
||||
virtual TimeValue gridAlign (TimeValue const& raw) const =0;
|
||||
virtual TimeValue gridLocal (TimeValue const& raw) const =0;
|
||||
virtual TimeValue timeOf (FrameCnt gridPoint) const =0;
|
||||
virtual TimeValue timeOf (FSecs gridTime, int=0) const =0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -114,25 +114,6 @@ namespace time {
|
|||
|
||||
|
||||
|
||||
/** alignment to a simple fixed size grid.
|
||||
* The actual calculation first determines the number
|
||||
* of the grid interval containing the given rawTime,
|
||||
* then followed by multiplying this interval number
|
||||
* with the grid spacing.
|
||||
* @return time of the start point of the grid interval
|
||||
* containing the rawTime, relative to the origin
|
||||
* of the time scale used by this quantiser.
|
||||
* @warning returned time values are limited by the
|
||||
* valid range of lumiera::Time
|
||||
* @see #lumiera_quantise_time
|
||||
*/
|
||||
TimeValue
|
||||
FixedFrameQuantiser::gridAlign (TimeValue const& rawTime) const
|
||||
{
|
||||
return TimeValue (lumiera_quantise_time (_raw(rawTime), _raw(origin_), _raw(raster_)));
|
||||
}
|
||||
|
||||
|
||||
/** grid quantisation (alignment).
|
||||
* Determine the next lower grid interval start point,
|
||||
* using a simple constant spaced time grid defined by
|
||||
|
|
@ -148,6 +129,25 @@ namespace time {
|
|||
}
|
||||
|
||||
|
||||
/** transform into the local time scale grid aligned.
|
||||
* The actual calculation first determines the number
|
||||
* of the grid interval containing the given rawTime,
|
||||
* then followed by multiplying this interval number
|
||||
* with the grid spacing.
|
||||
* @return time of the start point of the grid interval
|
||||
* containing the rawTime, _relative to the origin_
|
||||
* of the time scale used by this quantiser.
|
||||
* @warning returned time values are limited by the
|
||||
* valid range of lumiera::Time
|
||||
* @see #lumiera_quantise_time
|
||||
*/
|
||||
TimeValue
|
||||
FixedFrameQuantiser::gridLocal (TimeValue const& rawTime) const
|
||||
{
|
||||
return TimeValue (lumiera_quantise_time (_raw(rawTime), _raw(origin_), _raw(raster_)));
|
||||
}
|
||||
|
||||
|
||||
/** calculate time value of a grid interval (frame) start point
|
||||
* @return time point measured in Lumiera internal time
|
||||
* @warning returned time values are limited by the
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ namespace time {
|
|||
|
||||
//------Grid-API----------------------------------------------
|
||||
virtual FrameCnt gridPoint (TimeValue const& raw) const =0;
|
||||
virtual TimeValue gridAlign (TimeValue const& raw) const =0;
|
||||
virtual TimeValue gridLocal (TimeValue const& raw) const =0;
|
||||
virtual TimeValue timeOf (FrameCnt gridPoint) const =0;
|
||||
virtual TimeValue timeOf (FSecs, int =0) const =0;
|
||||
};
|
||||
|
|
@ -152,7 +152,7 @@ namespace time {
|
|||
FixedFrameQuantiser (Duration const& frame_duration, TimeValue referencePoint =TimeValue(0));
|
||||
|
||||
FrameCnt gridPoint (TimeValue const&) const;
|
||||
TimeValue gridAlign (TimeValue const&) const;
|
||||
TimeValue gridLocal (TimeValue const&) const;
|
||||
TimeValue timeOf (FrameCnt gridPoint) const;
|
||||
TimeValue timeOf (FSecs, int =0) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ namespace test{
|
|||
CHECK (Time( frames *F25) <= rawTime);
|
||||
CHECK (Time((frames+1)*F25) > rawTime);
|
||||
|
||||
Time quantTime (fixQ.gridAlign (rawTime));
|
||||
Time quantTime (fixQ.gridLocal (rawTime));
|
||||
|
||||
CHECK (Time(frames*F25) == quantTime);
|
||||
}
|
||||
|
|
@ -118,7 +118,7 @@ namespace test{
|
|||
int
|
||||
quant (int testPoint)
|
||||
{
|
||||
TimeVar quantised = this->gridAlign(TimeValue(testPoint));
|
||||
TimeVar quantised = this->gridLocal(TimeValue(testPoint));
|
||||
return int(quantised);
|
||||
}
|
||||
};
|
||||
|
|
@ -162,48 +162,48 @@ namespace test{
|
|||
{
|
||||
// origin at lower end of the time range
|
||||
FixedFrameQuantiser case1 (1, Time::MIN);
|
||||
CHECK (secs(0) == case1.gridAlign(Time::MIN ));
|
||||
CHECK (secs(0) == case1.gridAlign(Time::MIN +TimeValue(1) ));
|
||||
CHECK (secs(1) == case1.gridAlign(Time::MIN +secs(1) ));
|
||||
CHECK (Time::MAX -secs(1) > case1.gridAlign( secs(-1) ));
|
||||
CHECK (Time::MAX -secs(1) <= case1.gridAlign( secs (0) ));
|
||||
CHECK (Time::MAX > case1.gridAlign( secs (0) ));
|
||||
CHECK (Time::MAX == case1.gridAlign( secs(+1) ));
|
||||
CHECK (Time::MAX == case1.gridAlign( secs(+2) ));
|
||||
CHECK (secs(0) == case1.gridLocal(Time::MIN ));
|
||||
CHECK (secs(0) == case1.gridLocal(Time::MIN +TimeValue(1) ));
|
||||
CHECK (secs(1) == case1.gridLocal(Time::MIN +secs(1) ));
|
||||
CHECK (Time::MAX -secs(1) > case1.gridLocal( secs(-1) ));
|
||||
CHECK (Time::MAX -secs(1) <= case1.gridLocal( secs (0) ));
|
||||
CHECK (Time::MAX > case1.gridLocal( secs (0) ));
|
||||
CHECK (Time::MAX == case1.gridLocal( secs(+1) ));
|
||||
CHECK (Time::MAX == case1.gridLocal( secs(+2) ));
|
||||
|
||||
// origin at upper end of the time range
|
||||
FixedFrameQuantiser case2 (1, Time::MAX);
|
||||
CHECK (secs( 0) == case2.gridAlign(Time::MAX ));
|
||||
CHECK (secs(-1) == case2.gridAlign(Time::MAX -TimeValue(1) )); // note: next lower frame
|
||||
CHECK (secs(-1) == case2.gridAlign(Time::MAX -secs(1) )); // i.e. the same as a whole frame down
|
||||
CHECK (Time::MIN +secs(1) < case2.gridAlign( secs(+2) ));
|
||||
CHECK (Time::MIN +secs(1) >= case2.gridAlign( secs(+1) ));
|
||||
CHECK (Time::MIN < case2.gridAlign( secs(+1) ));
|
||||
CHECK (Time::MIN == case2.gridAlign( secs( 0) )); // note: because of downward truncating,
|
||||
CHECK (Time::MIN == case2.gridAlign( secs(-1) )); // resulting values will already exceed
|
||||
CHECK (Time::MIN == case2.gridAlign( secs(-2) )); // allowed range and thus will be clipped
|
||||
CHECK (secs( 0) == case2.gridLocal(Time::MAX ));
|
||||
CHECK (secs(-1) == case2.gridLocal(Time::MAX -TimeValue(1) )); // note: next lower frame
|
||||
CHECK (secs(-1) == case2.gridLocal(Time::MAX -secs(1) )); // i.e. the same as a whole frame down
|
||||
CHECK (Time::MIN +secs(1) < case2.gridLocal( secs(+2) ));
|
||||
CHECK (Time::MIN +secs(1) >= case2.gridLocal( secs(+1) ));
|
||||
CHECK (Time::MIN < case2.gridLocal( secs(+1) ));
|
||||
CHECK (Time::MIN == case2.gridLocal( secs( 0) )); // note: because of downward truncating,
|
||||
CHECK (Time::MIN == case2.gridLocal( secs(-1) )); // resulting values will already exceed
|
||||
CHECK (Time::MIN == case2.gridLocal( secs(-2) )); // allowed range and thus will be clipped
|
||||
|
||||
// use very large frame with size of half the time range
|
||||
Duration hugeFrame(Time::MAX);
|
||||
FixedFrameQuantiser case3 (hugeFrame);
|
||||
CHECK (Time::MIN == case3.gridAlign(Time::MIN ));
|
||||
CHECK (Time::MIN == case3.gridAlign(Time::MIN +TimeValue(1) ));
|
||||
CHECK (Time::MIN == case3.gridAlign( secs(-1) ));
|
||||
CHECK (TimeValue(0) == case3.gridAlign( secs( 0) ));
|
||||
CHECK (TimeValue(0) == case3.gridAlign( secs(+1) ));
|
||||
CHECK (TimeValue(0) == case3.gridAlign(Time::MAX -TimeValue(1) ));
|
||||
CHECK (Time::MAX == case3.gridAlign(Time::MAX ));
|
||||
CHECK (Time::MIN == case3.gridLocal(Time::MIN ));
|
||||
CHECK (Time::MIN == case3.gridLocal(Time::MIN +TimeValue(1) ));
|
||||
CHECK (Time::MIN == case3.gridLocal( secs(-1) ));
|
||||
CHECK (TimeValue(0) == case3.gridLocal( secs( 0) ));
|
||||
CHECK (TimeValue(0) == case3.gridLocal( secs(+1) ));
|
||||
CHECK (TimeValue(0) == case3.gridLocal(Time::MAX -TimeValue(1) ));
|
||||
CHECK (Time::MAX == case3.gridLocal(Time::MAX ));
|
||||
|
||||
// now displacing this grid by +1sec....
|
||||
FixedFrameQuantiser case4 (hugeFrame, secs(1));
|
||||
CHECK (Time::MIN == case4.gridAlign(Time::MIN ));
|
||||
CHECK (Time::MIN == case4.gridAlign(Time::MIN +TimeValue(1) )); // clipped...
|
||||
CHECK (Time::MIN == case4.gridAlign(Time::MIN +secs(1) )); // but now exact (unclipped)
|
||||
CHECK (Time::MIN == case4.gridAlign( secs(-1) ));
|
||||
CHECK (Time::MIN == case4.gridAlign( secs( 0) ));
|
||||
CHECK (TimeValue(0) == case4.gridAlign( secs(+1) )); //.....now exactly the frame number zero
|
||||
CHECK (TimeValue(0) == case4.gridAlign(Time::MAX -TimeValue(1) ));
|
||||
CHECK (TimeValue(0) == case4.gridAlign(Time::MAX )); //.......still truncated down to frame #0
|
||||
CHECK (Time::MIN == case4.gridLocal(Time::MIN ));
|
||||
CHECK (Time::MIN == case4.gridLocal(Time::MIN +TimeValue(1) )); // clipped...
|
||||
CHECK (Time::MIN == case4.gridLocal(Time::MIN +secs(1) )); // but now exact (unclipped)
|
||||
CHECK (Time::MIN == case4.gridLocal( secs(-1) ));
|
||||
CHECK (Time::MIN == case4.gridLocal( secs( 0) ));
|
||||
CHECK (TimeValue(0) == case4.gridLocal( secs(+1) )); //.....now exactly the frame number zero
|
||||
CHECK (TimeValue(0) == case4.gridLocal(Time::MAX -TimeValue(1) ));
|
||||
CHECK (TimeValue(0) == case4.gridLocal(Time::MAX )); //.......still truncated down to frame #0
|
||||
|
||||
// think big...
|
||||
Duration superHuge{secs(12345) + hugeFrame};
|
||||
|
|
@ -212,34 +212,34 @@ namespace test{
|
|||
|
||||
// Time::MAX < superHuge < Duration::Max is possible, but we can accommodate only one
|
||||
FixedFrameQuantiser case5 (superHuge);
|
||||
CHECK (TimeValue(0) == case5.gridAlign(Time::MAX ));
|
||||
CHECK (TimeValue(0) == case5.gridAlign(Time::MAX -TimeValue(1) ));
|
||||
CHECK (TimeValue(0) == case5.gridAlign( secs( 1) ));
|
||||
CHECK (TimeValue(0) == case5.gridAlign( secs( 0) ));
|
||||
CHECK (Time::MIN == case5.gridAlign( secs(-1) ));
|
||||
CHECK (Time::MIN == case5.gridAlign(Time::MIN +TimeValue(1) ));
|
||||
CHECK (Time::MIN == case5.gridAlign(Time::MIN ));
|
||||
CHECK (TimeValue(0) == case5.gridLocal(Time::MAX ));
|
||||
CHECK (TimeValue(0) == case5.gridLocal(Time::MAX -TimeValue(1) ));
|
||||
CHECK (TimeValue(0) == case5.gridLocal( secs( 1) ));
|
||||
CHECK (TimeValue(0) == case5.gridLocal( secs( 0) ));
|
||||
CHECK (Time::MIN == case5.gridLocal( secs(-1) ));
|
||||
CHECK (Time::MIN == case5.gridLocal(Time::MIN +TimeValue(1) ));
|
||||
CHECK (Time::MIN == case5.gridLocal(Time::MIN ));
|
||||
|
||||
// now with offset
|
||||
FixedFrameQuantiser case6 (superHuge, Time::MAX-secs(1));
|
||||
CHECK (TimeValue(0) == case6.gridAlign(Time::MAX ));
|
||||
CHECK (TimeValue(0) == case6.gridAlign(Time::MAX -TimeValue(1) ));
|
||||
CHECK (TimeValue(0) == case6.gridAlign(Time::MAX -secs(1) ));
|
||||
CHECK (Time::MIN == case6.gridAlign(Time::MAX -secs(2) ));
|
||||
CHECK (Time::MIN == case6.gridAlign( secs( 1) ));
|
||||
CHECK (Time::MIN == case6.gridAlign( secs(-12345) ));
|
||||
CHECK (Time::MIN == case6.gridAlign( secs(-12345-1) ));
|
||||
CHECK (Time::MIN == case6.gridAlign( secs(-12345-2) )); // this would be one frame lower, but is clipped
|
||||
CHECK (Time::MIN == case6.gridAlign(Time::MIN +TimeValue(1) ));
|
||||
CHECK (Time::MIN == case6.gridAlign(Time::MIN )); // same... unable to represent time points before Time::MIN
|
||||
CHECK (TimeValue(0) == case6.gridLocal(Time::MAX ));
|
||||
CHECK (TimeValue(0) == case6.gridLocal(Time::MAX -TimeValue(1) ));
|
||||
CHECK (TimeValue(0) == case6.gridLocal(Time::MAX -secs(1) ));
|
||||
CHECK (Time::MIN == case6.gridLocal(Time::MAX -secs(2) ));
|
||||
CHECK (Time::MIN == case6.gridLocal( secs( 1) ));
|
||||
CHECK (Time::MIN == case6.gridLocal( secs(-12345) ));
|
||||
CHECK (Time::MIN == case6.gridLocal( secs(-12345-1) ));
|
||||
CHECK (Time::MIN == case6.gridLocal( secs(-12345-2) )); // this would be one frame lower, but is clipped
|
||||
CHECK (Time::MIN == case6.gridLocal(Time::MIN +TimeValue(1) ));
|
||||
CHECK (Time::MIN == case6.gridLocal(Time::MIN )); // same... unable to represent time points before Time::MIN
|
||||
|
||||
// maximum frame size is spanning the full time range
|
||||
FixedFrameQuantiser case7 (extraHuge, Time::MIN+secs(1));
|
||||
CHECK (TimeValue(0) == case7.gridAlign(Time::MAX )); // rounded down one frame, i.e. to origin
|
||||
CHECK (TimeValue(0) == case7.gridAlign( secs( 0) ));
|
||||
CHECK (TimeValue(0) == case7.gridAlign(Time::MIN+secs(2) ));
|
||||
CHECK (TimeValue(0) == case7.gridAlign(Time::MIN+secs(1) )); // exactly at origin
|
||||
CHECK (Time::MIN == case7.gridAlign(Time::MIN )); // one frame further down, but clipped to Time::MIN
|
||||
CHECK (TimeValue(0) == case7.gridLocal(Time::MAX )); // rounded down one frame, i.e. to origin
|
||||
CHECK (TimeValue(0) == case7.gridLocal( secs( 0) ));
|
||||
CHECK (TimeValue(0) == case7.gridLocal(Time::MIN+secs(2) ));
|
||||
CHECK (TimeValue(0) == case7.gridLocal(Time::MIN+secs(1) )); // exactly at origin
|
||||
CHECK (Time::MIN == case7.gridLocal(Time::MIN )); // one frame further down, but clipped to Time::MIN
|
||||
|
||||
// even larger frames aren't possible
|
||||
Duration not_really_larger(secs(10000) + extraHuge);
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ namespace test {
|
|||
ASSERT (0 < dirt);
|
||||
|
||||
Time dirty(point + Time(dirt));
|
||||
CHECK (point == TEST_ORIGIN + myGrid->gridAlign(dirty));
|
||||
CHECK (point == TEST_ORIGIN + myGrid->gridLocal(dirty));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -41108,7 +41108,7 @@
|
|||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1670191753771" ID="ID_838942043" MODIFIED="1670191797559" TEXT="Nebenbei bemerkt: das Grid::gridAligned() - API ist „überraschend“">
|
||||
<node COLOR="#435e98" CREATED="1670191753771" ID="ID_838942043" MODIFIED="1670197700477" TEXT="Nebenbei bemerkt: das Grid::gridAligned() - API ist „überraschend“">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1670191803951" ID="ID_62422663" MODIFIED="1670191874006" TEXT="das Ergebnis ist relativ zum Grid-Origin">
|
||||
<icon BUILTIN="info"/>
|
||||
|
|
@ -41150,19 +41150,46 @@
|
|||
<icon BUILTIN="forward"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1670192170956" ID="ID_1026606570" MODIFIED="1670192201815" TEXT="API ändern: gridAligned() soll den Origin mit einschließen">
|
||||
<node COLOR="#690f14" CREATED="1670192170956" ID="ID_1026606570" MODIFIED="1670201051650" TEXT="API ändern: gridAlign() soll den Origin mit einschließen">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1670192209793" ID="ID_1904533160" MODIFIED="1670192229367" TEXT="Limitierung bedenken">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
<node CREATED="1670200909516" ID="ID_1643706345" MODIFIED="1670200945558" TEXT="besser doch nicht: die Funtion wäre dann nämlich komplett redundant"/>
|
||||
<node CREATED="1670200914583" ID="ID_316481460" MODIFIED="1670201239789" TEXT="die gewünschte Funktion gibt es bereits auf dem Quantiser-API">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
<font face="Monospaced" size="2">TimeValue Quantiser::materialise(TimeValue const& raw) { return timeOf (gridPoint (raw)); }</font>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1670192204551" ID="ID_1757335290" MODIFIED="1670192230352" TEXT="Implementierung anpassen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1670201304802" ID="ID_1724553119" MODIFIED="1670201393006" TEXT="und letztere hat zudem den Vorteil, daß sie nicht clippt">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<ul>
|
||||
<li>
|
||||
weil die Rechnung komplett auf Implementierungs-Ebene passiert, mit int64_t
|
||||
</li>
|
||||
<li>
|
||||
unter der Maßgabe daß die auftretenden Werte dahingehend limititert sind, und daher auch noch die Summe zum Origin ohne wrap-around berechnet werden kann
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1670192239363" ID="ID_968994817" MODIFIED="1670192243152" TEXT="dokumentieren">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1670192231262" ID="ID_185488622" MODIFIED="1670192236941" TEXT="Test anpassen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1670200952970" ID="ID_2558241" MODIFIED="1670197706677" TEXT="API-Funtkion umbenennen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1670200964176" ID="ID_795458621" MODIFIED="1670201044967" TEXT="gridAlign() ⟼ gridLocal()"/>
|
||||
<node CREATED="1670201059514" ID="ID_489288280" MODIFIED="1670201082523" TEXT="das macht dann wenigstens den Unterschied klar">
|
||||
<node CREATED="1670201083498" ID="ID_1913733433" MODIFIED="1670201094684" TEXT="Input: eine globale freie Zeit"/>
|
||||
<node CREATED="1670201095403" ID="ID_1247848116" MODIFIED="1670201105896" TEXT="Output: eine grit-relative, quantisierte Zeit"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -58042,6 +58069,7 @@
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1667476797049" FOLDED="true" ID="ID_767502481" MODIFIED="1667770624162" TEXT="Diskussion: interne Zeitbasis">
|
||||
<linktarget COLOR="#af1a4c" DESTINATION="ID_767502481" ENDARROW="Default" ENDINCLINATION="96;-430;" ID="Arrow_ID_1672039685" SOURCE="ID_1838246834" STARTARROW="None" STARTINCLINATION="-670;38;"/>
|
||||
<linktarget COLOR="#535cb5" DESTINATION="ID_767502481" ENDARROW="Default" ENDINCLINATION="-9;23;" ID="Arrow_ID_1371034703" SOURCE="ID_368365221" STARTARROW="None" STARTINCLINATION="-97;6;"/>
|
||||
<icon BUILTIN="hourglass"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1667486621881" ID="ID_566152244" MODIFIED="1667486629636" TEXT="#1258 clarify internal time base">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
|
|
|
|||
Loading…
Reference in a new issue