Commit c3947327 authored by Jerico Moeyersons's avatar Jerico Moeyersons 🏘
Browse files

Merge remote-tracking branch 'origin/2021'

parents d06719c2 b948144f
File added
......@@ -14,20 +14,30 @@
FROM golang:1.15-alpine as builder
RUN apk add --no-cache ca-certificates git
RUN apk add build-base
WORKDIR /src
# restore dependencies
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o /go/bin/frontend .
# Skaffold passes in debug-oriented compiler flags
ARG SKAFFOLD_GO_GCFLAGS
RUN go build -gcflags="${SKAFFOLD_GO_GCFLAGS}" -o /go/bin/frontend .
FROM alpine as release
RUN apk add --no-cache ca-certificates \
busybox-extras net-tools bind-tools
WORKDIR /frontend
COPY --from=builder /go/bin/frontend /frontend/server
WORKDIR /src
COPY --from=builder /go/bin/frontend /src/server
COPY ./templates ./templates
COPY ./static ./static
# Definition of this variable is used by 'skaffold debug' to identify a golang binary.
# Default behavior - a failure prints a stack trace for the current goroutine.
# See https://golang.org/pkg/runtime/
ENV GOTRACEBACK=single
EXPOSE 8080
ENTRYPOINT ["/frontend/server"]
ENTRYPOINT ["/src/server"]
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
annotations:
sidecar.istio.io/rewriteAppHTTPProbers: "true"
spec:
containers:
- name: server
image: gitlab.ilabt.imec.be:4567/lab-pds-microservices/frontend
ports:
- containerPort: 8080
readinessProbe:
initialDelaySeconds: 10
httpGet:
path: "/_healthz"
port: 8080
httpHeaders:
- name: "Cookie"
value: "shop_session-id=x-readiness-probe"
livenessProbe:
initialDelaySeconds: 10
httpGet:
path: "/_healthz"
port: 8080
httpHeaders:
- name: "Cookie"
value: "shop_session-id=x-liveness-probe"
env:
- name: PORT
value: "8080"
- name: PRODUCT_CATALOG_SERVICE_ADDR
value: "productcatalogservice:3550"
- name: CURRENCY_SERVICE_ADDR
value: "currencyservice:7000"
- name: CART_SERVICE_ADDR
value: "cartservice:7070"
- name: RECOMMENDATION_SERVICE_ADDR
value: "recommendationservice:8080"
- name: SHIPPING_SERVICE_ADDR
value: "shippingservice:50051"
- name: CHECKOUT_SERVICE_ADDR
value: "checkoutservice:5050"
- name: AD_SERVICE_ADDR
value: "adservice:9555"
- name: ENV_PLATFORM
value: "gcp"
- name: DISABLE_TRACING
value: "1"
- name: DISABLE_PROFILER
value: "1"
- name: JAEGER_SERVICE_ADDR
value: "jaeger-collector:14268"
resources:
requests:
cpu: 100m
memory: 64Mi
limits:
cpu: 200m
memory: 128Mi
---
apiVersion: v1
kind: Service
metadata:
name: frontend
spec:
type: ClusterIP
selector:
app: frontend
ports:
- name: http
port: 80
targetPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: frontend-external
spec:
type: LoadBalancer
selector:
app: frontend
ports:
- name: http
port: 80
targetPort: 8080
\ No newline at end of file
......@@ -14,8 +14,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#!/bin/bash -e
PATH=$PATH:$GOPATH/bin
protodir=../../pb
......
......@@ -381,7 +381,7 @@ type Product struct {
Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
Picture string `protobuf:"bytes,4,opt,name=picture,proto3" json:"picture,omitempty"`
PriceUsd *Money `protobuf:"bytes,5,opt,name=price_usd,json=priceUsd,proto3" json:"price_usd,omitempty"`
// Categories such as "vintage" or "gardening" that can be used to look up
// Categories such as "clothing" or "kitchen" that can be used to look up
// other related products.
Categories []string `protobuf:"bytes,6,rep,name=categories,proto3" json:"categories,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
......
......@@ -19,6 +19,7 @@ import (
"fmt"
"html/template"
"math/rand"
"net"
"net/http"
"os"
"strconv"
......@@ -39,13 +40,17 @@ type platformDetails struct {
}
var (
templates = template.Must(template.New("").
isCymbalBrand = "true" == strings.ToLower(os.Getenv("CYMBAL_BRANDING"))
templates = template.Must(template.New("").
Funcs(template.FuncMap{
"renderMoney": renderMoney,
"renderMoney": renderMoney,
"renderCurrencyLogo": renderCurrencyLogo,
}).ParseGlob("templates/*.html"))
plat platformDetails
)
var validEnvs = []string{"local", "gcp", "azure", "aws", "onprem", "alibaba"}
func (fe *frontendServer) homeHandler(w http.ResponseWriter, r *http.Request) {
log := r.Context().Value(ctxKeyLog{}).(logrus.FieldLogger)
log.WithField("currency", currentCurrency(r)).Info("home")
......@@ -79,23 +84,37 @@ func (fe *frontendServer) homeHandler(w http.ResponseWriter, r *http.Request) {
ps[i] = productView{p, price}
}
//get env and render correct platform banner.
// Set ENV_PLATFORM (default to local if not set; use env var if set; otherwise detect GCP, which overrides env)_
var env = os.Getenv("ENV_PLATFORM")
// Only override from env variable if set + valid env
if env == "" || stringinSlice(validEnvs, env) == false {
fmt.Println("env platform is either empty or invalid")
env = "local"
}
// Autodetect GCP
addrs, err := net.LookupHost("metadata.google.internal.")
if err == nil && len(addrs) >= 0 {
log.Debugf("Detected Google metadata server: %v, setting ENV_PLATFORM to GCP.", addrs)
env = "gcp"
}
log.Debugf("ENV_PLATFORM is: %s", env)
plat = platformDetails{}
plat.setPlatformDetails(strings.ToLower(env))
if err := templates.ExecuteTemplate(w, "home", map[string]interface{}{
"session_id": sessionID(r),
"request_id": r.Context().Value(ctxKeyRequestID{}),
"user_currency": currentCurrency(r),
"show_currency": true,
"currencies": currencies,
"products": ps,
"cart_size": cartSize(cart),
"banner_color": os.Getenv("BANNER_COLOR"), // illustrates canary deployments
"ad": fe.chooseAd(r.Context(), []string{}, log),
"platform_css": plat.css,
"platform_name": plat.provider,
"session_id": sessionID(r),
"request_id": r.Context().Value(ctxKeyRequestID{}),
"user_currency": currentCurrency(r),
"show_currency": true,
"currencies": currencies,
"products": ps,
"cart_size": cartSize(cart),
"banner_color": os.Getenv("BANNER_COLOR"), // illustrates canary deployments
"ad": fe.chooseAd(r.Context(), []string{}, log),
"platform_css": plat.css,
"platform_name": plat.provider,
"is_cymbal_brand": isCymbalBrand,
}); err != nil {
log.Error(err)
}
......@@ -111,9 +130,15 @@ func (plat *platformDetails) setPlatformDetails(env string) {
} else if env == "azure" {
plat.provider = "Azure"
plat.css = "azure-platform"
} else {
} else if env == "gcp" {
plat.provider = "Google Cloud"
plat.css = "gcp-platform"
} else if env == "alibaba" {
plat.provider = "Alibaba Cloud"
plat.css = "alibaba-platform"
} else {
plat.provider = "local"
plat.css = "local"
}
}
......@@ -173,6 +198,7 @@ func (fe *frontendServer) productHandler(w http.ResponseWriter, r *http.Request)
"cart_size": cartSize(cart),
"platform_css": plat.css,
"platform_name": plat.provider,
"is_cymbal_brand": isCymbalBrand,
}); err != nil {
log.Println(err)
}
......@@ -283,6 +309,7 @@ func (fe *frontendServer) viewCartHandler(w http.ResponseWriter, r *http.Request
"expiration_years": []int{year, year + 1, year + 2, year + 3, year + 4},
"platform_css": plat.css,
"platform_name": plat.provider,
"is_cymbal_brand": isCymbalBrand,
}); err != nil {
log.Println(err)
}
......@@ -354,6 +381,7 @@ func (fe *frontendServer) placeOrderHandler(w http.ResponseWriter, r *http.Reque
"recommendations": recommendations,
"platform_css": plat.css,
"platform_name": plat.provider,
"is_cymbal_brand": isCymbalBrand,
}); err != nil {
log.Println(err)
}
......@@ -453,5 +481,32 @@ func cartSize(c []*pb.CartItem) int {
}
func renderMoney(money pb.Money) string {
return fmt.Sprintf("%s %d.%02d", money.GetCurrencyCode(), money.GetUnits(), money.GetNanos()/10000000)
currencyLogo := renderCurrencyLogo(money.GetCurrencyCode())
return fmt.Sprintf("%s%d.%02d", currencyLogo, money.GetUnits(), money.GetNanos()/10000000)
}
func renderCurrencyLogo(currencyCode string) string {
logos := map[string]string{
"USD": "$",
"CAD": "$",
"JPY": "¥",
"EUR": "€",
"TRY": "₺",
"GBP": "£",
}
logo := "$" //default
if val, ok := logos[currencyCode]; ok {
logo = val
}
return logo
}
func stringinSlice(slice []string, val string) bool {
for _, item := range slice {
if item == val {
return true
}
}
return false
}
......@@ -263,9 +263,10 @@ func mustMapEnv(target *string, envKey string) {
func mustConnGRPC(ctx context.Context, conn **grpc.ClientConn, addr string) {
var err error
ctx, cancel := context.WithTimeout(ctx, time.Second*3)
defer cancel()
*conn, err = grpc.DialContext(ctx, addr,
grpc.WithInsecure(),
grpc.WithTimeout(time.Second*3),
grpc.WithStatsHandler(&ocgrpc.ClientHandler{}))
if err != nil {
panic(errors.Wrapf(err, "grpc: failed to connect %s", addr))
......
File mode changed from 100644 to 100755
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:version="1.0 (4035a4f, 2020-05-01)"
sodipodi:docname="Cymbal_NavLogo.svg"
id="svg835"
version="1.1"
fill="none"
viewBox="0 0 85.633156 28.251238"
height="28.251238"
width="85.633156">
<metadata
id="metadata841">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs839" />
<sodipodi:namedview
inkscape:current-layer="svg835"
inkscape:window-maximized="0"
inkscape:window-y="25"
inkscape:window-x="0"
inkscape:cy="17.327124"
inkscape:cx="59.485955"
inkscape:zoom="13.692308"
fit-margin-bottom="0"
fit-margin-right="0"
fit-margin-left="0"
fit-margin-top="0"
inkscape:snap-global="false"
showguides="false"
showgrid="false"
id="namedview837"
inkscape:window-height="1096"
inkscape:window-width="2277"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
guidetolerance="10"
gridtolerance="10"
objecttolerance="10"
borderopacity="1"
bordercolor="#666666"
pagecolor="#ffffff" />
<path
id="path833"
fill="#000000"
d="m 38.248749,11.252164 c -3.156207,0 -5.719697,-2.45769 -5.719697,-5.64087 C 32.529052,2.428104 35.062912,0 38.219119,0 c 1.95596,0 3.689611,0.903134 4.771411,2.546554 0.3556,0.53299 0.6371,1.14002 0.726,1.77666 h -2.904281 c -0.42972,-1.11042 -1.4077,-1.89511 -2.62277,-1.89511 -1.76333,0 -2.904307,1.49536 -2.904307,3.16838 0,1.67303 1.140977,3.2276 2.919127,3.2276 1.21507,0 2.11896,-0.75508 2.60795,-1.83588 h 2.904281 c -0.6223,2.5761596 -2.845011,4.26396 -5.467781,4.26396 z" />
<g
transform="translate(63.326481,0.033206)"
id="g867"
style="fill:none">
<path
d="m 5.56306,11.2706 c -0.8298,0 -1.9115,-0.3553 -2.3264,-1.14 H 3.20702 v 0.8587 H 0.880615 V 0.166504 H 3.31075 V 3.51255 C 3.94792,2.8463 4.7629,2.59461 5.66679,2.59461 c 0.59271,0 1.17061,0.14805 1.71887,0.39975 1.5707,0.72547 2.28196,2.20602 2.28196,3.89385 0,2.44291 -1.5707,4.38239 -4.10456,4.38239 z M 5.25189,4.85985 c -1.15579,0 -2.01523,0.90314 -2.01523,2.04316 0,1.15483 0.78534,2.08758 1.97077,2.08758 1.17062,0 2.03006,-0.91794 2.03006,-2.07277 0,-1.11042 -0.84462,-2.05797 -1.9856,-2.05797 z"
fill="#000000"
id="path856" />
</g>
<g
transform="translate(42.505839,2.180044)"
id="g854"
style="fill:none">
<path
d="M 20.8287,4.56236 V 9.00402 H 18.3986 V 4.68081 c 0,-0.88833 -0.1186,-1.80628 -1.2447,-1.80628 -1.0817,0 -1.3484,0.75509 -1.3484,1.68783 V 9.00402 H 13.3753 V 4.57717 c 0,-0.82911 -0.1926,-1.70264 -1.2151,-1.70264 -1.1261,0 -1.378,0.84392 -1.378,1.80628 V 9.00402 H 8.35205 V 3.8517 L 2.9287,11.7134 H 0.0688477 L 1.684,9.38897 V 0.875788 H 4.11413 V 5.80603 H 4.18822 L 7.53706,0.875788 H 10.6192 V 1.73451 h 0.0296 c 0.4742,-0.829111 1.3188,-1.140028 2.2375,-1.140028 1.0521,0 1.8523,0.532998 2.3412,1.450938 0.5928,-0.91794 1.4818,-1.450938 2.5784,-1.450938 0.8001,0 1.5707,0.236889 2.1337,0.814308 0.9336,0.94755 0.8891,1.90991 0.8891,3.15357 z"
fill="#000000"
id="path843" />
</g>
<g
transform="translate(73.255785,2.027234)"
id="g880"
style="fill:none">
<path
d="M 6.4988,8.98937 V 8.11585 H 6.46917 C 6.02463,8.94496 4.97256,9.27068 4.0983,9.27068 c -2.50423,0 -4.08975508,-1.93953 -4.08975508,-4.35283 0,-2.36888 1.64479508,-4.338016 4.08975508,-4.338016 0.88907,0 1.8967,0.340527 2.37087,1.140026 H 6.4988 V 0.861139 H 8.92895 V 8.98937 Z M 4.45393,2.85988 c -1.18544,0 -2.00042,0.93275 -2.00042,2.08758 0,1.12522 0.87426,2.04317 2.01524,2.04317 1.18544,0 2.03005,-0.90314 2.03005,-2.07278 0,-1.16963 -0.85944,-2.05797 -2.04487,-2.05797 z"
fill="#000000"
id="path869" />
</g>
<g
transform="translate(83.133197,-0.02268)"
id="g893"
style="fill:none">
<path
d="M 0.0698242,10.9893 V 0.166504 H 2.49996 V 11.0041 H 0.0698242 Z"
fill="#000000"
id="path882" />
</g>
<g
transform="translate(32.708522,14.032818)"
id="g906"
style="fill:none">
<path
d="m 4.18626,11.7607 c -2.19305,0 -3.926739,-1.1253 -3.926739,-3.44973 V 7.95564 H 3.03047 c 0,0.71067 0.32599,1.48056 1.12616,1.48056 0.57789,0 1.05206,-0.45898 1.05206,-1.03639 C 5.20869,7.68914 4.61598,7.46706 4.0529,7.21537 3.7269,7.06731 3.40091,6.93406 3.08974,6.80081 1.68204,6.20859 0.437336,5.39428 0.437336,3.69165 c 0,-2.02836 1.955964,-3.197998 3.808194,-3.197998 1.05207,0 2.25232,0.39975 2.93394,1.228858 0.56308,0.69586 0.69644,1.28808 0.72608,2.1468 H 5.16424 C 5.07533,3.26229 4.86788,2.81812 4.17144,2.81812 c -0.48899,0 -0.94834,0.34053 -0.94834,0.85872 0,0.16286 0.01482,0.32572 0.10372,0.45897 0.26672,0.44417 1.68924,0.99198 2.1486,1.19925 C 6.91275,6.00131 8.02409,6.74159 8.02409,8.44422 7.97964,10.7095 6.33485,11.7607 4.18626,11.7607 Z"
fill="#000000"
id="path895" />
</g>
<g
transform="translate(40.443303,14.020917)"
id="g919"
style="fill:none">
<path
d="M 5.89196,11.5535 V 7.12668 c 0,-0.88833 -0.25191,-1.70264 -1.30398,-1.70264 -1.05207,0 -1.36324,0.69586 -1.36324,1.61381 V 11.5535 H 0.779785 V 0.686279 H 3.22474 V 4.15077 H 3.25437 C 3.68409,3.38088 4.52871,3.12919 5.35852,3.12919 c 0.80016,0 1.68923,0.2813 2.22268,0.88833 0.78535,0.88833 0.77053,1.8655 0.77053,2.97591 V 11.5387 H 5.89196 Z"
fill="#000000"
id="path908" />
</g>
<g
transform="translate(48.369792,16.988328)"
id="g932"
style="fill:none">
<path
d="m 5.38968,8.80519 c -2.50422,0 -4.40091,-1.83589 -4.40091,-4.33802 0,-2.50214 1.89669,-4.33802 4.40091,-4.33802 2.50423,0 4.40092,1.83588 4.40092,4.33802 0,2.50213 -1.89669,4.33802 -4.40092,4.33802 z m 0,-6.38118 c -1.12616,0 -1.95596,0.94755 -1.95596,2.05796 0,1.11042 0.8298,2.05797 1.95596,2.05797 1.12616,0 1.95597,-0.94755 1.95597,-2.05797 0,-1.11041 -0.81499,-2.05796 -1.95597,-2.05796 z"
fill="#000000"
id="path921" />
</g>
<g
transform="translate(58.368261,16.973537)"
id="g945"
style="fill:none">
<path
d="m 5.40643,8.83479 c -0.96316,0 -1.79296,-0.29611 -2.45977,-1.00677 V 11.2777 H 0.501709 V 0.410455 H 2.8133 V 1.29879 H 2.82812 2.85775 C 3.49492,0.499289 4.39882,0.12915 5.40643,0.12915 7.9403,0.12915 9.39245,2.20192 9.39245,4.556 9.37763,6.83605 7.79212,8.83479 5.40643,8.83479 Z M 4.90263,2.4092 c -1.17062,0 -2.04488,0.91794 -2.04488,2.08758 0,1.14002 0.87426,2.07277 2.04488,2.07277 1.15579,0 2.04487,-0.91794 2.04487,-2.07277 C 6.93268,3.32714 6.07324,2.4092 4.90263,2.4092 Z"
fill="#000000"
id="path934" />
</g>
<g
transform="translate(67.2903,17.010531)"
id="g958"
style="fill:none">
<path
d="m 3.94884,8.83463 c -1.70405,0 -3.126569,-0.90314 -3.319201,-2.6946 H 3.05977 c 0.07409,0.50338 0.44454,0.75508 0.91871,0.75508 0.37045,0 0.85943,-0.20728 0.85943,-0.63664 0,-0.59222 -0.6668,-0.76988 -1.09652,-0.93274 C 3.38576,5.20728 3.03013,5.08884 2.68932,4.95559 1.72616,4.60026 0.74818,3.97843 0.74818,2.8236 c 0,-1.70264 1.58551,-2.679801 3.15621,-2.679801 1.62997,0 2.96357,0.843913 3.12657,2.576161 H 4.63046 C 4.61565,2.26098 4.28965,2.09812 3.85993,2.09812 c -0.32599,0 -0.69643,0.17767 -0.69643,0.54781 0,1.27327 4.10454,0.56261 4.10454,3.43488 0,1.82107 -1.6596,2.75382 -3.3192,2.75382 z"
fill="#000000"
id="path947" />
</g>
<g
transform="translate(12.600322,11.81969)"
id="g1017"
style="fill:none">
<path
d="M 13.0939,13.6186 V 4.09905 c 0,-1.7213 -1.408,-3.143239 -3.14566,-3.143239 H 3.29732 c -1.72265,0 -3.145709,1.406979 -3.145709,3.143239 v 6.39125 c 0,1.7213 1.408079,3.1433 3.145709,3.1433 z"
fill="#840237"
id="path1006" />
</g>
<g
transform="translate(5.816672,0.035276)"
id="g1030"
style="fill:none">
<path
d="M 13.6377,9.82748 V 3.48112 c 0,-1.75124 -1.4231,-3.188151 -3.1907,-3.188151 H 3.84102 c -1.72265,0 -3.145708,1.406971 -3.145708,3.143241 V 12.9558 H 10.477 c 1.7376,0 3.1607,-1.407 3.1607,-3.12832 z"
fill="#ce0631"
id="path1019" />
</g>
<g
transform="translate(-0.239258,12.021229)"
id="g1043"
style="fill:none">
<path
d="M 13.1666,10.4903 V 4.09905 c 0,-1.7213 -1.4081,-3.143239 -3.1457,-3.143239 H 0.239258 V 10.4753 c 0,1.7213 1.408082,3.1433 3.145712,3.1433 h 6.65093 c 1.7226,0 3.1307,-1.407 3.1307,-3.1283 z"
fill="#ff6631"
id="path1032" />
</g>
</svg>
File mode changed from 100644 to 100755
<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" data-name="Layer 1" viewBox="0 0 20 20"><defs><style>.cls-1{fill:#b4b2bb}</style></defs><title>Hipster</title><g><path d="M7.76,14.3a1.1,1.1,0,1,0,1.1,1.1A1.1,1.1,0,0,0,7.76,14.3Zm5.5,0a1.1,1.1,0,1,0,1.1,1.1A1.1,1.1,0,0,0,13.26,14.3ZM7.85,12.51l0-.06.49-.9h4.1a1.1,1.1,0,0,0,1-.57l2.12-3.85-.95-.53h0L14,7.7H7.29L6.77,6.6,6.25,5.5H4.46V6.6h1.1l2,4.17-.75,1.35a1.19,1.19,0,0,0-.13.53,1.1,1.1,0,0,0,1.1,1.1h6.6v-1.1H8A.14.14,0,0,1,7.85,12.51Z" class="cls-1"/><path d="M10,2a8,8,0,1,1-8,8,8,8,0,0,1,8-8m0-2A10,10,0,1,0,20,10,10,10,0,0,0,10,0Z" class="cls-1"/></g></svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:version="1.0 (4035a4f, 2020-05-01)"
height="11.002236"
width="10.434605"
sodipodi:docname="Hipster_CartIcon.svg"
version="1.1"
viewBox="0 0 10.434605 11.002236"
data-name="Layer 1"
id="Layer_1">
<metadata
id="metadata1201">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Hipster</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
inkscape:current-layer="g1196"
inkscape:window-maximized="0"
inkscape:window-y="25"
inkscape:window-x="625"
inkscape:cy="-0.89051508"
inkscape:cx="22.434662"
inkscape:zoom="20.841972"
fit-margin-bottom="0"
fit-margin-right="0"
fit-margin-left="0"
fit-margin-top="0"
showgrid="false"
id="namedview1199"
inkscape:window-height="1387"
inkscape:window-width="1935"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
guidetolerance="10"
gridtolerance="10"
objecttolerance="10"
borderopacity="1"
bordercolor="#666666"
pagecolor="#ffffff" />
<defs
id="defs1188">
<style
id="style1186">.cls-1{fill:#b4b2bb}</style>
</defs>
<title
id="title1190">Hipster</title>
<g
transform="translate(-4.4609375,-5.5)"
id="g1196">
<path
sodipodi:nodetypes="ccccccsccccccccccccccccccssssssss"
d="m 4.4609375,5.5 v 1.0996094 h 1.0996094 l 2,4.1699216 -0.75,1.34961 c -0.083803,0.164211 -0.1291659,0.346898 -0.1308594,0.53125 0,0.607513 0.4920962,1.099609 1.0996094,1.099609 H 14.380859 V 12.650391 H 8 c -0.081192,0.0058 -0.1505985,-0.05923 -0.1503906,-0.140625 v -0.06055 l 0.4902344,-0.898438 h 4.0996092 c 0.414076,0.01348 0.800604,-0.207156 1,-0.570312 l 1.456089,-4.4008431 -8.1260108,0.019984 v 0 L 6.25,5.5 Z M 7.1729534,7.576157 13.673828,7.54223 12.681641,10.603516 8.5214844,10.589846 Z m 0.5868122,6.724624 c -0.9800635,0 -1.4702693,1.184027 -0.7773437,1.876953 0.6929255,0.692925 1.8769531,0.20272 1.8769531,-0.777343 0,-0.607513 -0.4920962,-1.09961 -1.0996094,-1.09961 z m 5.5000004,0 c -0.980063,0 -1.470269,1.184027 -0.777344,1.876953 0.692926,0.692925 1.876953,0.20272 1.876953,-0.777343 0,-0.607513 -0.492096,-1.09961 -1.099609,-1.09961 z"
id="path1192" />
</g>
</svg>
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" data-name="Layer 1" viewBox="0 0 10 6"><defs><style>.cls-1{fill:#605f64}</style></defs><title>Hipster</title><polygon points="5 6 0 1 1 0 5 4 9 0 10 1 5 6" class="cls-1"/></svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:version="1.0 (4035a4f, 2020-05-01)"
sodipodi:docname="Hipster_DownArrow.svg"
version="1.1"
viewBox="0 0 10 6"
data-name="Layer 1"
id="Layer_1">
<metadata
id="metadata1241">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
inkscape:current-layer="g1805"
inkscape:window-maximized="0"
inkscape:window-y="432"
inkscape:window-x="453"
inkscape:cy="7.8920446"
inkscape:cx="9.2114456"
inkscape:zoom="27.4"
showgrid="false"
id="namedview1239"
inkscape:window-height="815"
inkscape:window-width="1338"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
guidetolerance="10"
gridtolerance="10"
objecttolerance="10"
borderopacity="1"
bordercolor="#666666"
pagecolor="#ffffff" />
<defs
id="defs1232">
<style
id="style1230">.cls-1{fill:#605f64}</style>
</defs>
<title