Freigeben über


scan-Operator

Gilt für: ✅Microsoft Fabric✅Azure Data ExplorerAzure MonitorMicrosoft Sentinel

Scannt Daten, führt Abgleiche durch und erstellt Sequenzen basierend auf den Prädikaten.

Übereinstimmende Datensätze werden gemäß den in den Schritten des Operators definierten Prädikaten bestimmt. Ein Prädikat kann vom Zustand abhängen, der durch vorherige Schritte generiert wird. Die Ausgabe für den übereinstimmenden Datensatz wird durch den Eingabedatensatz und die zuordnungen bestimmt, die in den Schritten des Operators definiert sind.

Syntax

T | scan [ with_match_id = MatchIdColumnName ] [ declare ( ColumnDeclarations ) ] with ( StepDefinitions )

ColumnDeclarations-Syntax

ColumnName : ColumnType[= DefaultValue ] [, ... ]

StepDefinition-Syntax

stepStepName [ outputlast | all | none = ] : Bedingung [ Spaltenzuweisung = [, => ... ];

Erfahren Sie mehr über Syntaxkonventionen.

Parameter

Name Type Erforderlich Beschreibung
T string ✔️ Die Tabellarische Eingabequelle.
MatchIdColumnName string Der Name einer Spalte vom Typ long , die als Teil der Scanausführung an die Ausgabe angefügt wird. Gibt den 0-basierten Index der Übereinstimmung für den Datensatz an.
ColumnDeclarations string Deklariert eine Erweiterung für das Schema von T. Diese Spalten sind in den Schritten Werte zugewiesen. Wenn sie nicht zugewiesen ist, wird der DefaultValue zurückgegeben. Sofern nicht anders angegeben, ist nullDefaultValue .
StepName string ✔️ Wird verwendet, um auf Werte im Status der Überprüfung für Bedingungen und Zuordnungen zu verweisen. Der Schrittname muss eindeutig sein.
Condition string ✔️ Ein Ausdruck, der ausgewertet true wird oder false definiert, welche Datensätze aus der Eingabe mit dem Schritt übereinstimmen. Ein Datensatz stimmt mit dem Schritt überein, wenn die Bedingung mit dem Status des Schritts oder mit dem Status des vorherigen Schritts übereinstimmt true .
Abtretung string Ein skalarer Ausdruck, der der entsprechenden Spalte zugewiesen ist, wenn ein Datensatz einem Schritt entspricht.
output string Steuert die Ausgabelogik des Schritts für wiederholte Übereinstimmungen. all gibt alle Datensätze aus, die dem Schritt entsprechen, last gibt nur den letzten Datensatz in einer Reihe wiederholter Übereinstimmungen für den Schritt aus und none gibt keine Datensätze aus, die dem Schritt entsprechen. Der Standardwert ist all.

Gibt zurück

Ein Datensatz für jede Übereinstimmung eines Datensatzes von der Eingabe zu einem Schritt. Das Schema der Ausgabe ist das Schema der Quelle, die mit der Spalte in der declare Klausel erweitert wird.

Scanlogik

scan überschreitet die serialisierten Eingabedaten, datensätze nach Datensatz, vergleicht jeden Datensatz mit der Bedingung jedes Schritts und berücksichtigt dabei den aktuellen Zustand jedes Schritts.

State

Der zugrunde liegende Zustand des scan Operators kann als Tabelle mit jeweils einer Zeile stepbetrachtet werden. Jeder Schritt behält seinen eigenen Zustand mit den neuesten Werten der Spalten und deklarierten Variablen aus allen vorherigen Schritten und dem aktuellen Schritt. Falls relevant, enthält sie auch die Übereinstimmungs-ID für die fortlaufende Sequenz.

Wenn ein Scanoperator n Schritte mit dem Namen s_1, s_2, ..., s_n hat, würde schritt s_k k Datensätze in seinem Zustand aufweisen, der s_1, s_2, ..., s_k entspricht. Der Schrittname.Das ColumnName-Format wird verwendet, um auf einen Wert im Zustand zu verweisen. Würde z. B. auf spalte verweisen, s_2.col1 die zu Schritt s_2 im Status s_k gehört.col1 Ein ausführliches Beispiel finden Sie in der exemplarischen Vorgehensweise zur Überprüfungslogik.

Der Zustand beginnt leer und wird aktualisiert, wenn ein gescannter Eingabedatensatz einem Schritt entspricht. Wenn der Status des aktuellen Schritts nicht inAktiv ist, wird der Schritt als aktive Sequenz bezeichnet.

Abgleichslogik

Jeder Eingabedatensatz wird von dem letzten Schritt bis zum ersten Schritt anhand aller Schritte in umgekehrter Reihenfolge ausgewertet. Wenn ein Datensatz r anhand eines Schritts s_k ausgewertet wird, wird die folgende Logik angewendet:

  • Check 1: If the state of the previous step (s_k-1) is nonempty, and r meets the Condition of s_k, then a match occurs. Die Übereinstimmung führt zu den folgenden Aktionen:

    1. Der Status der s_k wird gelöscht.
    2. Der Zustand von s_k-1 wird gefördert, um zum Zustand der s_k zu werden.
    3. Die Zuordnungen von s_k werden berechnet und erweitert r.
    4. Der erweiterte r wird der Ausgabe und dem Status von s_k hinzugefügt.

    Hinweis

    Wenn "Check 1 " zu einer Übereinstimmung führt, wird "Check 2 " ignoriert, und r bewegt sich, um gegen s_k-1 ausgewertet zu werden.

  • Prüfung 2: Wenn der Status von s_k eine aktive Sequenz aufweist oder s_k der erste Schritt ist und r die Bedingung von s_k erfüllt, tritt eine Übereinstimmung auf. Die Übereinstimmung führt zu den folgenden Aktionen:

    1. Die Zuordnungen von s_k werden berechnet und erweitert r.
    2. Die Werte, die s_k im Zustand s_k darstellen, werden durch die Werte des erweiterten R ersetzt.
    3. Wenn s_k definiert output=allist, wird der Ausgabe das erweiterte r hinzugefügt.
    4. Wenn s_k der erste Schritt ist, beginnt eine neue Sequenz, und die Übereinstimmungs-ID erhöht sich um 1. Dies wirkt sich nur auf die Ausgabe aus, wenn with_match_id sie verwendet wird.

Sobald die Überprüfungen für s_k abgeschlossen sind, wird r fort, um gegen s_k-1 ausgewertet zu werden.

Ein ausführliches Beispiel für diese Logik finden Sie in der exemplarischen Vorgehensweise zur Überprüfungslogik.

Beispiele

Kumulierte Summe

Berechnen Sie die kumulierte Summe für eine Eingabespalte. Das Ergebnis dieses Beispiels entspricht der Verwendung von row_cumsum().

range x from 1 to 5 step 1 
| scan declare (cumulative_x:long=0) with 
(
    step s1: true => cumulative_x = x + s1.cumulative_x;
)

Ausgabe

x cumulative_x
1 1
2 3
3 6
4 10
5 15

Kumulierte Summe für mehrere Spalten mit einer Zurücksetzungsbedingung

Berechnen Sie die kumulierte Summe für zwei Eingabespalten, setzen Sie den Summenwert auf den aktuellen Datensatzwert zurück, wenn die kumulierte Summe 10 oder mehr erreicht hat.

range x from 1 to 5 step 1
| extend y = 2 * x
| scan declare (cumulative_x:long=0, cumulative_y:long=0) with 
(
    step s1: true => cumulative_x = iff(s1.cumulative_x >= 10, x, x + s1.cumulative_x), 
                     cumulative_y = iff(s1.cumulative_y >= 10, y, y + s1.cumulative_y);
)

Ausgabe

x Y cumulative_x cumulative_y
1 2 1 2
2 4 3 6
3 6 6 12
4 8 10 8
5 10 5 18

Weiterleiten einer Spalte

Füllen Sie eine Zeichenfolgenspalte vorwärts aus. Jedem leeren Wert wird der zuletzt angezeigte Nichterwendwert zugewiesen.Each empty value is assigned the last seen nonempty value.

let Events = datatable (Ts: timespan, Event: string) [
    0m, "A",
    1m, "",
    2m, "B",
    3m, "",
    4m, "",
    6m, "C",
    8m, "",
    11m, "D",
    12m, ""
]
;
Events
| sort by Ts asc
| scan declare (Event_filled: string="") with 
(
    step s1: true => Event_filled = iff(isempty(Event), s1.Event_filled, Event);
)

Output

Ts Ereignis Event_filled
00:00:00 A A
00:01:00 A
00:02:00 b b
00:03:00 b
00:04:00 b
00:06:00 K K
00:08:00 K
00:11:00 D D
00:12:00 D

Tagging von Sitzungen

Teilen Sie die Eingabe in Sitzungen auf: Eine Sitzung endet 30 Minuten nach dem ersten Ereignis der Sitzung, nach dem eine neue Sitzung gestartet wird. Beachten Sie die Verwendung der with_match_id Kennzeichnung, die für jede eindeutige Übereinstimmung (Sitzung) des Scans einen eindeutigen Wert zuweist. Beachten Sie außerdem die besondere Verwendung von zwei Schritten in diesem Beispiel als Bedingung, inSession true sodass alle Datensätze aus der Eingabe erfasst und ausgegeben werden, während endSession Datensätze erfasst werden, die mehr als 30 m vom sessionStart Wert für die aktuelle Übereinstimmung stammen. Der endSession Schritt hat output=none die Bedeutung, dass es keine Ausgabedatensätze erzeugt. Der endSession Schritt wird verwendet, um den Status der aktuellen Übereinstimmung von inSession zu zu endSessionwechseln, sodass eine neue Übereinstimmung (Sitzung) beginnen kann, beginnend mit dem aktuellen Datensatz.

let Events = datatable (Ts: timespan, Event: string) [
    0m, "A",
    1m, "A",
    2m, "B",
    3m, "D",
    32m, "B",
    36m, "C",
    38m, "D",
    41m, "E",
    75m, "A"
]
;
Events
| sort by Ts asc
| scan with_match_id=session_id declare (sessionStart: timespan) with 
(
    step inSession: true => sessionStart = iff(isnull(inSession.sessionStart), Ts, inSession.sessionStart);
    step endSession output=none: Ts - inSession.sessionStart > 30m;
)

Output

Ts Ereignis sessionStart session_id
00:00:00 A 00:00:00 0
00:01:00 A 00:00:00 0
00:02:00 b 00:00:00 0
00:03:00 D 00:00:00 0
00:32:00 b 00:32:00 1
00:36:00 K 00:32:00 1
00:38:00 D 00:32:00 1
00:41:00 E 00:32:00 1
01:15:00 A 01:15:00 2

Ereignisse zwischen Start und Stopp

Suchen Sie alle Abfolgen von Ereignissen zwischen dem Ereignis Start und dem Ereignis Stop , die innerhalb von 5 Minuten auftreten. Weisen Sie für jede Sequenz eine Übereinstimmungs-ID zu.

let Events = datatable (Ts: timespan, Event: string) [
    0m, "A",
    1m, "Start",
    2m, "B",
    3m, "D",
    4m, "Stop",
    6m, "C",
    8m, "Start",
    11m, "E",
    12m, "Stop"
]
;
Events
| sort by Ts asc
| scan with_match_id=m_id with 
(
    step s1: Event == "Start";
    step s2: Event != "Start" and Event != "Stop" and Ts - s1.Ts <= 5m;
    step s3: Event == "Stop" and Ts - s1.Ts <= 5m;
)

Output

Ts Ereignis m_id
00:01:00 Start 0
00:02:00 b 0
00:03:00 D 0
00:04:00 Beenden 0
00:08:00 Start 1
00:11:00 E 1
00:12:00 Beenden 1

Berechnen eines benutzerdefinierten Trichters von Ereignissen

Berechnen Eines Trichterabschlusses der Sequenz Hail ->>TornadoThunderstorm Wind nach State benutzerdefinierten Schwellenwerten für die Zeiten zwischen den Ereignissen (Tornado innerhalb 1h und Thunderstorm Wind innerhalb ).2h Dieses Beispiel ähnelt dem funnel_sequence_completion-Plug-In, ermöglicht jedoch größere Flexibilität.

StormEvents
| partition hint.strategy=native by State 
    (
    sort by StartTime asc
    | scan with 
    (
        step hail: EventType == "Hail";
        step tornado: EventType == "Tornado" and StartTime - hail.StartTime <= 1h;
        step thunderstormWind: EventType == "Thunderstorm Wind" and StartTime - tornado.StartTime <= 2h;
    )
    )
| summarize dcount(State) by EventType

Ausgabe

EventType dcount_State
Hagel 50
Tornado 34
Sturm 32

Exemplarische Vorgehensweise zur Überprüfungslogik

In diesem Abschnitt wird die Scanlogik mithilfe einer schrittweisen exemplarischen Vorgehensweise der Ereignisse zwischen Start- und Stoppbeispiel veranschaulicht:

let Events = datatable (Ts: timespan, Event: string) [
    0m, "A",
    1m, "Start",
    2m, "B",
    3m, "D",
    4m, "Stop",
    6m, "C",
    8m, "Start",
    11m, "E",
    12m, "Stop"
]
;
Events
| sort by Ts asc
| scan with_match_id=m_id with 
(
    step s1: Event == "Start";
    step s2: Event != "Start" and Event != "Stop" and Ts - s1.Ts <= 5m;
    step s3: Event == "Stop" and Ts - s1.Ts <= 5m;
)

Der Zustand

Stellen Sie sich den Status des scan Operators als Tabelle mit einer Zeile für jeden Schritt vor, in der jeder Schritt über einen eigenen Zustand verfügt. Dieser Zustand enthält die neuesten Werte der Spalten und deklarierten Variablen aus allen vorherigen Schritten und dem aktuellen Schritt. Weitere Informationen finden Sie unter "Bundesland".

In diesem Beispiel kann der Zustand mit der folgenden Tabelle dargestellt werden:

step m_id s1. Ts s1. Ereignis s2. Ts s2. Ereignis s3. Ts s3. Ereignis
s1 X X X X
s2 X X
s3

Das "X" gibt an, dass für diesen Schritt ein bestimmtes Feld irrelevant ist.

Die entsprechende Logik

Dieser Abschnitt folgt der übereinstimmenden Logik durch jeden Datensatz der Events Tabelle und erläutert die Transformation des Zustands und der Ausgabe in jedem Schritt.

Hinweis

Ein Eingabedatensatz wird anhand der Schritte in umgekehrter Reihenfolge ausgewertet, von dem letzten Schritt (s3) bis zum ersten Schritt (s1).

Datensatz 1

Ts Ereignis
0m "A"

Aufzeichnen der Auswertung bei jedem Schritt:

  • s3: Die Prüfung 1 wird nicht übergeben, da der Status s2 leer ist und Check 2 nicht übergeben wird, da s3 keine aktive Sequenz vorhanden ist.
  • s2: Die Prüfung 1 wird nicht übergeben, da der Status s1 leer ist und Check 2 nicht übergeben wird, da s2 keine aktive Sequenz vorhanden ist.
  • s1: Check 1 ist irrelevant, da kein vorheriger Schritt vorhanden ist. Check 2 wird nicht übergeben, weil der Datensatz nicht die Bedingung erfüllt Event == "Start". Datensatz 1 wird verworfen, ohne den Zustand oder die Ausgabe zu beeinträchtigen.

Zustand:

step m_id s1. Ts s1. Ereignis s2. Ts s2. Ereignis s3. Ts s3. Ereignis
s1 X X X X
s2 X X
s3

Datensatz 2

Ts Ereignis
1 Min. "Start"

Aufzeichnen der Auswertung bei jedem Schritt:

  • s3: Die Prüfung 1 wird nicht übergeben, da der Status s2 leer ist und Check 2 nicht übergeben wird, da s3 keine aktive Sequenz vorhanden ist.
  • s2: Die Prüfung 1 wird nicht übergeben, da der Status s1 leer ist und Check 2 nicht übergeben wird, da s2 keine aktive Sequenz vorhanden ist.
  • s1: Check 1 ist irrelevant, da kein vorheriger Schritt vorhanden ist. Check 2 wird übergeben, da der Datensatz die Bedingung von Event == "Start". Diese Übereinstimmung initiiert eine neue Sequenz und wird m_id zugewiesen. Datensatz 2 und seine m_id (0) werden dem Zustand und der Ausgabe hinzugefügt.

Zustand:

step m_id s1. Ts s1. Ereignis s2. Ts s2. Ereignis s3. Ts s3. Ereignis
s1 0 00:01:00 "Start" X X X X
s2 X X
s3

Datensatz 3

Ts Ereignis
2m „B“

Aufzeichnen der Auswertung bei jedem Schritt:

  • s3: Die Prüfung 1 wird nicht übergeben, da der Status s2 leer ist und Check 2 nicht übergeben wird, da s3 keine aktive Sequenz vorhanden ist.
  • s2: Überprüfung 1 wird übergeben, da der Status nicht s1 erfüllt ist und der Datensatz die Bedingung erfüllt Ts - s1.Ts < 5m. Diese Übereinstimmung bewirkt, dass der Zustand der s1 Löschung erfolgt und die Reihenfolge s1 höhergestuft s2wird. Datensatz 3 und seine m_id (0) werden dem Zustand und der Ausgabe hinzugefügt.
  • s1: Check 1 ist irrelevant, da kein vorheriger Schritt vorhanden ist und Check 2 nicht übergeben wird, da der Datensatz nicht die Bedingung erfüllt Event == "Start".

Zustand:

step m_id s1. Ts s1. Ereignis s2. Ts s2. Ereignis s3. Ts s3. Ereignis
s1 X X X X
s2 0 00:01:00 "Start" 00:02:00 „B“ X X
s3

Datensatz 4

Ts Ereignis
3 Min. "D"

Aufzeichnen der Auswertung bei jedem Schritt:

  • s3: Überprüfung 1 wird nicht übergeben, weil der Datensatz nicht die Bedingung Event == "Stop"erfüllt, und Check 2 wird nicht übergeben, da s3 keine aktive Sequenz vorhanden ist.
  • s2: Überprüfung 1 wird nicht übergeben, weil der Status s1 leer ist. die Prüfung 2 besteht, weil sie die Bedingung erfülltTs - s1.Ts < 5m. Datensatz 4 und seine m_id (0) werden dem Zustand und der Ausgabe hinzugefügt. Die Werte aus diesem Datensatz überschreiben die vorherigen Zustandswerte für s2.Ts und s2.Event.
  • s1: Check 1 ist irrelevant, da kein vorheriger Schritt vorhanden ist und Check 2 nicht übergeben wird, da der Datensatz nicht die Bedingung erfüllt Event == "Start".

Zustand:

step m_id s1. Ts s1. Ereignis s2. Ts s2. Ereignis s3. Ts s3. Ereignis
s1 X X X X
s2 0 00:01:00 "Start" 00:03:00 "D" X X
s3

Datensatz 5

Ts Ereignis
4 Min. "Stopp"

Aufzeichnen der Auswertung bei jedem Schritt:

  • s3: Prüfung 1 wird übergeben, weil s2 sie nicht entsent ist und die s3 Bedingung erfüllt Event == "Stop". Diese Übereinstimmung bewirkt, dass der Zustand der s2 Löschung erfolgt und die Reihenfolge s2 höhergestuft s3wird. Datensatz 5 und seine m_id (0) werden dem Zustand und der Ausgabe hinzugefügt.
  • s2: Die Prüfung 1 wird nicht übergeben, da der Status s1 leer ist und Check 2 nicht übergeben wird, da s2 keine aktive Sequenz vorhanden ist.
  • s1: Check 1 ist irrelevant, da kein vorheriger Schritt vorhanden ist. Check 2 wird nicht übergeben, weil der Datensatz nicht die Bedingung erfüllt Event == "Start".

Zustand:

step m_id s1. Ts s1. Ereignis s2. Ts s2. Ereignis s3. Ts s3. Ereignis
s1 X X X X
s2 X X
s3 0 00:01:00 "Start" 00:03:00 "D" 00:04:00 "Stopp"

Datensatz 6

Ts Ereignis
6m „C“

Aufzeichnen der Auswertung bei jedem Schritt:

  • s3: Check 1 wird nicht übergeben, weil der Status s2 leer ist und Check 2 nicht übergeben wird, da s3 die s3 Bedingung von Event == "Stop".
  • s2: Die Prüfung 1 wird nicht übergeben, da der Status s1 leer ist und Check 2 nicht übergeben wird, da s2 keine aktive Sequenz vorhanden ist.
  • s1: Überprüfung 1 wird nicht übergeben, weil kein vorheriger Schritt vorhanden ist, und Check 2 wird nicht übergeben, weil sie nicht die Bedingung erfüllt Event == "Start". Datensatz 6 wird verworfen, ohne den Zustand oder die Ausgabe zu beeinträchtigen.

Zustand:

step m_id s1. Ts s1. Ereignis s2. Ts s2. Ereignis s3. Ts s3. Ereignis
s1 X X X X
s2 X X
s3 0 00:01:00 "Start" 00:03:00 "D" 00:04:00 "Stopp"

Datensatz 7

Ts Ereignis
8m "Start"

Aufzeichnen der Auswertung bei jedem Schritt:

  • s3: Prüfung 1 wird nicht übergeben, weil der Status s2 leer ist und Check 2 nicht übergeben wird, weil sie nicht die Bedingung erfüllt Event == "Stop".
  • s2: Die Prüfung 1 wird nicht übergeben, da der Status s1 leer ist und Check 2 nicht übergeben wird, da s2 keine aktive Sequenz vorhanden ist.
  • s1: Überprüfung 1 wird nicht übergeben, da kein vorheriger Schritt vorhanden ist. die Prüfung 2 besteht, weil sie die Bedingung erfülltEvent == "Start". Diese Übereinstimmung initiiert eine neue Sequenz s1 mit einer neuen m_id. Datensatz 7 und seine m_id (1) werden dem Zustand und der Ausgabe hinzugefügt.

Zustand:

step m_id s1. Ts s1. Ereignis s2. Ts s2. Ereignis s3. Ts s3. Ereignis
s1 1 00:08:00 "Start" X X X X
s2 X X
s3 0 00:01:00 "Start" 00:03:00 "D" 00:04:00 "Stopp"

Hinweis

Es gibt nun zwei aktive Sequenzen im Zustand.

Datensatz 8

Ts Ereignis
11 Min. "E"

Aufzeichnen der Auswertung bei jedem Schritt:

  • s3: Prüfung 1 wird nicht übergeben, weil der Status s2 leer ist und Check 2 nicht übergeben wird, weil sie nicht die s3 Bedingung erfüllt Event == "Stop".
  • s2: Überprüfung 1 wird übergeben, da der Status nicht s1 erfüllt ist und der Datensatz die Bedingung erfüllt Ts - s1.Ts < 5m. Diese Übereinstimmung bewirkt, dass der Zustand der s1 Löschung erfolgt und die Reihenfolge s1 höhergestuft s2wird. Datensatz 8 und seine m_id (1) werden dem Zustand und der Ausgabe hinzugefügt.
  • s1: Check 1 ist irrelevant, da kein vorheriger Schritt vorhanden ist und Check 2 nicht übergeben wird, da der Datensatz nicht die Bedingung erfüllt Event == "Start".

Zustand:

step m_id s1. Ts s1. Ereignis s2. Ts s2. Ereignis s3. Ts s3. Ereignis
s1 X X X X
s2 1 00:08:00 "Start" 00:11:00 "E" X X
s3 0 00:01:00 "Start" 00:03:00 "D" 00:04:00 "Stopp"

Datensatz 9

Ts Ereignis
12m "Stopp"

Aufzeichnen der Auswertung bei jedem Schritt:

  • s3: Prüfung 1 wird übergeben, weil s2 sie nicht entsent ist und die s3 Bedingung erfüllt Event == "Stop". Diese Übereinstimmung bewirkt, dass der Zustand der s2 Löschung erfolgt und die Reihenfolge s2 höhergestuft s3wird. Datensatz 9 und seine m_id (1) werden dem Zustand und der Ausgabe hinzugefügt.
  • s2: Die Prüfung 1 wird nicht übergeben, da der Status s1 leer ist und Check 2 nicht übergeben wird, da s2 keine aktive Sequenz vorhanden ist.
  • s1: Überprüfung 1 wird nicht übergeben, da kein vorheriger Schritt vorhanden ist. die Prüfung 2 besteht, weil sie die Bedingung erfülltEvent == "Start". Diese Übereinstimmung initiiert eine neue Sequenz s1 mit einer neuen m_id.

Zustand:

step m_id s1. Ts s1. Ereignis s2. Ts s2. Ereignis s3. Ts s3. Ereignis
s1 X X X X
s2 X X
s3 1 00:08:00 "Start" 00:11:00 "E" 00:12:00 "Stopp"

Endgültige Ausgabe

Ts Ereignis m_id
00:01:00 Start 0
00:02:00 b 0
00:03:00 D 0
00:04:00 Beenden 0
00:08:00 Start 1
00:11:00 E 1
00:12:00 Beenden 1