Timeline visualization
출처: 문서
본문
Timeline 시각화
Timeline은 OpenSearch Dashboards에서 표현식 기반 데이터 시각화 도구로, 간단한 표현식 언어를 사용하여 시계열 시각화를 만들 수 있습니다. 그래픽 인터페이스를 사용하는 다른 시각화 유형과 달리 Timeline은 텍스트 기반 표현식 구문을 사용하여 데이터 소스, 변환 및 표시 옵션을 정의합니다. 이 구문을 사용하면 여러 시계열을 비교하고, 수학 함수를 적용하고, 서로 다른 기간의 데이터를 오버레이할 수 있습니다.
Timeline 시각화를 사용하는 경우
Timeline은 시간 기반 데이터 분석 전용으로 사용하며, 특히 표현식 구문을 사용하여 시간적 패턴과 이벤트 시퀀스를 드러내는 데 적합합니다.
Timeline은 레거시 시각화 도구입니다. 새로운 시간 기반 시각화에는 TSVB 또는 Vega를 사용하는 것이 좋습니다. {: .note}
Timeline은 오프셋을 사용하여 기간별 데이터 비교, 시리즈에 수학적 변환 적용, 단일 차트에 여러 데이터 소스 결합 등 시각화에 대한 표현식 기반 제어가 필요한 시나리오에 가장 적합합니다. {: .tip}
전제 조건
Timeline 시각화를 만들기 전에 다음이 준비되어 있는지 확인하세요.
- 실행 중이고 접근 가능한 OpenSearch Dashboards 인스턴스.
- 샘플 데이터가 로드되었거나 시계열 인덱스를 사용할 수 있어야 합니다. 이 문서의 예제는 e-커머스 샘플 데이터 세트를 사용합니다. 샘플 데이터 세트 추가에 대한 자세한 내용은 샘플 데이터 추가를 참조하세요.
Timeline 시각화 만들기
Timeline 시각화를 만들려면 다음 단계를 따르세요.
- 상단 메뉴에서 OpenSearch Dashboards > Visualize를 선택합니다.
- Create visualization을 선택합니다.
- Timeline을 선택합니다.
Timeline 편집기는 다음 구성 요소로 구성됩니다.
- 차트 영역: 렌더링된 시각화를 표시합니다.
- 간격: 데이터 집계를 위한 시간 버킷 크기를 설정합니다(예:
1d,1h또는auto). - Timeline 표현식: 시각화의 데이터와 모양을 정의하는 Timeline 표현식을 작성하는 텍스트 편집기입니다.
- 업데이트 및 취소 버튼: 표현식에 대한 변경 사항을 적용하거나 되돌립니다.
다음 이미지는 e-커머스 데이터를 쿼리하는 기본 표현식이 포함된 Timeline 편집기를 보여줍니다.
{: width="700" }
Timeline 표현식 구문
Timeline 표현식은 쉼표로 구분된 하나 이상의 함수 체인으로 구성됩니다. 각 체인은 데이터 소스 함수로 시작하고 점 표기법을 사용하여 연결된 추가 함수가 이어집니다. 여러 체인은 쉼표로 구분되며 동일한 차트에 여러 시리즈를 생성합니다.
기본 구문은 다음과 같습니다.
.function1(arg1=value1, arg2=value2).function2(arg1=value1)
{% include copy.html %}
동일한 차트에 여러 시리즈를 표시하려면 표현식을 쉼표로 구분하세요.
.opensearch(index=my-index).label("Series 1"), .opensearch(index=my-index, metric=avg:price).label("Series 2")
{% include copy.html %}
데이터 소스 함수
.opensearch() 함수는 Timeline 표현식의 기본 데이터 소스입니다. OpenSearch 인덱스에서 시계열 데이터를 가져옵니다.
.opensearch() 매개변수
다음 표는 .opensearch() 함수 매개변수를 나열합니다.
| 매개변수 | 유형 | 설명 |
|---|---|---|
q |
String | Apache Lucene 쿼리 문자열 구문의 쿼리입니다. 기본값은 *(모두 일치)입니다. |
metric |
String | OpenSearch 메트릭 집계: avg, sum, min, max, percentiles 또는 cardinality 뒤에 필드 이름이 옵니다. 예: sum:bytes 또는 percentiles:bytes:95,99,99.9. 기본값은 count입니다. |
split |
String | 시리즈를 분할할 필드와 제한입니다. 예: hostname:10은 상위 10개 호스트 이름을 검색합니다. |
index |
String | 쿼리할 인덱스입니다. 와일드카드가 허용됩니다. 스크립트 필드 및 필드 이름 제안에 인덱스 패턴 이름을 제공합니다. |
timefield |
String | x축에 사용할 date 유형의 필드입니다. |
offset |
String | 날짜 표현식으로 시리즈 검색을 오프셋합니다. 예: -1M은 한 달 전 이벤트가 지금 발생하는 것처럼 표시합니다. timerange:-2를 사용하여 전체 차트 시간 범위의 두 배만큼 과거로 오프셋합니다. |
opensearchDashboards |
Boolean | true로 설정하면 OpenSearch Dashboards 대시보드에 적용된 필터를 적용합니다. 대시보드에서 사용할 때만 효과가 있습니다. |
data_source_name |
String | 쿼리할 데이터 소스입니다. 여러 데이터 소스가 활성화된 경우에만 작동합니다. |
fit |
String | 시리즈를 대상 시간 범위 및 간격에 맞추는 데 사용할 알고리즘입니다. average, carry, nearest, none 또는 scale 중 하나입니다. |
기본 쿼리 예제
다음 표현식은 시간에 따라 e-커머스 샘플 데이터 인덱스에서 문서 수를 검색합니다.
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date)
{% include copy.html %}
메트릭 집계 예제
다음 표현식은 taxful_total_price 필드의 평균 값을 계산합니다.
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date, metric=avg:taxful_total_price)
{% include copy.html %}
쿼리 필터 예제
다음 표현식은 q 매개변수를 사용하여 Lucene 쿼리 구문으로 데이터를 필터링합니다.
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date, q="customer_gender:MALE").label("Male Orders"),
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date, q="customer_gender:FEMALE").label("Female Orders")
{% include copy.html %}
분할 예제
다음 표현식은 customer_gender 필드로 데이터를 분할하여 상위 2개 값을 반환합니다.
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date, split=customer_gender:2)
{% include copy.html %}
오프셋 예제
다음 표현식은 현재 시간 범위를 일주일 전 데이터와 오버레이하여 비교합니다.
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date).label("This Week"),
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date, offset=-1w).label("Previous Week")
{% include copy.html %}
다음 이미지는 오프셋을 사용하여 현재 주와 이전 주를 비교한 것입니다.
{: width="700" }
표시 함수
표시 함수는 시리즈를 렌더링하는 데 사용되는 차트 유형(선, 막대 또는 점)을 제어합니다.
.lines()
시리즈를 선으로 렌더링합니다. 다음 표는 .lines() 함수 매개변수를 나열합니다.
| 매개변수 | 유형 | 설명 |
|---|---|---|
width |
Number | 선 두께(픽셀)입니다. |
fill |
Number | 채우기 불투명도를 제어하는 0에서 10 사이의 숫자입니다. 영역 차트를 만드는 데 사용합니다. |
stack |
Boolean | true로 설정하면 선을 쌓습니다. |
show |
Boolean | 선을 표시하거나 숨깁니다. |
steps |
Boolean | true로 설정하면 점 사이를 보간하지 않고 선을 계단식으로 렌더링합니다. |
예제
다음 표현식은 사용자 지정 너비와 채우기로 선 차트를 렌더링합니다.
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date).lines(width=2, fill=1)
{% include copy.html %}
.bars()
시리즈를 막대로 렌더링합니다. 다음 표는 .bars() 함수 매개변수를 나열합니다.
| 매개변수 | 유형 | 설명 |
|---|---|---|
width |
Number | 막대 너비(픽셀)입니다. |
stack |
Boolean | true로 설정하면 막대를 쌓습니다. 기본값은 true입니다. |
예제
다음 표현식은 총 수익의 막대 차트를 렌더링합니다.
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date, metric=sum:taxful_total_price).bars(width=2)
{% include copy.html %}
.points()
시리즈를 점으로 렌더링합니다. 다음 표는 .points() 함수 매개변수를 나열합니다.
| 매개변수 | 유형 | 설명 |
|---|---|---|
radius |
Number | 점 크기입니다. |
weight |
Number | 점 주위 선의 두께입니다. |
fill |
Number | 채우기 불투명도를 나타내는 0에서 10 사이의 숫자입니다. |
fillColor |
String | 점을 채울 색상입니다. |
symbol |
String | 점 기호입니다. triangle, cross, square, diamond 또는 circle 중 하나입니다. |
show |
Boolean | 점을 표시하거나 숨깁니다. |
예제
다음 표현식은 데이터를 십자 모양 점으로 렌더링합니다.
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date, metric=max:taxful_total_price).points(symbol=cross, radius=3)
{% include copy.html %}
스타일링 함수
스타일링 함수는 차트 유형을 변경하지 않고 시리즈의 레이블, 색상 및 범례를 제어합니다.
.label()
범례에 표시되는 시리즈의 레이블을 변경합니다. $1, $2 등을 사용하여 정규식 캡처 그룹을 참조합니다. 다음 표는 .label() 함수 매개변수를 나열합니다.
| 매개변수 | 유형 | 설명 |
|---|---|---|
label |
String | 시리즈의 범례 값입니다. $1, $2 등을 사용하여 정규식 캡처 그룹을 참조합니다. |
regex |
String | 캡처 그룹을 지원하는 정규식입니다. |
예제
다음 표현식은 시리즈에 사용자 지정 레이블을 설정합니다.
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date).label("Daily Order Count")
{% include copy.html %}
.color()
시리즈의 색상을 변경합니다. 16진수 색상 값을 허용합니다. 여러 시리즈에 걸쳐 그라데이션을 만들려면 콜론으로 구분된 여러 색상을 지정합니다.
예제
다음 표현식은 시리즈 색상을 파란색으로 설정합니다.
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date).color(#1E88E5)
{% include copy.html %}
.legend()
범례의 위치와 스타일을 설정합니다. 다음 표는 .legend() 함수 매개변수를 나열합니다.
| 매개변수 | 유형 | 설명 |
|---|---|---|
position |
String 또는 Boolean | 범례를 배치할 모서리: nw, ne, se 또는 sw. false로 설정하면 범례를 비활성화합니다. |
columns |
Number | 범례를 나눌 열 수입니다. |
showTime |
Boolean | true로 설정하면 그래프 위로 마우스를 가져갈 때 범례에 시간 값을 표시합니다. 기본값은 true입니다. |
timeFormat |
String | moment.js 형식 패턴입니다. 기본값은 MMMM Do YYYY, HH:mm:ss.SSS입니다. |
.title()
플롯 상단에 제목을 추가합니다. 둘 이상의 시리즈에서 호출되면 마지막 호출이 사용됩니다. 다음 표는 .title() 함수 매개변수를 나열합니다.
| 매개변수 | 유형 | 설명 |
|---|---|---|
title |
String | 플롯의 제목입니다. |
.hide()
기본적으로 시리즈를 숨깁니다. 시리즈는 여전히 범례에서 사용할 수 있으며 켜고 끌 수 있습니다. 다음 표는 .hide() 함수 매개변수를 나열합니다.
| 매개변수 | 유형 | 설명 |
|---|---|---|
hide |
Boolean | true로 설정하면 시리즈를 숨깁니다. 기본값은 true입니다. |
Y축 구성
하나 이상의 y축을 구성하여 배율, 위치 및 형식을 제어할 수 있습니다.
.yaxis()
y축 옵션을 구성합니다. .yaxis(2)를 사용하여 보조 y축에 시리즈를 플롯합니다. 다음 표는 .yaxis() 함수 매개변수를 나열합니다.
| 매개변수 | 유형 | 설명 |
|---|---|---|
yaxis |
Number | 이 시리즈를 플롯할 번호가 매겨진 y축입니다. 예: 보조 y축의 경우 2. |
min |
Number | 최소값입니다. |
max |
Number | 최대값입니다. |
position |
String | 축 위치: left 또는 right. |
label |
String | 축의 레이블입니다. |
color |
String | 축 레이블의 색상입니다. |
units |
String | y축 레이블의 형식입니다. bits, bits/s, bytes, bytes/s, currency(:ISO 4217 코드), percent 또는 custom(:prefix:suffix) 중 하나입니다. |
tickDecimals |
Number | y축 눈금 레이블의 소수 자릿수입니다. |
예제
다음 표현식은 수익을 왼쪽 y축에 막대로 표시하고 주문 수를 오른쪽 y축에 선으로 표시합니다.
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date, metric=sum:taxful_total_price).label("Total Revenue").bars(width=2),
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date).label("Order Count").lines(fill=1, width=1).yaxis(2)
{% include copy.html %}
다음 이미지는 수익을 막대로, 주문 수를 선으로 표시하는 이중 y축 시각화를 보여줍니다.
{: width="700" }
데이터 변환 함수
데이터 변환 함수는 시계열 데이터를 수정, 평활화 또는 분석해요.
.movingaverage()
주어진 윈도우에 대해 이동 평균을 계산해요. 이 함수를 사용하여 노이즈가 많은 시계열을 평활화해요. 별칭: .mvavg(). 다음 표는 .movingaverage() 함수의 매개변수를 나열해요.
| 매개변수 | 유형 | 설명 |
|---|---|---|
window |
Number or String | 평균을 계산할 포인트 수 또는 날짜 수학 표현식(예: 1d 또는 1M)이에요. |
position |
String | 결과 시간을 기준으로 평균화된 포인트의 위치예요. left, right 또는 center 중 하나예요. |
예시
다음 표현식은 일일 수익에 7일 이동 평균을 오버레이해요.
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date, metric=sum:taxful_total_price).label("Daily Revenue"),
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date, metric=sum:taxful_total_price).movingaverage(window=7).label("7-Day Moving Average").color(#F04E37).lines(width=3)
{% include copy.html %}
다음 이미지는 7일 이동 평균 오버레이가 있는 일일 수익을 보여줘요.
{: width="700" }
.movingstd()
주어진 윈도우에 대해 이동 표준 편차를 계산해요. 별칭: .mvstd(). 다음 표는 .movingstd() 함수의 매개변수를 나열해요.
| 매개변수 | 유형 | 설명 |
|---|---|---|
window |
Number | 표준 편차를 계산할 포인트 수예요. |
position |
String | 결과 시간을 기준으로 윈도우 슬라이스의 위치예요. left, right 또는 center 중 하나예요. 기본값은 left예요. |
예시
다음 표현식은 5포인트 이동 표준 편차를 계산해요.
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date).movingstd(window=5).label("5-Point Std Dev")
{% include copy.html %}
.derivative()
시간에 따른 값의 변화를 플롯해요.
예시
다음 표현식은 시간에 따른 주문 수의 변화를 플롯해요.
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date).derivative().label("Change in Order Count")
{% include copy.html %}
.trend()
지정된 회귀 알고리즘을 사용하여 추세선을 그려요. 다음 표는 .trend() 함수의 매개변수를 나열해요.
| 매개변수 | 유형 | 설명 |
|---|---|---|
mode |
String | 사용할 알고리즘이에요. linear 또는 log 중 하나예요. |
start |
Number | 계산을 시작할 위치예요. 음수 값은 끝에서부터 계산해요. 기본값은 0이에요. |
end |
Number | 계산을 중지할 위치예요. 음수 값은 끝에서부터 계산해요. 기본값은 0이에요. |
예시
다음 표현식은 주문 수에 선형 추세선을 오버레이해요.
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date).label("Order Count"),
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date).trend(mode=linear).label("Trend").color(#E53935)
{% include copy.html %}
.cusum()
시리즈의 누적 합계를 기본값에서 시작하여 반환해요. 다음 표는 .cusum() 함수의 매개변수를 나열해요.
| 매개변수 | 유형 | 설명 |
|---|---|---|
base |
Number | 시작할 숫자예요. 이 값은 시리즈의 시작 부분에 추가돼요. |
.fit()
정의된 피트 함수를 사용하여 null 값을 채워요. 다음 표는 .fit() 함수의 매개변수를 나열해요.
| 매개변수 | 유형 | 설명 |
|---|---|---|
mode |
String | 사용할 알고리즘이에요. average, carry, nearest, none 또는 scale 중 하나예요. |
.trim()
시리즈의 시작 또는 끝에 있는 N개의 버킷을 null로 설정해요. 이 함수를 사용하여 부분 버킷 문제를 해결해요. 다음 표는 .trim() 함수의 매개변수를 나열해요.
| 매개변수 | 유형 | 설명 |
|---|---|---|
start |
Number | 처음부터 트림할 버킷 수예요. 기본값은 1이에요. |
end |
Number | 끝에서 트림할 버킷 수예요. 기본값은 1이에요. |
수학 함수
Timeline은 시리즈를 결합하거나 변환하기 위해 다음 수학 함수를 지원해요. 수학 함수는 인수로 숫자 또는 다른 시리즈를 받아요.
| 함수 | 설명 |
|---|---|
.add() (별칭: .plus(), .sum()) |
입력 시리즈의 각 위치에 하나 이상의 시리즈 값을 더해요. |
.subtract() |
입력 시리즈의 각 위치에서 하나 이상의 시리즈 값을 빼요. |
.multiply() |
입력 시리즈의 각 위치에서 하나 이상의 시리즈 값을 곱해요. |
.divide() |
입력 시리즈의 각 위치에서 하나 이상의 시리즈 값을 나눠요. |
.abs() |
시리즈의 각 값의 절대값을 반환해요. |
.log() |
각 값의 로그를 반환해요 (기본 밑: 10). |
.min() |
현재 시리즈와 제공된 시리즈 또는 숫자 사이의 각 위치에서 최소값을 반환해요. |
.max() |
현재 시리즈와 제공된 시리즈 또는 숫자 사이의 각 위치에서 최대값을 반환해요. |
.precision() |
값의 소수 부분을 지정된 자릿수로 잘라요. |
.scale_interval() |
값(보통 합계 또는 개수)을 새 간격으로 조정해요, 예를 들어 초당 비율로요. |
.range() |
시리즈의 최대값과 최소값을 변경하지만 동일한 모양을 유지해요. |
예시
다음 표현식은 총 수익을 주문 수로 나누어 주문당 수익을 계산해요.
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date, metric=sum:taxful_total_price).divide(value=.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date)).label("Revenue per Order")
{% include copy.html %}
조건 함수
조건 함수를 사용하여 비교 논리에 따라 값을 설정해요.
.condition()
각 포인트를 연산자를 사용하여 숫자 또는 다른 시리즈의 동일한 포인트와 비교한 다음, 조건이 참이면 값을 결과로 설정해요. else가 생략되면 조건을 충족하지 않는 포인트는 원래 값을 유지해요. 별칭: .if(). 다음 표는 .condition() 함수의 매개변수를 나열해요.
| 매개변수 | 유형 | 설명 |
|---|---|---|
operator |
String | 비교 연산자: eq, ne, lt, lte, gt 또는 gte. |
if |
Number or SeriesList | 각 포인트를 비교할 값이에요. |
then |
Number or SeriesList | 비교가 참일 경우 설정할 값이에요. |
else |
Number or SeriesList | 비교가 거짓일 경우 설정할 값이에요. |
예시
다음 표현식은 값을 150으로 제한하고 낮은 값은 0으로 설정해요.
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date).condition(operator=gte, if=150, then=150, else=0).label("Days Meeting Target")
{% include copy.html %}
정적 값
정적 값을 사용하여 차트에 대상 또는 임계값과 같은 참조선을 그려요.
.static()
단일 값을 차트 전체에 수평선으로 그려요. 별칭: .value(). 다음 표는 .static() 함수의 매개변수를 나열해요.
| 매개변수 | 유형 | 설명 |
|---|---|---|
value |
Number or String | 표시할 단일 값이에요. 여러 값을 전달하여 시간 범위에 걸쳐 균등하게 보간할 수 있어요. |
label |
String | 시리즈의 레이블이에요. |
offset |
String | 날짜 표현식으로 시리즈 검색을 오프셋해요. |
fit |
String | 피팅에 사용할 알고리즘이에요. average, carry, nearest, none 또는 scale 중 하나예요. |
예시
다음 표현식은 150개 주문에 대상선을 추가해요.
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date).label("Order Count").lines(fill=2, width=1),
.static(value=150, label="Target").color(#E53935).lines(width=2)
{% include copy.html %}
다음 이미지는 150개 주문의 정적 대상선이 있는 주문 수를 보여줘요.
{: width="700" }
집계 함수
집계 함수를 사용하여 시리즈를 단일 값으로 줄이고 수평선으로 표시해요.
.aggregate()
시리즈의 모든 포인트를 처리한 결과를 기반으로 정적선을 만들어요. 다음 표는 .aggregate() 함수의 매개변수를 나열해요.
| 매개변수 | 유형 | 설명 |
|---|---|---|
function |
String | avg, cardinality, min, max, last, first 또는 sum 중 하나예요. |
예시
다음 표현식은 주문 수를 평균값으로 수평선과 함께 표시해요.
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date).label("Order Count"),
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date).aggregate(function=avg).label("Average").color(#E53935)
{% include copy.html %}
예측 함수
예측 함수를 사용하여 시리즈의 과거 패턴을 기반으로 미래 값을 예측해요.
.holt()
시리즈의 시작 부분을 샘플링하고 Holt-Winters 삼중 지수 평활화를 사용하여 미래 값을 예측해요. 이 함수를 이상 탐지에 사용해요. Null 값은 예측된 값으로 채워져요. 다음 표는 .holt() 함수의 매개변수를 나열해요.
| 매개변수 | 유형 | 설명 |
|---|---|---|
alpha |
Number | 0에서 1 사이의 평활화 가중치예요. 값이 높을수록 시리즈가 원본을 더 밀접하게 따라요. |
beta |
Number | 0에서 1 사이의 추세 가중치예요. 값이 높을수록 상승 또는 하락선이 더 오래 지속돼요. |
gamma |
Number | 0에서 1 사이의 계절성 가중치예요. 값이 높을수록 최근 계절에 더 중요성을 부여해요. |
season |
String | 계절 길이예요, 예를 들어 주간 패턴의 경우 1w예요. gamma와 함께만 유용해요. |
sample |
Number | 예측 전에 샘플링할 계절 수예요. gamma와 함께만 유용해요. 기본값은 모두예요. |
예시
다음 표현식은 Holt-Winters 평활화를 사용하여 주문 수를 예측해요.
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date).label("Actual"),
.opensearch(index=opensearch_dashboards_sample_data_ecommerce, timefield=order_date).holt(alpha=0.5, beta=0.5).label("Forecast").color(#E53935)
{% include copy.html %}