資料彙整流程

Fig-1: Pata Preparation

Fig-1: Pata Preparation


1. 交易項目計錄:Z

rm(list=ls(all=T))
Sys.setlocale("LC_ALL","C")
[1] "C"
library(dplyr)
library(ggplot2)
library(caTools)
1.1 The do.call-rbind-lapply Combo
Z = do.call(rbind, lapply(
    dir('data/TaFengDataSet','.*csv$',full.names=T),
    read.csv, header=F) 
  ) %>% 
  setNames(c("date","cust","age","area","cat","prod","qty","cost","price"))
Z
Data Convresion
Z$date = as.Date(as.character(Z$date))
summary(Z)
      date                 cust               age        
 Min.   :2000-11-01   Min.   :    1069   D      :181213  
 1st Qu.:2000-11-28   1st Qu.:  969222   E      :151023  
 Median :2001-01-01   Median : 1587722   C      :140805  
 Mean   :2000-12-30   Mean   : 1406620   F      : 99719  
 3rd Qu.:2001-01-30   3rd Qu.: 1854930   B      : 66432  
 Max.   :2001-02-28   Max.   :20002000   G      : 53719  
                                         (Other):124830  
      area             cat              prod              
 E      :312501   Min.   :100101   Min.   :     20008819  
 F      :245213   1st Qu.:110106   1st Qu.:4710085127020  
 G      : 72092   Median :130106   Median :4710421090060  
 C      : 71640   Mean   :284950   Mean   :4461639280530  
 H      : 40666   3rd Qu.:520314   3rd Qu.:4712500125130  
 D      : 38674   Max.   :780510   Max.   :9789579967620  
 (Other): 36955                                           
      qty              cost            price       
 Min.   :   1.0   Min.   :     0   Min.   :     1  
 1st Qu.:   1.0   1st Qu.:    35   1st Qu.:    42  
 Median :   1.0   Median :    62   Median :    76  
 Mean   :   1.4   Mean   :   112   Mean   :   132  
 3rd Qu.:   1.0   3rd Qu.:   112   3rd Qu.:   132  
 Max.   :1200.0   Max.   :432000   Max.   :444000  
                                                   
Quantile of Variables
sapply(Z[,7:9], quantile, prob=c(.99, .999, .9995))
       qty cost price
99%      6  858  1014
99.9%   14 2722  3136
99.95%  24 3799  3999
Get rid of Outliers
Z = subset(Z, qty<=24 & cost<=3800 & price<=4000) 
nrow(Z)  
[1] 817182
Assign Transaction ID
#為一筆交易產生id
Z$tid = group_indices(Z, date, cust)
Z
No. Customers, Categories, Product Items & Transactions
sapply(Z[,c("cust","cat","prod","tid")], n_distinct)
  cust    cat   prod    tid 
 32256   2007  23789 119422 
Summary of Item Records
summary(Z)
      date                 cust               age        
 Min.   :2000-11-01   Min.   :    1069   D      :181089  
 1st Qu.:2000-11-28   1st Qu.:  968775   E      :150947  
 Median :2001-01-01   Median : 1587685   C      :140721  
 Mean   :2000-12-30   Mean   : 1406500   F      : 99641  
 3rd Qu.:2001-01-30   3rd Qu.: 1854701   B      : 66353  
 Max.   :2001-02-28   Max.   :20002000   G      : 53689  
                                         (Other):124742  
      area             cat              prod              
 E      :312358   Min.   :100101   Min.   :     20008819  
 F      :245079   1st Qu.:110106   1st Qu.:4710085127020  
 G      : 71905   Median :130106   Median :4710421090060  
 C      : 71600   Mean   :284784   Mean   :4461978778400  
 H      : 40647   3rd Qu.:520311   3rd Qu.:4712500125130  
 D      : 38654   Max.   :780510   Max.   :9789579967620  
 (Other): 36939                                           
      qty             cost          price           tid        
 Min.   : 1.00   Min.   :   0   Min.   :   1   Min.   :     1  
 1st Qu.: 1.00   1st Qu.:  35   1st Qu.:  42   1st Qu.: 28783  
 Median : 1.00   Median :  62   Median :  76   Median : 59391  
 Mean   : 1.36   Mean   : 106   Mean   : 126   Mean   : 58845  
 3rd Qu.: 1.00   3rd Qu.: 112   3rd Qu.: 132   3rd Qu.: 87391  
 Max.   :24.00   Max.   :3798   Max.   :4000   Max.   :119422  
                                                               


2. 交易計錄:X

交易資料彙整
X = group_by(Z, tid) %>% summarise(
  date = first(date),  # 交易日期
  cust = first(cust),  # 顧客 ID
  age = first(age),    # 顧客 年齡級別
  area = first(area),  # 顧客 居住區別
  items = n(),                # 交易項目(總)數
  pieces = sum(qty),          # 產品(總)件數
  total = sum(price),         # 交易(總)金額
  gross = sum(price - cost)   # 毛利
  ) %>% data.frame  # 119422
X
交易摘要
summary(X)    
      tid              date                 cust         
 Min.   :     1   Min.   :2000-11-01   Min.   :    1069  
 1st Qu.: 29856   1st Qu.:2000-11-29   1st Qu.:  927093  
 Median : 59712   Median :2001-01-01   Median : 1615661  
 Mean   : 59712   Mean   :2000-12-31   Mean   : 1402548  
 3rd Qu.: 89567   3rd Qu.:2001-02-02   3rd Qu.: 1894493  
 Max.   :119422   Max.   :2001-02-28   Max.   :20002000  
                                                         
      age             area           items            pieces     
 D      :23775   E      :50532   Min.   :  1.00   Min.   :  1.0  
 C      :19661   F      :33826   1st Qu.:  2.00   1st Qu.:  3.0  
 E      :19596   G      : 9498   Median :  5.00   Median :  6.0  
 F      :13992   C      : 8527   Mean   :  6.84   Mean   :  9.3  
 B      :10515   H      : 7502   3rd Qu.:  9.00   3rd Qu.: 12.0  
 G      : 8493   D      : 5108   Max.   :112.00   Max.   :339.0  
 (Other):23390   (Other): 4429                                   
     total           gross      
 Min.   :    5   Min.   :-1645  
 1st Qu.:  227   1st Qu.:   21  
 Median :  510   Median :   68  
 Mean   :  859   Mean   :  132  
 3rd Qu.: 1082   3rd Qu.:  169  
 Max.   :30171   Max.   : 8069  
                                
Check Quantile & Remove Outliers
sapply(X[,6:9], quantile, prob=c(.999, .9995, .9999))
       items pieces total gross
99.9%     54  81.00  9010  1825
99.95%    62  94.29 10612  2180
99.99%    82 133.00 16044  3227
X = subset(X, items<=62 & pieces<95 & total<16000) # 119328
Weekly Transactions
par(cex=0.8)
hist(X$date, "weeks", freq=T, border='lightgray', col='darkcyan', 
     las=2, main="No. Transaction per Week")



3. 顧客資料:A

顧客資料彙整
#r:顧客最後一次消費距離今日
#S:顧客最近一次消費距離今日
d0 = max(X$date)
A = group_by(X, cust) %>% summarise(
  r = 1 + as.integer(difftime(d0, max(date), units="days")), # recency
  s = 1 + as.integer(difftime(d0, min(date), units="days")), # seniority
  f = n(),            # frquency
  m = mean(total),    # monetary
  rev = sum(total),   # total revenue contribution
  raw = sum(gross),   # total gross profit contribution
  age = first(age),   # age group
  area = first(area) # area code
  ) %>% data.frame    # 33241
A
顧客摘要
summary(A) 
      cust                r               s               f       
 Min.   :    1069   Min.   :  1.0   Min.   :  1.0   Min.   : 1.0  
 1st Qu.: 1088519   1st Qu.:  9.0   1st Qu.: 56.0   1st Qu.: 1.0  
 Median : 1663402   Median : 26.0   Median : 92.0   Median : 2.0  
 Mean   : 1473585   Mean   : 37.5   Mean   : 80.8   Mean   : 3.7  
 3rd Qu.: 1958089   3rd Qu.: 60.0   3rd Qu.:110.0   3rd Qu.: 4.0  
 Max.   :20002000   Max.   :120.0   Max.   :120.0   Max.   :85.0  
                                                                  
       m              rev              raw             age      
 Min.   :    8   Min.   :     8   Min.   : -784   D      :6580  
 1st Qu.:  365   1st Qu.:   707   1st Qu.:   75   C      :5915  
 Median :  706   Median :  1750   Median :  241   E      :5080  
 Mean   :  993   Mean   :  3152   Mean   :  485   F      :3719  
 3rd Qu.: 1291   3rd Qu.:  3968   3rd Qu.:  612   B      :3193  
 Max.   :12636   Max.   :127686   Max.   :20273   G      :2183  
                                                  (Other):5571  
      area      
 E      :10800  
 F      : 8539  
 G      : 3695  
 C      : 3683  
 D      : 2166  
 H      : 1453  
 (Other): 1905  
par(mfrow=c(3,2), mar=c(3,3,4,2))
for(x in c('r','s','f','m')) 
  hist(A[,x],freq=T,main=x,xlab="",ylab="",cex.main=2)
hist(pmin(A$f,10),0:10,freq=T,xlab="",ylab="",cex.main=2)
hist(log(A$m,10),freq=T,xlab="",ylab="",cex.main=2)

Duplicate & Save
A0 = A; X0 = X; Z0 = Z
save(Z0, X0, A0, file="data/tf0.rdata")


4. Objective of the Contest

range(X$date)
[1] "2000-11-01" "2001-02-28"

使用一月底(含2001-01-31)以前的資料,建立模型來預測每一位顧客:

  1. 她在2月份(2001-02-01 ~ 2001-02-28)會不會來買?
  2. 如果她來買的話,會買多少錢?


The Basic Questions of Analysis

【Q】 What are the Unit of Analysis?

【Q】 What are the Target of Analysis? Should we model for every customers in the dataset? Why not?

【Q】 How to make the Training/Testing Data Split?

【Q】 What are the Predicting and Targeted Variables?

The Target of Analysis

Screen out the new customers (who arrive after 2001-02-01)

A = filter(A0, s > 28)  # 28584
The Baseline Probability
mean(A$r <= 28)
[1] 0.4633
Spliting Factor and Spliting Ratio
library(caTools)
set.seed(1234); spl = sample.split(A$r <= 28, SplitRatio=0.75)
cid1 = subset(A, spl)$cust    # 21438
cid2 = subset(A, !spl)$cust   # 7146

cid1/cid2 are the customers ids in the training/testing data. But, …

【Q】 What are the Predicting (X) and Targeted Variables (Y)?









LS0tDQp0aXRsZTogIlRoZSBUYS1GZW5nIERhdGFzZXQiDQphdXRob3I6ICLlionogrLpipgsIOS4reWxseWkp+WtuCDos4fnrqHmiYAiDQpkYXRlOiAiYHIgU3lzLnRpbWUoKWAiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQo8YnI+DQoNCiMjIyDos4fmlpnlvZnmlbTmtYHnqIsNCg0KPGNlbnRlcj4NCg0KIVtGaWctMTogUGF0YSBQcmVwYXJhdGlvbl0oZmlnL2FnZ3JlZ2F0aW9uLmpwZykNCg0KPC9jZW50ZXI+DQoNCjxocj4NCg0KIyMjIDEuIOS6pOaYk+mgheebruioiOmMhO+8mmBaYA0KDQpgYGB7ciBlY2hvPVQsIG1lc3NhZ2U9RiwgY2FjaGU9Riwgd2FybmluZz1GfQ0Kcm0obGlzdD1scyhhbGw9VCkpDQpTeXMuc2V0bG9jYWxlKCJMQ19BTEwiLCJDIikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGNhVG9vbHMpDQpgYGANCg0KIyMjIyMgMS4xIFRoZSBgZG8uY2FsbC1yYmluZC1sYXBwbHlgIENvbWJvDQpgYGB7cn0NClogPSBkby5jYWxsKHJiaW5kLCBsYXBwbHkoDQogICAgZGlyKCdkYXRhL1RhRmVuZ0RhdGFTZXQnLCcuKmNzdiQnLGZ1bGwubmFtZXM9VCksDQogICAgcmVhZC5jc3YsIGhlYWRlcj1GKSANCiAgKSAlPiUgDQogIHNldE5hbWVzKGMoImRhdGUiLCJjdXN0IiwiYWdlIiwiYXJlYSIsImNhdCIsInByb2QiLCJxdHkiLCJjb3N0IiwicHJpY2UiKSkNCloNCmBgYA0KDQojIyMjIyBEYXRhIENvbnZyZXNpb24NCmBgYHtyfQ0KWiRkYXRlID0gYXMuRGF0ZShhcy5jaGFyYWN0ZXIoWiRkYXRlKSkNCnN1bW1hcnkoWikNCmBgYA0KDQojIyMjIyBRdWFudGlsZSBvZiBWYXJpYWJsZXMNCmBgYHtyfQ0Kc2FwcGx5KFpbLDc6OV0sIHF1YW50aWxlLCBwcm9iPWMoLjk5LCAuOTk5LCAuOTk5NSkpDQpgYGANCg0KIyMjIyMgR2V0IHJpZCBvZiBPdXRsaWVycw0KYGBge3J9DQpaID0gc3Vic2V0KFosIHF0eTw9MjQgJiBjb3N0PD0zODAwICYgcHJpY2U8PTQwMDApIA0KbnJvdyhaKSAgDQpgYGANCg0KIyMjIyMgQXNzaWduIFRyYW5zYWN0aW9uIElEDQpgYGB7cn0NCiPngrrkuIDnrYbkuqTmmJPnlKLnlJ9pZA0KWiR0aWQgPSBncm91cF9pbmRpY2VzKFosIGRhdGUsIGN1c3QpDQpaDQpgYGANCg0KIyMjIyMgTm8uIEN1c3RvbWVycywgQ2F0ZWdvcmllcywgUHJvZHVjdCBJdGVtcyAmIFRyYW5zYWN0aW9ucw0KYGBge3J9DQpzYXBwbHkoWlssYygiY3VzdCIsImNhdCIsInByb2QiLCJ0aWQiKV0sIG5fZGlzdGluY3QpDQpgYGANCg0KIyMjIyMgU3VtbWFyeSBvZiBJdGVtIFJlY29yZHMNCmBgYHtyfQ0Kc3VtbWFyeShaKQ0KYGBgDQo8YnI+PGhyPg0KDQoNCg0KIyMjIDIuIOS6pOaYk+ioiOmMhO+8mmBYYA0KDQojIyMjIyDkuqTmmJPos4fmlpnlvZnmlbQNCmBgYHtyfQ0KWCA9IGdyb3VwX2J5KFosIHRpZCkgJT4lIHN1bW1hcmlzZSgNCiAgZGF0ZSA9IGZpcnN0KGRhdGUpLCAgIyDkuqTmmJPml6XmnJ8NCiAgY3VzdCA9IGZpcnN0KGN1c3QpLCAgIyDpoaflrqIgSUQNCiAgYWdlID0gZmlyc3QoYWdlKSwgICAgIyDpoaflrqIg5bm06b2h57Sa5YilDQogIGFyZWEgPSBmaXJzdChhcmVhKSwgICMg6aGn5a6iIOWxheS9j+WNgOWIpQ0KICBpdGVtcyA9IG4oKSwgICAgICAgICAgICAgICAgIyDkuqTmmJPpoIXnm64o57i9KeaVuA0KICBwaWVjZXMgPSBzdW0ocXR5KSwgICAgICAgICAgIyDnlKLlk4Eo57i9KeS7tuaVuA0KICB0b3RhbCA9IHN1bShwcmljZSksICAgICAgICAgIyDkuqTmmJMo57i9KemHkemhjQ0KICBncm9zcyA9IHN1bShwcmljZSAtIGNvc3QpICAgIyDmr5vliKkNCiAgKSAlPiUgZGF0YS5mcmFtZSAgIyAxMTk0MjINCg0KWA0KYGBgDQoNCiMjIyMjIOS6pOaYk+aRmOimgQ0KYGBge3J9DQpzdW1tYXJ5KFgpICAgIA0KYGBgDQoNCiMjIyMjIENoZWNrIFF1YW50aWxlICYgUmVtb3ZlIE91dGxpZXJzDQpgYGB7cn0NCnNhcHBseShYWyw2OjldLCBxdWFudGlsZSwgcHJvYj1jKC45OTksIC45OTk1LCAuOTk5OSkpDQpgYGANCg0KYGBge3J9DQpYID0gc3Vic2V0KFgsIGl0ZW1zPD02MiAmIHBpZWNlczw5NSAmIHRvdGFsPDE2MDAwKSAjIDExOTMyOA0KYGBgDQoNCiMjIyMjIFdlZWtseSBUcmFuc2FjdGlvbnMNCmBgYHtyIGZpZy5oZWlnaHQ9MywgZmlnLndpZHRoPTd9DQpwYXIoY2V4PTAuOCkNCmhpc3QoWCRkYXRlLCAid2Vla3MiLCBmcmVxPVQsIGJvcmRlcj0nbGlnaHRncmF5JywgY29sPSdkYXJrY3lhbicsIA0KICAgICBsYXM9MiwgbWFpbj0iTm8uIFRyYW5zYWN0aW9uIHBlciBXZWVrIikNCmBgYA0KPGJyPjxocj4NCg0KDQoNCiMjIyAzLiDpoaflrqLos4fmlpnvvJpgQWANCg0KIyMjIyMg6aGn5a6i6LOH5paZ5b2Z5pW0DQpgYGB7cn0NCiNyOumhp+WuouacgOW+jOS4gOasoea2iOiyu+i3nembouS7iuaXpQ0KI1M66aGn5a6i5pyA6L+R5LiA5qyh5raI6LK76Led6Zui5LuK5pelDQpkMCA9IG1heChYJGRhdGUpDQpBID0gZ3JvdXBfYnkoWCwgY3VzdCkgJT4lIHN1bW1hcmlzZSgNCiAgciA9IDEgKyBhcy5pbnRlZ2VyKGRpZmZ0aW1lKGQwLCBtYXgoZGF0ZSksIHVuaXRzPSJkYXlzIikpLCAjIHJlY2VuY3kNCiAgcyA9IDEgKyBhcy5pbnRlZ2VyKGRpZmZ0aW1lKGQwLCBtaW4oZGF0ZSksIHVuaXRzPSJkYXlzIikpLCAjIHNlbmlvcml0eQ0KICBmID0gbigpLCAgICAgICAgICAgICMgZnJxdWVuY3kNCiAgbSA9IG1lYW4odG90YWwpLCAgICAjIG1vbmV0YXJ5DQogIHJldiA9IHN1bSh0b3RhbCksICAgIyB0b3RhbCByZXZlbnVlIGNvbnRyaWJ1dGlvbg0KICByYXcgPSBzdW0oZ3Jvc3MpLCAgICMgdG90YWwgZ3Jvc3MgcHJvZml0IGNvbnRyaWJ1dGlvbg0KICBhZ2UgPSBmaXJzdChhZ2UpLCAgICMgYWdlIGdyb3VwDQogIGFyZWEgPSBmaXJzdChhcmVhKSAjIGFyZWEgY29kZQ0KICApICU+JSBkYXRhLmZyYW1lICAgICMgMzMyNDENCkENCmBgYA0KDQojIyMjIyDpoaflrqLmkZjopoENCmBgYHtyfQ0Kc3VtbWFyeShBKSANCmBgYA0KDQpgYGB7ciBmaWcuaGVpZ2h0PTh9DQpwYXIobWZyb3c9YygzLDIpLCBtYXI9YygzLDMsNCwyKSkNCmZvcih4IGluIGMoJ3InLCdzJywnZicsJ20nKSkgDQogIGhpc3QoQVsseF0sZnJlcT1ULG1haW49eCx4bGFiPSIiLHlsYWI9IiIsY2V4Lm1haW49MikNCmhpc3QocG1pbihBJGYsMTApLDA6MTAsZnJlcT1ULHhsYWI9IiIseWxhYj0iIixjZXgubWFpbj0yKQ0KaGlzdChsb2coQSRtLDEwKSxmcmVxPVQseGxhYj0iIix5bGFiPSIiLGNleC5tYWluPTIpDQpgYGANCg0KIyMjIyMgRHVwbGljYXRlICYgU2F2ZQ0KYGBge3J9DQpBMCA9IEE7IFgwID0gWDsgWjAgPSBaDQpzYXZlKFowLCBYMCwgQTAsIGZpbGU9ImRhdGEvdGYwLnJkYXRhIikNCmBgYA0KPGJyPjxocj4NCg0KDQoNCiMjIyA0LiBPYmplY3RpdmUgb2YgdGhlIENvbnRlc3QgDQoNCmBgYHtyfQ0KcmFuZ2UoWCRkYXRlKQ0KYGBgDQoNCioq5L2/55So5LiA5pyI5bqVKOWQqzIwMDEtMDEtMzEp5Lul5YmN55qE6LOH5paZ77yM5bu656uL5qih5Z6L5L6G6aCQ5ris5q+P5LiA5L2N6aGn5a6i77yaKioNCg0KYS4gKirlpbnlnKgy5pyI5Lu9KDIwMDEtMDItMDEgfiAyMDAxLTAyLTI4Keacg+S4jeacg+S+huiyt++8nyoqDQpiLiAqKuWmguaenOWlueS+huiyt+eahOipse+8jOacg+iyt+WkmuWwkemMou+8nyoqDQoNCjxicj4NCg0KIyMjIyMgVGhlIEJhc2ljIFF1ZXN0aW9ucyBvZiBBbmFseXNpcw0KDQoqKuOAkFHjgJEqKiBfV2hhdCBhcmUgdGhlIFVuaXQgb2YgQW5hbHlzaXM/XyANCg0KKw0KKw0KDQoqKuOAkFHjgJEqKiBfV2hhdCBhcmUgdGhlIFRhcmdldCBvZiBBbmFseXNpcz9fIA0KX1Nob3VsZCB3ZSBtb2RlbCBmb3IgZXZlcnkgY3VzdG9tZXJzIGluIHRoZSBkYXRhc2V0P18gDQpfV2h5IG5vdD9fDQoNCisNCisNCg0KKirjgJBR44CRKiogX0hvdyB0byBtYWtlIHRoZSBUcmFpbmluZy9UZXN0aW5nIERhdGEgU3BsaXQ/Xw0KDQorDQorDQoNCioq44CQUeOAkSoqIF9XaGF0IGFyZSB0aGUgUHJlZGljdGluZyBhbmQgVGFyZ2V0ZWQgVmFyaWFibGVzP18NCg0KKw0KKw0KDQojIyMjIyBUaGUgVGFyZ2V0IG9mIEFuYWx5c2lzDQoNCg0KU2NyZWVuIG91dCB0aGUgbmV3IGN1c3RvbWVycyAod2hvIGFycml2ZSBhZnRlciAyMDAxLTAyLTAxKQ0KYGBge3J9DQpBID0gZmlsdGVyKEEwLCBzID4gMjgpICAjIDI4NTg0DQpgYGANCg0KIyMjIyMgVGhlIEJhc2VsaW5lIFByb2JhYmlsaXR5DQpgYGB7cn0NCm1lYW4oQSRyIDw9IDI4KQ0KYGBgDQoNCiMjIyMjIFNwbGl0aW5nIEZhY3RvciBhbmQgU3BsaXRpbmcgUmF0aW8NCmBgYHtyfQ0KbGlicmFyeShjYVRvb2xzKQ0Kc2V0LnNlZWQoMTIzNCk7IHNwbCA9IHNhbXBsZS5zcGxpdChBJHIgPD0gMjgsIFNwbGl0UmF0aW89MC43NSkNCmNpZDEgPSBzdWJzZXQoQSwgc3BsKSRjdXN0ICAgICMgMjE0MzgNCmNpZDIgPSBzdWJzZXQoQSwgIXNwbCkkY3VzdCAgICMgNzE0Ng0KYGBgDQpgY2lkMWAvYGNpZDJgIGFyZSB0aGUgY3VzdG9tZXJzIGlkcyBpbiB0aGUgdHJhaW5pbmcvdGVzdGluZyBkYXRhLiBCdXQsIC4uLg0KDQoqKuOAkFHjgJEqKiBfV2hhdCBhcmUgdGhlIFByZWRpY3RpbmcgKFgpIGFuZCBUYXJnZXRlZCBWYXJpYWJsZXMgKFkpP18NCg0KKw0KKw0KDQo8YnI+PGJyPjxicj48YnI+PGhyPjxicj48YnI+PGJyPg0KDQo8c3R5bGU+DQoNCi5jYXB0aW9uIHsNCiAgY29sb3I6ICM3Nzc7DQogIG1hcmdpbi10b3A6IDEwcHg7DQp9DQpwIGNvZGUgew0KICB3aGl0ZS1zcGFjZTogaW5oZXJpdDsNCn0NCnByZSB7DQogIHdvcmQtYnJlYWs6IG5vcm1hbDsNCiAgd29yZC13cmFwOiBub3JtYWw7DQogIGxpbmUtaGVpZ2h0OiAxOw0KfQ0KcHJlIGNvZGUgew0KICB3aGl0ZS1zcGFjZTogaW5oZXJpdDsNCn0NCnAsbGkgew0KICBmb250LWZhbWlseTogIlRyZWJ1Y2hldCBNUyIsICLlvq7ou5/mraPpu5Hpq5QiLCAiTWljcm9zb2Z0IEpoZW5nSGVpIjsNCn0NCg0KLnJ7DQogIGxpbmUtaGVpZ2h0OiAxLjI7DQp9DQoNCi5xaXogew0KICBsaW5lLWhlaWdodDogMS43NTsNCiAgYmFja2dyb3VuZDogI2YwZjBmMDsNCiAgYm9yZGVyLWxlZnQ6IDEycHggc29saWQgI2NjZmZjYzsNCiAgcGFkZGluZzogNHB4Ow0KICBwYWRkaW5nLWxlZnQ6IDEwcHg7DQogIGNvbG9yOiAjMDA5OTAwOw0KfQ0KDQp0aXRsZXsNCiAgY29sb3I6ICNjYzAwMDA7DQogIGZvbnQtZmFtaWx5OiAiVHJlYnVjaGV0IE1TIiwgIuW+rui7n+ato+m7kemrlCIsICJNaWNyb3NvZnQgSmhlbmdIZWkiOw0KfQ0KDQpib2R5ew0KICBmb250LWZhbWlseTogIlRyZWJ1Y2hldCBNUyIsICLlvq7ou5/mraPpu5Hpq5QiLCAiTWljcm9zb2Z0IEpoZW5nSGVpIjsNCn0NCg0KaDEsaDIsaDMsaDQsaDV7DQogIGNvbG9yOiAjMDA2NmZmOw0KICBmb250LWZhbWlseTogIlRyZWJ1Y2hldCBNUyIsICLlvq7ou5/mraPpu5Hpq5QiLCAiTWljcm9zb2Z0IEpoZW5nSGVpIjsNCn0NCg0KDQpoM3sNCiAgY29sb3I6ICMwMDg4MDA7DQogIGJhY2tncm91bmQ6ICNlNmZmZTY7DQogIGxpbmUtaGVpZ2h0OiAyOw0KICBmb250LXdlaWdodDogYm9sZDsNCn0NCg0KaDV7DQogIGNvbG9yOiAjMDA2MDAwOw0KICBiYWNrZ3JvdW5kOiAjZjhmOGY4Ow0KICBsaW5lLWhlaWdodDogMS41Ow0KICBmb250LXdlaWdodDogYm9sZDsNCn0NCg0KPC9zdHlsZT4NCg0K