From 715aca065e07f05cbcfc044afdc8ec947d896e33 Mon Sep 17 00:00:00 2001 From: afeiszli Date: Tue, 16 Nov 2021 21:20:06 -0500 Subject: [PATCH 1/7] adding DO button --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 805a1a6b..2db5b130 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,9 @@ - [x] OAuth and Private DNS - [x] Linux, Mac, Windows, iPhone, and Android -# Get Started in 5 Minutes +[![DO button](https://www.deploytodo.com/do-btn-blue.svg)](https://marketplace.digitalocean.com/apps/netmaker?refcode=496ffcf1e252) + +# Get Started in 5 Minutes **For production-grade installations, visit the [Install Docs](https://netmaker.readthedocs.io/en/develop/install.html).** **For an HA install using helm on k8s, visit the [Helm Repo](https://github.com/gravitl/netmaker-helm/).** From f04576ac4206b4a76b129a3b8dd08455033dd6ca Mon Sep 17 00:00:00 2001 From: afeiszli Date: Tue, 16 Nov 2021 21:25:47 -0500 Subject: [PATCH 2/7] adding DO button --- README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README.md b/README.md index 2db5b130..55e22740 100644 --- a/README.md +++ b/README.md @@ -33,10 +33,9 @@ - [x] OAuth and Private DNS - [x] Linux, Mac, Windows, iPhone, and Android -[![DO button](https://www.deploytodo.com/do-btn-blue.svg)](https://marketplace.digitalocean.com/apps/netmaker?refcode=496ffcf1e252) - # Get Started in 5 Minutes +**For DigitalOcean, use the 1-Click App: **For production-grade installations, visit the [Install Docs](https://netmaker.readthedocs.io/en/develop/install.html).** **For an HA install using helm on k8s, visit the [Helm Repo](https://github.com/gravitl/netmaker-helm/).** 1. Get a cloud VM with Ubuntu 20.04 and a public IP. @@ -47,8 +46,6 @@ Upon completion, the logs will display a script that can be used to automatically connect Linux and Mac devices. It will also display instructions for Windows, iPhone, and Android. - - After installing Netmaker, check out the [Walkthrough](https://itnext.io/getting-started-with-netmaker-a-wireguard-virtual-networking-platform-3d563fbd87f0) and [Getting Started](https://netmaker.readthedocs.io/en/master/getting-started.html) guides to learn more about configuring networks. Or, check out some of our other [Tutorials](https://gravitl.com/resources) for different use cases, including Kubernetes. ### Optional configurations From 512af09da16cfe98107be9de0ae9096ef41dfbda Mon Sep 17 00:00:00 2001 From: afeiszli Date: Tue, 16 Nov 2021 21:26:49 -0500 Subject: [PATCH 3/7] adding DO button --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 55e22740..2a8dfda1 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ # Get Started in 5 Minutes -**For DigitalOcean, use the 1-Click App: +**For DigitalOcean, use the 1-Click App:** **For production-grade installations, visit the [Install Docs](https://netmaker.readthedocs.io/en/develop/install.html).** **For an HA install using helm on k8s, visit the [Helm Repo](https://github.com/gravitl/netmaker-helm/).** 1. Get a cloud VM with Ubuntu 20.04 and a public IP. From f96f64f515756c56d1031f2386b0500b7aa336a7 Mon Sep 17 00:00:00 2001 From: afeiszli Date: Tue, 16 Nov 2021 21:27:04 -0500 Subject: [PATCH 4/7] adding DO button --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2a8dfda1..4b221946 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ # Get Started in 5 Minutes -**For DigitalOcean, use the 1-Click App:** +**For DigitalOcean, use the 1-Click App:** **For production-grade installations, visit the [Install Docs](https://netmaker.readthedocs.io/en/develop/install.html).** **For an HA install using helm on k8s, visit the [Helm Repo](https://github.com/gravitl/netmaker-helm/).** 1. Get a cloud VM with Ubuntu 20.04 and a public IP. From e2110d14023ce0cda1257ba02f98b1162db71fe7 Mon Sep 17 00:00:00 2001 From: afeiszli Date: Tue, 16 Nov 2021 21:27:23 -0500 Subject: [PATCH 5/7] adding DO button --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4b221946..c0ab26c9 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ # Get Started in 5 Minutes -**For DigitalOcean, use the 1-Click App:** +**For DigitalOcean, use the 1-Click App:** **For production-grade installations, visit the [Install Docs](https://netmaker.readthedocs.io/en/develop/install.html).** **For an HA install using helm on k8s, visit the [Helm Repo](https://github.com/gravitl/netmaker-helm/).** 1. Get a cloud VM with Ubuntu 20.04 and a public IP. From aac6837147b727d5a3a6c6dac112c2bc280c2e0e Mon Sep 17 00:00:00 2001 From: afeiszli Date: Tue, 16 Nov 2021 22:18:24 -0500 Subject: [PATCH 6/7] docker working --- docker/Dockerfile-netclient-full | 45 ++++++++++++++++++++------------ docker/Dockerfile-userspace | 2 +- scripts/netclient.sh | 13 +++++++-- 3 files changed, 41 insertions(+), 19 deletions(-) mode change 100644 => 100755 scripts/netclient.sh diff --git a/docker/Dockerfile-netclient-full b/docker/Dockerfile-netclient-full index c8fa9233..642c2864 100644 --- a/docker/Dockerfile-netclient-full +++ b/docker/Dockerfile-netclient-full @@ -1,26 +1,39 @@ -#first stage - builder +FROM gravitl/builder:latest as builder +# add glib support daemon manager +WORKDIR /app -FROM golang:latest as builder - -COPY . /app - -WORKDIR /app/netclient +COPY . . ENV GO111MODULE=auto -RUN CGO_ENABLED=0 GOOS=linux go build -o netclient main.go - -#second stage - -FROM debian:latest - -RUN apt-get update && apt-get -y install systemd procps +RUN GOOS=linux GOARCH=amd64 CGO_ENABLED=0 /usr/local/go/bin/go build -ldflags="-w -s" -o netclient-app netclient/main.go WORKDIR /root/ -COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ +RUN apk add --update git build-base libmnl-dev iptables -COPY --from=builder /app/netclient/netclient . +RUN git clone https://git.zx2c4.com/wireguard-go && \ + cd wireguard-go && \ + make && \ + make install -CMD ["./netclient"] +ENV WITH_WGQUICK=yes +RUN git clone https://git.zx2c4.com/wireguard-tools && \ + cd wireguard-tools && \ + cd src && \ + make && \ + make install +FROM alpine:3.13.6 + +WORKDIR /root/ + +RUN apk add --no-cache --update bash libmnl iptables openresolv iproute2 +COPY --from=builder /usr/bin/wireguard-go /usr/bin/wg* /usr/bin/ +COPY --from=builder /app/netclient-app ./netclient +COPY --from=builder /app/scripts/netclient.sh . +RUN chmod 0755 netclient && chmod 0755 netclient.sh + +ENV WG_QUICK_USERSPACE_IMPLEMENTATION=wireguard-go + +ENTRYPOINT ["/bin/sh", "./netclient.sh"] diff --git a/docker/Dockerfile-userspace b/docker/Dockerfile-userspace index 9307caba..1da2198a 100644 --- a/docker/Dockerfile-userspace +++ b/docker/Dockerfile-userspace @@ -21,6 +21,6 @@ FROM gravitl/netmaker:${NM_VERSION} RUN apk add --no-cache --update bash libmnl iptables openresolv iproute2 COPY --from=builder /usr/bin/wireguard-go /usr/bin/wg* /usr/bin/ -COPY scripts/userspace-entrypoint.sh ./entrypoint.sh +COPY scripts/netclient.sh ./entrypoint.sh ENTRYPOINT ["/bin/sh", "./entrypoint.sh"] diff --git a/scripts/netclient.sh b/scripts/netclient.sh old mode 100644 new mode 100755 index 1b64dae5..05dd728d --- a/scripts/netclient.sh +++ b/scripts/netclient.sh @@ -1,13 +1,22 @@ #!/bin/sh echo "[netclient] joining network" -/etc/netclient/netclient join -t $NETCLIENT_ACCESSTOKEN -daemon off -dnson no +if [ -z "${SLEEP}" ]; then + SLEEP=10 +fi + +TOKEN_CMD="" +if [ "$TOKEN" != "" ]; then + TOKEN_CMD="-t $TOKEN" +fi + +/root/netclient join $TOKEN_CMD -daemon off -dnson no echo "[netclient] Starting netclient checkin" # loop and call checkin -n all while [ 1 ]; do # add logs to netclient.logs - /etc/netclient/netclient checkin -n all + /root/netclient checkin -n all sleep $SLEEP done echo "[netclient] exiting" From e0d876ccbcb1fd114982ab677784b603b66a3d10 Mon Sep 17 00:00:00 2001 From: afeiszli Date: Tue, 16 Nov 2021 22:39:28 -0500 Subject: [PATCH 7/7] updating docs --- README.md | 4 +- compose/docker-compose.caddy.yml | 5 +- compose/docker-compose.contained.yml | 5 +- compose/docker-compose.nodns.yml | 5 +- compose/docker-compose.reference.yml | 5 +- compose/docker-compose.yml | 5 +- docs/_build/doctrees/about.doctree | Bin 13390 -> 13407 bytes docs/_build/doctrees/api.doctree | Bin 49486 -> 49503 bytes docs/_build/doctrees/architecture.doctree | Bin 54044 -> 54425 bytes .../doctrees/client-installation.doctree | Bin 42782 -> 42739 bytes docs/_build/doctrees/conduct.doctree | Bin 14067 -> 14084 bytes docs/_build/doctrees/environment.pickle | Bin 93276 -> 94427 bytes docs/_build/doctrees/external-clients.doctree | Bin 14616 -> 14613 bytes docs/_build/doctrees/getting-started.doctree | Bin 30271 -> 30288 bytes docs/_build/doctrees/index.doctree | Bin 18659 -> 18676 bytes docs/_build/doctrees/install.doctree | Bin 6053 -> 6070 bytes docs/_build/doctrees/license.doctree | Bin 3511 -> 3528 bytes docs/_build/doctrees/oauth.doctree | Bin 12374 -> 12606 bytes .../_build/doctrees/quick-start-nginx.doctree | Bin 35856 -> 35873 bytes docs/_build/doctrees/quick-start.doctree | Bin 25750 -> 25767 bytes .../doctrees/server-installation.doctree | Bin 120786 -> 120969 bytes docs/_build/doctrees/support.doctree | Bin 14062 -> 14079 bytes docs/_build/doctrees/troubleshoot.doctree | Bin 37779 -> 37796 bytes docs/_build/doctrees/usage.doctree | Bin 11556 -> 11573 bytes docs/_build/html/.buildinfo | 2 +- .../_build/html/_sources/architecture.rst.txt | 2 + docs/_build/html/_sources/oauth.rst.txt | 22 +- docs/_build/html/_static/basic.css | 88 +- docs/_build/html/_static/doctools.js | 2 + .../html/_static/documentation_options.js | 2 +- docs/_build/html/_static/pygments.css | 7 +- docs/_build/html/_static/searchtools.js | 15 +- docs/_build/html/_static/underscore.js | 1711 +---------------- docs/_build/html/about.html | 53 +- docs/_build/html/api.html | 53 +- docs/_build/html/architecture.html | 55 +- docs/_build/html/client-installation.html | 67 +- docs/_build/html/conduct.html | 53 +- docs/_build/html/external-clients.html | 18 +- docs/_build/html/genindex.html | 18 +- docs/_build/html/getting-started.html | 53 +- docs/_build/html/index.html | 18 +- docs/_build/html/install.html | 53 +- docs/_build/html/license.html | 53 +- docs/_build/html/oauth.html | 39 +- docs/_build/html/quick-start-nginx.html | 53 +- docs/_build/html/quick-start.html | 53 +- docs/_build/html/search.html | 18 +- docs/_build/html/searchindex.js | 2 +- docs/_build/html/server-installation.html | 25 +- docs/_build/html/support.html | 53 +- docs/_build/html/troubleshoot.html | 53 +- docs/_build/html/usage.html | 53 +- docs/architecture.rst | 2 + docs/conf.py | 2 +- 55 files changed, 774 insertions(+), 1953 deletions(-) diff --git a/README.md b/README.md index c0ab26c9..1bf9a528 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@

- + @@ -31,7 +31,7 @@ - [x] Peer-to-Peer Mesh Networks - [x] Kubernetes, Multi-Cloud - [x] OAuth and Private DNS -- [x] Linux, Mac, Windows, iPhone, and Android +- [x] Linux, Mac, Windows, FreeBSD, iPhone, and Android # Get Started in 5 Minutes diff --git a/compose/docker-compose.caddy.yml b/compose/docker-compose.caddy.yml index 015d191e..52249660 100644 --- a/compose/docker-compose.caddy.yml +++ b/compose/docker-compose.caddy.yml @@ -3,7 +3,7 @@ version: "3.4" services: netmaker: container_name: netmaker - image: gravitl/netmaker:v0.8.5 + image: gravitl/netmaker:v0.9.0 volumes: - /var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket - /run/systemd/system:/run/systemd/system @@ -33,13 +33,14 @@ services: MASTER_KEY: "REPLACE_MASTER_KEY" SERVER_GRPC_WIREGUARD: "off" CORS_ALLOWED_ORIGIN: "*" + DISPLAY_KEYS: "on" DATABASE: "sqlite" NODE_ID: "netmaker-server-1" netmaker-ui: container_name: netmaker-ui depends_on: - netmaker - image: gravitl/netmaker-ui:v0.8.5 + image: gravitl/netmaker-ui:v0.9.0 links: - "netmaker:api" ports: diff --git a/compose/docker-compose.contained.yml b/compose/docker-compose.contained.yml index fb5cc9d1..ba225a2b 100644 --- a/compose/docker-compose.contained.yml +++ b/compose/docker-compose.contained.yml @@ -3,7 +3,7 @@ version: "3.4" services: netmaker: container_name: netmaker - image: gravitl/netmaker:v0.8.5 + image: gravitl/netmaker:v0.9.0 volumes: - dnsconfig:/root/config/dnsconfig - /usr/bin/wg:/usr/bin/wg @@ -27,6 +27,7 @@ services: MASTER_KEY: "REPLACE_MASTER_KEY" SERVER_GRPC_WIREGUARD: "off" CORS_ALLOWED_ORIGIN: "*" + DISPLAY_KEYS: "on" DATABASE: "sqlite" NODE_ID: "netmaker-server-1" ports: @@ -37,7 +38,7 @@ services: container_name: netmaker-ui depends_on: - netmaker - image: gravitl/netmaker-ui:v0.8.5 + image: gravitl/netmaker-ui:v0.9.0 links: - "netmaker:api" ports: diff --git a/compose/docker-compose.nodns.yml b/compose/docker-compose.nodns.yml index 9b78dc20..867915ad 100644 --- a/compose/docker-compose.nodns.yml +++ b/compose/docker-compose.nodns.yml @@ -3,7 +3,7 @@ version: "3.4" services: netmaker: container_name: netmaker - image: gravitl/netmaker:v0.8.5 + image: gravitl/netmaker:v0.9.0 volumes: - /usr/bin/wg:/usr/bin/wg - sqldata:/root/data @@ -23,6 +23,7 @@ services: API_PORT: "8081" GRPC_PORT: "50051" CLIENT_MODE: "on" + DISPLAY_KEYS: "on" MASTER_KEY: "REPLACE_MASTER_KEY" SERVER_GRPC_WIREGUARD: "off" CORS_ALLOWED_ORIGIN: "*" @@ -35,7 +36,7 @@ services: container_name: netmaker-ui depends_on: - netmaker - image: gravitl/netmaker-ui:v0.8.5 + image: gravitl/netmaker-ui:v0.9.0 links: - "netmaker:api" ports: diff --git a/compose/docker-compose.reference.yml b/compose/docker-compose.reference.yml index 1a48bb5f..f90ae1de 100644 --- a/compose/docker-compose.reference.yml +++ b/compose/docker-compose.reference.yml @@ -11,7 +11,7 @@ services: container_name: netmaker depends_on: - rqlite - image: gravitl/netmaker:v0.8.5 + image: gravitl/netmaker:v0.9.0 volumes: # Volume mounts necessary for CLIENT_MODE to control wireguard networking on host (except dnsconfig, which is where dns config files are stored for use by CoreDNS) - dnsconfig:/root/config/dnsconfig # Netmaker writes Corefile to this location, which gets mounted by CoreDNS for DNS configuration. - /usr/bin/wg:/usr/bin/wg @@ -34,13 +34,14 @@ services: DISABLE_REMOTE_IP_CHECK: "off" # If turned "on", Server will not set Host based on remote IP check. This is already overridden if SERVER_HOST is set. Turned "off" by default. GRPC_SSL: "off" # Tells clients to use SSL to connect to GRPC. Switch to on to turn on. COREDNS_ADDR: "" # Address of the CoreDNS server. Defaults to SERVER_HOST + DISPLAY_KEYS: "on" # Show keys permanently in UI (until deleted) as opposed to 1-time display. SERVER_API_CONN_STRING: "" # Changes the api connection string. IP:PORT format. By default is empty and uses SERVER_HOST:API_PORT SERVER_GRPC_CONN_STRING: "" # Changes the grpc connection string. IP:PORT format. By default is empty and uses SERVER_HOST:GRPC_PORT netmaker-ui: # The Netmaker UI Component container_name: netmaker-ui depends_on: - netmaker - image: gravitl/netmaker-ui:v0.7 + image: gravitl/netmaker-ui:v0.9.0 links: - "netmaker:api" ports: diff --git a/compose/docker-compose.yml b/compose/docker-compose.yml index 20dea76f..e07c520a 100644 --- a/compose/docker-compose.yml +++ b/compose/docker-compose.yml @@ -3,7 +3,7 @@ version: "3.4" services: netmaker: container_name: netmaker - image: gravitl/netmaker:v0.8.5 + image: gravitl/netmaker:v0.9.0 volumes: - /var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket - /run/systemd/system:/run/systemd/system @@ -34,12 +34,13 @@ services: SERVER_GRPC_WIREGUARD: "off" CORS_ALLOWED_ORIGIN: "*" DATABASE: "sqlite" + DISPLAY_KEYS: "on" NODE_ID: "netmaker-server-1" netmaker-ui: container_name: netmaker-ui depends_on: - netmaker - image: gravitl/netmaker-ui:v0.8.5 + image: gravitl/netmaker-ui:v0.9.0 links: - "netmaker:api" ports: diff --git a/docs/_build/doctrees/about.doctree b/docs/_build/doctrees/about.doctree index 42dafee2a3348748b4ecf0d13d4fc6b8a0272726..1c53c1c75b32def1cb29139c832a76841c89fe53 100644 GIT binary patch delta 100 zcmX??aX*8lfpu!gMiw(hZYBMU{M=Oi#GKTM&5?{T`n)`;xk;%h@tL`a>8Zt&HyId+ z2o|R%mt^MW#TTdMq{ZiC=4DUm-2BjB4HMH7rpb!RDlF1j4?zsM$ybdH81GMJGw}cb D5CJ2l delta 85 zcmcbgaV~?Ufpx0$Miw(hc{BZt{M=Oi#I)4R;;NiX{q+3!f};Ga)Z~(4{oR{H)aEl4AYhqU6n? Rj8%Ik-`}gdS#h5oGXSr<7kK~x diff --git a/docs/_build/doctrees/architecture.doctree b/docs/_build/doctrees/architecture.doctree index 83922c8b971bcf9485b4f89f2c766111cceeb3cc..95215812d979f3f72417a5f5bd86df94e691a2ef 100644 GIT binary patch delta 991 zcmYL{TSydP6vzF>-F3!Q)Y4sb*9#TVDz$cdC@j*{ha{s5iA61IPL89yimuv)N{hfi z3_DwCNNqPOtZZj?cic-BWrk#?OF_|#KJ<_V^`HcW)c4I;z8uc^e*g17hcnaD8`=FJ zQr)7y-0|M6-j1{;GgoV4&DI+Bm{^Iy{)({qNEgu@$xTRu~alVI-&ri>QTUVF{cNo4_ULQ4tIXM#%IuL$R0$eV!Po7UN*p z(*!@nB$Wdj!Nrgs9NuQQ>Pdt@-WZTPagge3f?RJ3x&`~a=`e(=X>StpU-G5Welpy^ z2f-c4hF)nSY<0&$r%#8*;l9sEk1IG#uzCOs$6zXu1?@s2Y?e0BGYbAHV?V}UWc)$8 zhEG*D;6#j`mi?1xnCe;v=73i749gN|*cK>($)FaZeep0KET>k|&>@(pd>Z_Mfyr0e z3TSY5Wx=PAnQ$p+LS--&G%{rhJ}6_&Aa*Pz1589^4HYsDh1V;bOti~fwGsp9EHq~D zkvQX3I5cuuyqA19BbUvk6^F2RxxB6R33(;U$~_se{Ix~dGtu>wLQEfKSn_~|wOexH zdr5`3$OWqx;>_T66(wP}r73XdkDk)}#IyKWSob!RcblXx626o0jfBr6e8i!# zov~YOtmAkc+dzJFo-~&5g%pX0nTUus-U8;avJ~P{B0H4G-EECrCehEr%`qWWw&(B# z6?<|k*`5!B?cE%e%|ONYbLt#}FSJ5s;9E$N4mA_&(P?l^=+GIECazL9{_!4#UkN9p NZs-piu2$7ZEF=gbnC5GaWc zeitP~P-;>6CwI5`XHHB)?Vnj%)T0EI_TZCXnbbMg1nK3=x##!&e!l0N+w&;$&V$J4 zYtc7#OC!+*#B|&&IBIO>iird4_}us@B_iaD0q@u0ldlQ){RvvL zG9p4ymV1T7&ZyJ&+D5n~4~hZ_i1lkA1hmNVyRjb7Ys>c-&lMG(!kpg&Z_tSHfCghh zJ(>e<6pZS%H})7U&ME=%K@Yx<8Za2tVBc6AUI&}dJ(jNyGb1mCl+bl$pnvoja>u>& zD)Us;t2@JQN?5uMqi0y72vhGDC2ohTsoVcmc&~ds-d67sAzGA2y!c0kDkf-Viy_jv zO(nic>6~5#ou60hRdRPC{p!k4gs3e}wQGwFr;|+Nhm%1jD_L$lTu4r0V6q}=lNRHs zDcK}`peyks6_=191{9Q*EMy7?i&^7_d}z&6w#&{eXG{o<$B?kJImHom>rVX@6^JoQ zA4^@$Y=;Pu|1i^1!SvlIu0w@;79)N?|HXByP+yjYl-XX=ftlGYT`x`0a^ZHE&z~UEQp>!^Y1V0^bHB~$bT~2cGG5|dedh4vO*XO@t}0&8 zp*V}-g-MHxEuBoBF_~gA$mB5gR4?JgS@3%oMSgoy%UIEP9k<>E%U^RqUE!H0Y=w5mH+?% diff --git a/docs/_build/doctrees/client-installation.doctree b/docs/_build/doctrees/client-installation.doctree index 980374a7381b0495775491b545b1af141a1561fb..437bc4a12a3ef2c706b2f2de9412b701db035181 100644 GIT binary patch delta 136 zcmbPtj_LDRCe{YlsV|moWDR8GHqg(=&rQ`&%t@`-T*}C5!)=Zbm@F8px_O_ii9E94 zX2ICYlH67(s^m8-mB;At@}%Y_rKZGZ<|d}67Ei8TY#<_7oSIycnV%P5oSKsspOcxF MJ*9K=s>LPD00I&*&;S4c delta 181 zcmex-mTBHOCe{Ylslv-QvIa8ByXa@+=cei>rln>USLI~tr{~8P6y;~7CYKcJ7Z)XO zPGn@Yk@qH`sL(c2o{*x+g|@1jf5ohml=s7L8c?D9=1XNUI+N`d>uzpXT+9pr6MIE> diff --git a/docs/_build/doctrees/conduct.doctree b/docs/_build/doctrees/conduct.doctree index 1d79fc06a266d788d49a2a1b15dc7aeaa63f4708..74fd47d5eee37ace6ac7e291a9be13a66a0eda08 100644 GIT binary patch delta 74 zcmeyI+mgr9z&iEkMiwtdZWaBE{M=Oi#GKTM&AE&ljCgrcbCXh2;xls-(^HElOPLsm e2o|R%mt^MW#TTdMq{ZiC=4DUm-0W$xiU|Py#v5_~ delta 59 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≤#hSR!k3~S4xjbw=dKrD;9%)D|F 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 diff --git a/docs/_build/doctrees/external-clients.doctree b/docs/_build/doctrees/external-clients.doctree index f8acda750f589f1e21bbe807496722ff48091e24..1b5e7885a62a23eb0653bf4b18a5b9f0c9485e0c 100644 GIT binary patch delta 91 zcmbPHG_{DOfpsd^Miw7NZe9J1{M=Oi#GKTM&H0RF>fA<10xX)-d3kwKbCXh2;xls- m(^HEl&oDC(5iCwkF3HT#i!V;iNsG_P%*&qAx%s$RAQJ$3SRf++ delta 96 zcmbPQG^2>6fpseHMiw7Nc}M+>{M=Oi#I)4R;;NiX{q+3!f};Ga)Z~(4{ohf*`6y4F7&O5o;On389vj8Rljt(Qr diff --git a/docs/_build/doctrees/getting-started.doctree b/docs/_build/doctrees/getting-started.doctree index 82fcf885da426a89ef9147b199376c4772bb4e2f..ff2a0611df170055442bb0262b1410fdfcc20d25 100644 GIT binary patch delta 103 zcmdo0hVjB1MwSNFsjeGYycoH4^fU5vQ}q*bQY$v+GHxs2;b>*0R(^rl{B#gN&z20FKBOVWiMf7WodJIY-ulNZ(ne7Z)#;@baO9r va$~bu0k&|HA95|TVR9k^0_z5ofhQscENB~Q=mwL)9v+j+buaS7($C1xP1R4#Nv+s?ohihLmnSthDK#ZNGdD3kwRp0I gtAU7MacXi&W`16LacWLld`@Ow_LR=e;jTT*08wKcv;Y7A delta 61 zcmew|k@4|FMwSNFsW&#VY+;f&)6dAyP1R3KOU*2<%E{DE&yO!C%FjwoE-BV8E=t~f Rm?^|*vbwA8=1kXaW&r5U7k&T$ diff --git a/docs/_build/doctrees/install.doctree b/docs/_build/doctrees/install.doctree index 515c5258fd65c030afe7ec3fc523c281e4fb57f4..04e8dc3ca46587f43b07e749330c96c354769f10 100644 GIT binary patch delta 74 zcmZ3gzfGT|fpzNYjVxA-+$#DR`MIh3i8-kin`0SOMR<8qbCXh2;xls-(^HEl*NYm6 e2o|R%mt^MW#TTdMq{ZiC=4DUm+`LZoJ0k$1v>KWK delta 59 zcmdm{zf_;4fpzMvjVxA-@)r6T`MIh3iD{{s#Z@_(`sw-c1x5K;smUe9`o%@bn>`s- PMJCsY>TW(D`i&6)atRe= diff --git a/docs/_build/doctrees/license.doctree b/docs/_build/doctrees/license.doctree index 76da75e8185345e5368d64e5072165e51e232ebd..58bb6167ec95a9ce91022c3d91285cd9d5fe831b 100644 GIT binary patch delta 74 zcmdlkeL|Y0fpzNMjVxA-+$#DR`MIh3i8-kin`0TBxp;X}bCXh2;xls-(^HEl&*e4{ e5iCwkF3HT#i!V;iNsG_P%*&qAx%mwDYeoR9jvCki delta 59 zcmX>hy`tw PxhBuy*4=!M`xPSqcCi(r diff --git a/docs/_build/doctrees/oauth.doctree b/docs/_build/doctrees/oauth.doctree index 198bb23d7d871f2371ec5ebb2f6b8fab1b41be33..a82021b7c5beb9518f6a40a8949a31d55aceddca 100644 GIT binary patch delta 960 zcmb_ZOH30%7-rg3LbnvEpeb!(sa49$Z9z=vtx`~cv;0cN5r!^5WP00O=`V_9y%K}=AP@dVMjBhf_#KVM?-^`T zSiv9I@gsvz6pDHQb>P?ZguJK|`A+wdMW35|Y2M~+7TWY+D=h@rdq6+&@ZaqLdR3Xn zMVeYSxjs|W%S5Zy-7Xwr4S=kbxagCZA8-SvD#}ze$~HiAL*&N6b#BCDhIg4k#u&xG z7~mw6nygUuCm6+gG`*0(dr8aTSHdCMDC)S47JP+*xf)ab5}T`tWlvMvOW*IFTYq}U zkG88IY7~Q-1-vk}I<_sf4wy;6lr)=>XP`)-~dRj`)X6N)3(r~1B z?IGLa9vi=o*6<_t%J&&`vwjDIy9@}0La8PzXP~x_gDU%c%)BC67t1!WY!SW;#(ub=ThQLowmJw?J delta 879 zcmdm&bS;6kfpx04!A4eJMtL*+jQreG{lv7?%;Kt?O#Sry_=2MRtkmR^V*TQx+tJ{ zAoL|nfm&!fS(jfMXu~xA5^nxKj-eqQ@c}{pVV*9oLAH}+WK=po67vsBHg^ylHA1X)FR!)f=u0%{M^LMJUb;Ww;+GN5LZ8!_|PC9oH|kx zi!+k)6N^&d`d}_XbA*yjVpVBTs%~OR&17{MNo4ng;xwHS_iX+rBf-e1H(6Y+5=c&z z3)?(To{5q38zTclhIG~!#>oOICXA+&?o@W>;q9FoCEt0;)1)wFjx1?4T+#IaXyMhZ97~0W9SR zlG^N`8p_BK01@{Cid*u-3@uH{Vg`y&{;r@nnN59#z8H{GJ0(j3NM+>$35dgh3=D_( zfwWG(tA1P-Sx*DHp2-I_>KJV|J7|_Lac>1m_VA?^73CLAZqydud`bHz)8yTHx|9Fv z)oAnsC9`@!Hf_z=lrq82Mu*9T?dpuSljGas7_BGoYm;HLnS8r# zDq{>-JaY2Pc3asn4hDuE7ND-wDc%7+Y{mJdMaijCGPFxGw6d%>e{PRrWU~b-$pYz= znVjD_k#Q1OcR!GnpWNFmI61OQUcnluBttr@ml;SgW-w>SWN2r|dIyvyWkn)u)}8#Y aD}`|#*nrhg1B4h?OkU6}4Rqk1?hpWUAzN|) delta 254 zcmZ2DgK5GHCYA=)sjM4Wav0^E^fU5vQ}q+mQZtLIax(SP^WzJO^0QKtON#Z2i;_22 zGfFf~Ufis^`Dt?!6O$ds+QoX9i*YygXN zRxiioL diff --git a/docs/_build/doctrees/quick-start.doctree b/docs/_build/doctrees/quick-start.doctree index 737e1bdbb112aebf60beaddfca2304d733be8389..655f2907d1a48faabe3ef3eee16600ae2789047b 100644 GIT binary patch delta 100 zcmbPsl5zP-MwSNFsdF~6xG{2T=x5~Trs^l=q*iRsWIPqe%afX$l$sKsnVXoNT0Gex z!9YZ?I5oK>Ge0lBI5j6NJ|{CTdrIfx_yi`#%*hE!>WpcVJCfoUQ#LE}xiH~BBV+pH!X$OZl*u!b;uw=Q|47Pb1adM`>;Zl2Aff;O diff --git a/docs/_build/doctrees/server-installation.doctree b/docs/_build/doctrees/server-installation.doctree index a1645a5f066a9077c8116f0dac0c3a0852983181..4c0e2a531c94ebb871a06c29d402e7c8b30a435a 100644 GIT binary patch delta 620 zcmcb#p1pG;J4*xWRECW#DU93(`WgATsrrdIsTG^s8Dm?K1t#9>mIIAh6kM z&L&1?OFe_l|K~2?OmXoH4)Ae|jQ4hp47O5G%Fk0$P*w=e$S+sOPOU6fC`c{JP0UNp zE6J%;$jnm+^;FO(%`3^wQAkP6Ni9iD(Nst*R>&_X$S+P!Q7Fk*Fw`x{%uQ8D$t*6& zNvzc4QUHO;3i{%kA53qBSZlrVHWOzCd+d}9v4}z89ARc|3#7oyUBeU1JGJx%0~mmu zIoaXA%H)OrbEofQWR%#d&nSA9mnSthDK#ZNGdD3kwRpPYSw;g9!Q#~9lFaK?Y@{L-T2)F~O-JuE;wQm1&|E6vc#0-02r ylm#<__Zp)kqb`Oegs_`}S;NWVX;V-E22+0q17+8M7G~%{M<>d7Ei+!yI-z z3WS;EeF!+^{~Dg)sUnP1*{ANl&Hx0{1(_M8wjN{@Jv;r`Sw`LM8s`|_urV=9O#jHp zsKP9r#V}pq2BX3B+^dZ8O#j5E_g!T)Wcn{Y{oqx`L?%VJDmjoULq^Hz3D+4#`MvLz zW@u&o6K7y3P09i)UU-c$g~=MO*aAth3@1Vv&`jm&E3PxzGljy{1|g{x`ty P8%=gF(cRo+Qp*GY#3L5v diff --git a/docs/_build/doctrees/troubleshoot.doctree b/docs/_build/doctrees/troubleshoot.doctree index 3b3e6d0d63fb75128db512ba98435a4e9b98a2a2..9b30bcbd120d9c0f64190d1089f3703bcbbb3f3b 100644 GIT binary patch delta 76 zcmV-S0JHy-rvjv>0tA2sm6@>wN&yQgFKBOVWiMfDWq7k~0Vj_Q3}tO%Wn^DzZDD6+ ibCZ#fFccAUWn*+{Z*E_6Wo%|&Y-w(5l!>#zkkbMSMI7+} delta 61 zcmZ3ooN4lMCYA=)sT~_xycp$e^)vEwQ}q+mQZtLIax(SP^WzJO^0QKtON#Z2i;_1- RGOG7ao-jdo^Q8%wm;kS57rOue diff --git a/docs/_build/doctrees/usage.doctree b/docs/_build/doctrees/usage.doctree index d35c59e55dd309c63a662293dc209085546cb062..a32ce4754a4ae464cede7ab35db182c281b666df 100644 GIT binary patch delta 74 zcmZ1ywKa;Rfpx0ZMivi7ZYBMU{M=Oi#GKTM&Do4cGu4E> e2o|R%mt^MW#TTdMq{ZiC=4DUm+#IcSk_iB|JsOb! delta 59 zcmdlQwIqtAfpx0nMivi7c{BZt{M=Oi#I)4R;;NiX{q+3!f};Ga)Z~(4{o2A)|I>7`0ax@iN diff --git a/docs/_build/html/.buildinfo b/docs/_build/html/.buildinfo index 87876135..65439e79 100644 --- a/docs/_build/html/.buildinfo +++ b/docs/_build/html/.buildinfo @@ -1,4 +1,4 @@ # Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: 99bfa40b6c844b896e1a7ae8e49d7971 +config: 7d73735f557dbf90d3004bb9dfde743b tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/_build/html/_sources/architecture.rst.txt b/docs/_build/html/_sources/architecture.rst.txt index 13fc100a..e760597a 100644 --- a/docs/_build/html/_sources/architecture.rst.txt +++ b/docs/_build/html/_sources/architecture.rst.txt @@ -171,6 +171,8 @@ Simply clone the repo, cd to netmaker/netclient and run "go build" (Golang must The following systems should be operable natively with Netclient in daemon mode: - Windows - Mac + - FreeBSD + - OpenWRT - Fedora - Ubuntu - Debian diff --git a/docs/_build/html/_sources/oauth.rst.txt b/docs/_build/html/_sources/oauth.rst.txt index d5519356..9b094b70 100644 --- a/docs/_build/html/_sources/oauth.rst.txt +++ b/docs/_build/html/_sources/oauth.rst.txt @@ -18,13 +18,13 @@ Configuring your provider In order to use OAuth, configure your OAuth provider (GitHub, Google, Azure AD). -You must configure your provider to use the Netmaker Dashboard URI dashboard. as the origin URL. +You must configure your provider (except for Azure AD) to use the Netmaker Dashboard URI dashboard. as the origin URL. For example: `https://dashboard.netmaker.mydomain.com` -You must configure your provider to use the Netmaker API URI redirect route with the following format: https://api./api/oauth2/callback. +You must configure your provider to use the Netmaker API URI redirect route with the following format: https://api./api/oauth/callback. -For example: `https://api.netmaker.mydomain.com/api/oauth2/callback` +For example: `https://api.netmaker.mydomain.com/api/oauth/callback` General provider instructions can be found with the following links: @@ -41,14 +41,18 @@ Next, Configure Netmaker with the following environment variables. If any are le .. code-block:: - AUTH_PROVIDER="" - CLIENT_ID="" - CLIENT_SECRET="" - SERVER_HTTP_HOST="https://" - FRONTEND_URL="https://" + AUTH_PROVIDER: "" + CLIENT_ID: "" + CLIENT_SECRET: "" + SERVER_HTTP_HOST: "api." + FRONTEND_URL: "https://dashboard." -After restarting your server, the Netmaker logs will indicate if the OAuth provider was successfully initialized. +After restarting your server, the Netmaker logs will indicate if the OAuth provider was successfully initialized: + +.. code-block:: + + sudo docker logs netmaker Once successful, users can click the key symbol on the login page to sign-in with your configured OAuth provider. diff --git a/docs/_build/html/_static/basic.css b/docs/_build/html/_static/basic.css index b3bdc004..603f6a87 100644 --- a/docs/_build/html/_static/basic.css +++ b/docs/_build/html/_static/basic.css @@ -130,7 +130,7 @@ ul.search li a { font-weight: bold; } -ul.search li div.context { +ul.search li p.context { color: #888; margin: 2px 0 0 30px; text-align: left; @@ -508,6 +508,63 @@ table.hlist td { vertical-align: top; } +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + /* -- other body styles ----------------------------------------------------- */ @@ -634,14 +691,6 @@ dl.glossary dt { font-size: 1.1em; } -.optional { - font-size: 1.3em; -} - -.sig-paren { - font-size: larger; -} - .versionmodified { font-style: italic; } @@ -682,8 +731,9 @@ dl.glossary dt { .classifier:before { font-style: normal; - margin: 0.5em; + margin: 0 0.5em; content: ":"; + display: inline-block; } abbr, acronym { @@ -770,8 +820,12 @@ div.code-block-caption code { table.highlighttable td.linenos, span.linenos, -div.doctest > div.highlight span.gp { /* gp: Generic.Prompt */ - user-select: none; +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ } div.code-block-caption span.caption-number { @@ -786,16 +840,6 @@ div.literal-block-wrapper { margin: 1em 0; } -code.descname { - background-color: transparent; - font-weight: bold; - font-size: 1.2em; -} - -code.descclassname { - background-color: transparent; -} - code.xref, a code { background-color: transparent; font-weight: bold; diff --git a/docs/_build/html/_static/doctools.js b/docs/_build/html/_static/doctools.js index 61ac9d26..8cbf1b16 100644 --- a/docs/_build/html/_static/doctools.js +++ b/docs/_build/html/_static/doctools.js @@ -301,12 +301,14 @@ var Documentation = { window.location.href = prevHref; return false; } + break; case 39: // right var nextHref = $('link[rel="next"]').prop('href'); if (nextHref) { window.location.href = nextHref; return false; } + break; } } }); diff --git a/docs/_build/html/_static/documentation_options.js b/docs/_build/html/_static/documentation_options.js index 0f99328d..a3a901a7 100644 --- a/docs/_build/html/_static/documentation_options.js +++ b/docs/_build/html/_static/documentation_options.js @@ -1,6 +1,6 @@ var DOCUMENTATION_OPTIONS = { URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), - VERSION: '0.8.5', + VERSION: '0.9.0', LANGUAGE: 'None', COLLAPSE_INDEX: false, BUILDER: 'html', diff --git a/docs/_build/html/_static/pygments.css b/docs/_build/html/_static/pygments.css index d04b98df..918ae67e 100644 --- a/docs/_build/html/_static/pygments.css +++ b/docs/_build/html/_static/pygments.css @@ -1,10 +1,5 @@ -pre { line-height: 125%; margin: 0; } -td.linenos pre { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; } -span.linenos { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; } -td.linenos pre.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; } -span.linenos.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; } .highlight .hll { background-color: #ffffcc } -.highlight { background: #f8f8f8; } +.highlight { background: #f8f8f8; } .highlight .c { color: #008800; font-style: italic } /* Comment */ .highlight .err { border: 1px solid #FF0000 } /* Error */ .highlight .k { color: #AA22FF; font-weight: bold } /* Keyword */ diff --git a/docs/_build/html/_static/searchtools.js b/docs/_build/html/_static/searchtools.js index 1a90152e..002e9c4a 100644 --- a/docs/_build/html/_static/searchtools.js +++ b/docs/_build/html/_static/searchtools.js @@ -282,7 +282,10 @@ var Search = { complete: function(jqxhr, textstatus) { var data = jqxhr.responseText; if (data !== '' && data !== undefined) { - listItem.append(Search.makeSearchSummary(data, searchterms, hlterms)); + var summary = Search.makeSearchSummary(data, searchterms, hlterms); + if (summary) { + listItem.append(summary); + } } Search.output.append(listItem); setTimeout(function() { @@ -325,7 +328,9 @@ var Search = { var results = []; for (var prefix in objects) { - for (var name in objects[prefix]) { + for (var iMatch = 0; iMatch != objects[prefix].length; ++iMatch) { + var match = objects[prefix][iMatch]; + var name = match[4]; var fullname = (prefix ? prefix + '.' : '') + name; var fullnameLower = fullname.toLowerCase() if (fullnameLower.indexOf(object) > -1) { @@ -339,7 +344,6 @@ var Search = { } else if (parts[parts.length - 1].indexOf(object) > -1) { score += Scorer.objPartialMatch; } - var match = objects[prefix][name]; var objname = objnames[match[1]][2]; var title = titles[match[0]]; // If more than one term searched for, we require other words to be @@ -498,6 +502,9 @@ var Search = { */ makeSearchSummary : function(htmlText, keywords, hlwords) { var text = Search.htmlToText(htmlText); + if (text == "") { + return null; + } var textLower = text.toLowerCase(); var start = 0; $.each(keywords, function() { @@ -509,7 +516,7 @@ var Search = { var excerpt = ((start > 0) ? '...' : '') + $.trim(text.substr(start, 240)) + ((start + 240 - text.length) ? '...' : ''); - var rv = $('

').text(excerpt); + var rv = $('

').text(excerpt); $.each(hlwords, function() { rv = rv.highlightText(this, 'highlighted'); }); diff --git a/docs/_build/html/_static/underscore.js b/docs/_build/html/_static/underscore.js index 709ae8e3..cf177d42 100644 --- a/docs/_build/html/_static/underscore.js +++ b/docs/_build/html/_static/underscore.js @@ -1,1707 +1,6 @@ -// Underscore.js 1.9.1 -// http://underscorejs.org -// (c) 2009-2018 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +!function(n,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define("underscore",r):(n="undefined"!=typeof globalThis?globalThis:n||self,function(){var t=n._,e=n._=r();e.noConflict=function(){return n._=t,e}}())}(this,(function(){ +// Underscore.js 1.13.1 +// https://underscorejs.org +// (c) 2009-2021 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors // Underscore may be freely distributed under the MIT license. - -(function() { - - // Baseline setup - // -------------- - - // Establish the root object, `window` (`self`) in the browser, `global` - // on the server, or `this` in some virtual machines. We use `self` - // instead of `window` for `WebWorker` support. - var root = typeof self == 'object' && self.self === self && self || - typeof global == 'object' && global.global === global && global || - this || - {}; - - // Save the previous value of the `_` variable. - var previousUnderscore = root._; - - // Save bytes in the minified (but not gzipped) version: - var ArrayProto = Array.prototype, ObjProto = Object.prototype; - var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null; - - // Create quick reference variables for speed access to core prototypes. - var push = ArrayProto.push, - slice = ArrayProto.slice, - toString = ObjProto.toString, - hasOwnProperty = ObjProto.hasOwnProperty; - - // All **ECMAScript 5** native function implementations that we hope to use - // are declared here. - var nativeIsArray = Array.isArray, - nativeKeys = Object.keys, - nativeCreate = Object.create; - - // Naked function reference for surrogate-prototype-swapping. - var Ctor = function(){}; - - // Create a safe reference to the Underscore object for use below. - var _ = function(obj) { - if (obj instanceof _) return obj; - if (!(this instanceof _)) return new _(obj); - this._wrapped = obj; - }; - - // Export the Underscore object for **Node.js**, with - // backwards-compatibility for their old module API. If we're in - // the browser, add `_` as a global object. - // (`nodeType` is checked to ensure that `module` - // and `exports` are not HTML elements.) - if (typeof exports != 'undefined' && !exports.nodeType) { - if (typeof module != 'undefined' && !module.nodeType && module.exports) { - exports = module.exports = _; - } - exports._ = _; - } else { - root._ = _; - } - - // Current version. - _.VERSION = '1.9.1'; - - // Internal function that returns an efficient (for current engines) version - // of the passed-in callback, to be repeatedly applied in other Underscore - // functions. - var optimizeCb = function(func, context, argCount) { - if (context === void 0) return func; - switch (argCount == null ? 3 : argCount) { - case 1: return function(value) { - return func.call(context, value); - }; - // The 2-argument case is omitted because we’re not using it. - case 3: return function(value, index, collection) { - return func.call(context, value, index, collection); - }; - case 4: return function(accumulator, value, index, collection) { - return func.call(context, accumulator, value, index, collection); - }; - } - return function() { - return func.apply(context, arguments); - }; - }; - - var builtinIteratee; - - // An internal function to generate callbacks that can be applied to each - // element in a collection, returning the desired result — either `identity`, - // an arbitrary callback, a property matcher, or a property accessor. - var cb = function(value, context, argCount) { - if (_.iteratee !== builtinIteratee) return _.iteratee(value, context); - if (value == null) return _.identity; - if (_.isFunction(value)) return optimizeCb(value, context, argCount); - if (_.isObject(value) && !_.isArray(value)) return _.matcher(value); - return _.property(value); - }; - - // External wrapper for our callback generator. Users may customize - // `_.iteratee` if they want additional predicate/iteratee shorthand styles. - // This abstraction hides the internal-only argCount argument. - _.iteratee = builtinIteratee = function(value, context) { - return cb(value, context, Infinity); - }; - - // Some functions take a variable number of arguments, or a few expected - // arguments at the beginning and then a variable number of values to operate - // on. This helper accumulates all remaining arguments past the function’s - // argument length (or an explicit `startIndex`), into an array that becomes - // the last argument. Similar to ES6’s "rest parameter". - var restArguments = function(func, startIndex) { - startIndex = startIndex == null ? func.length - 1 : +startIndex; - return function() { - var length = Math.max(arguments.length - startIndex, 0), - rest = Array(length), - index = 0; - for (; index < length; index++) { - rest[index] = arguments[index + startIndex]; - } - switch (startIndex) { - case 0: return func.call(this, rest); - case 1: return func.call(this, arguments[0], rest); - case 2: return func.call(this, arguments[0], arguments[1], rest); - } - var args = Array(startIndex + 1); - for (index = 0; index < startIndex; index++) { - args[index] = arguments[index]; - } - args[startIndex] = rest; - return func.apply(this, args); - }; - }; - - // An internal function for creating a new object that inherits from another. - var baseCreate = function(prototype) { - if (!_.isObject(prototype)) return {}; - if (nativeCreate) return nativeCreate(prototype); - Ctor.prototype = prototype; - var result = new Ctor; - Ctor.prototype = null; - return result; - }; - - var shallowProperty = function(key) { - return function(obj) { - return obj == null ? void 0 : obj[key]; - }; - }; - - var has = function(obj, path) { - return obj != null && hasOwnProperty.call(obj, path); - } - - var deepGet = function(obj, path) { - var length = path.length; - for (var i = 0; i < length; i++) { - if (obj == null) return void 0; - obj = obj[path[i]]; - } - return length ? obj : void 0; - }; - - // Helper for collection methods to determine whether a collection - // should be iterated as an array or as an object. - // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength - // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 - var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; - var getLength = shallowProperty('length'); - var isArrayLike = function(collection) { - var length = getLength(collection); - return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; - }; - - // Collection Functions - // -------------------- - - // The cornerstone, an `each` implementation, aka `forEach`. - // Handles raw objects in addition to array-likes. Treats all - // sparse array-likes as if they were dense. - _.each = _.forEach = function(obj, iteratee, context) { - iteratee = optimizeCb(iteratee, context); - var i, length; - if (isArrayLike(obj)) { - for (i = 0, length = obj.length; i < length; i++) { - iteratee(obj[i], i, obj); - } - } else { - var keys = _.keys(obj); - for (i = 0, length = keys.length; i < length; i++) { - iteratee(obj[keys[i]], keys[i], obj); - } - } - return obj; - }; - - // Return the results of applying the iteratee to each element. - _.map = _.collect = function(obj, iteratee, context) { - iteratee = cb(iteratee, context); - var keys = !isArrayLike(obj) && _.keys(obj), - length = (keys || obj).length, - results = Array(length); - for (var index = 0; index < length; index++) { - var currentKey = keys ? keys[index] : index; - results[index] = iteratee(obj[currentKey], currentKey, obj); - } - return results; - }; - - // Create a reducing function iterating left or right. - var createReduce = function(dir) { - // Wrap code that reassigns argument variables in a separate function than - // the one that accesses `arguments.length` to avoid a perf hit. (#1991) - var reducer = function(obj, iteratee, memo, initial) { - var keys = !isArrayLike(obj) && _.keys(obj), - length = (keys || obj).length, - index = dir > 0 ? 0 : length - 1; - if (!initial) { - memo = obj[keys ? keys[index] : index]; - index += dir; - } - for (; index >= 0 && index < length; index += dir) { - var currentKey = keys ? keys[index] : index; - memo = iteratee(memo, obj[currentKey], currentKey, obj); - } - return memo; - }; - - return function(obj, iteratee, memo, context) { - var initial = arguments.length >= 3; - return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial); - }; - }; - - // **Reduce** builds up a single result from a list of values, aka `inject`, - // or `foldl`. - _.reduce = _.foldl = _.inject = createReduce(1); - - // The right-associative version of reduce, also known as `foldr`. - _.reduceRight = _.foldr = createReduce(-1); - - // Return the first value which passes a truth test. Aliased as `detect`. - _.find = _.detect = function(obj, predicate, context) { - var keyFinder = isArrayLike(obj) ? _.findIndex : _.findKey; - var key = keyFinder(obj, predicate, context); - if (key !== void 0 && key !== -1) return obj[key]; - }; - - // Return all the elements that pass a truth test. - // Aliased as `select`. - _.filter = _.select = function(obj, predicate, context) { - var results = []; - predicate = cb(predicate, context); - _.each(obj, function(value, index, list) { - if (predicate(value, index, list)) results.push(value); - }); - return results; - }; - - // Return all the elements for which a truth test fails. - _.reject = function(obj, predicate, context) { - return _.filter(obj, _.negate(cb(predicate)), context); - }; - - // Determine whether all of the elements match a truth test. - // Aliased as `all`. - _.every = _.all = function(obj, predicate, context) { - predicate = cb(predicate, context); - var keys = !isArrayLike(obj) && _.keys(obj), - length = (keys || obj).length; - for (var index = 0; index < length; index++) { - var currentKey = keys ? keys[index] : index; - if (!predicate(obj[currentKey], currentKey, obj)) return false; - } - return true; - }; - - // Determine if at least one element in the object matches a truth test. - // Aliased as `any`. - _.some = _.any = function(obj, predicate, context) { - predicate = cb(predicate, context); - var keys = !isArrayLike(obj) && _.keys(obj), - length = (keys || obj).length; - for (var index = 0; index < length; index++) { - var currentKey = keys ? keys[index] : index; - if (predicate(obj[currentKey], currentKey, obj)) return true; - } - return false; - }; - - // Determine if the array or object contains a given item (using `===`). - // Aliased as `includes` and `include`. - _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) { - if (!isArrayLike(obj)) obj = _.values(obj); - if (typeof fromIndex != 'number' || guard) fromIndex = 0; - return _.indexOf(obj, item, fromIndex) >= 0; - }; - - // Invoke a method (with arguments) on every item in a collection. - _.invoke = restArguments(function(obj, path, args) { - var contextPath, func; - if (_.isFunction(path)) { - func = path; - } else if (_.isArray(path)) { - contextPath = path.slice(0, -1); - path = path[path.length - 1]; - } - return _.map(obj, function(context) { - var method = func; - if (!method) { - if (contextPath && contextPath.length) { - context = deepGet(context, contextPath); - } - if (context == null) return void 0; - method = context[path]; - } - return method == null ? method : method.apply(context, args); - }); - }); - - // Convenience version of a common use case of `map`: fetching a property. - _.pluck = function(obj, key) { - return _.map(obj, _.property(key)); - }; - - // Convenience version of a common use case of `filter`: selecting only objects - // containing specific `key:value` pairs. - _.where = function(obj, attrs) { - return _.filter(obj, _.matcher(attrs)); - }; - - // Convenience version of a common use case of `find`: getting the first object - // containing specific `key:value` pairs. - _.findWhere = function(obj, attrs) { - return _.find(obj, _.matcher(attrs)); - }; - - // Return the maximum element (or element-based computation). - _.max = function(obj, iteratee, context) { - var result = -Infinity, lastComputed = -Infinity, - value, computed; - if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) { - obj = isArrayLike(obj) ? obj : _.values(obj); - for (var i = 0, length = obj.length; i < length; i++) { - value = obj[i]; - if (value != null && value > result) { - result = value; - } - } - } else { - iteratee = cb(iteratee, context); - _.each(obj, function(v, index, list) { - computed = iteratee(v, index, list); - if (computed > lastComputed || computed === -Infinity && result === -Infinity) { - result = v; - lastComputed = computed; - } - }); - } - return result; - }; - - // Return the minimum element (or element-based computation). - _.min = function(obj, iteratee, context) { - var result = Infinity, lastComputed = Infinity, - value, computed; - if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) { - obj = isArrayLike(obj) ? obj : _.values(obj); - for (var i = 0, length = obj.length; i < length; i++) { - value = obj[i]; - if (value != null && value < result) { - result = value; - } - } - } else { - iteratee = cb(iteratee, context); - _.each(obj, function(v, index, list) { - computed = iteratee(v, index, list); - if (computed < lastComputed || computed === Infinity && result === Infinity) { - result = v; - lastComputed = computed; - } - }); - } - return result; - }; - - // Shuffle a collection. - _.shuffle = function(obj) { - return _.sample(obj, Infinity); - }; - - // Sample **n** random values from a collection using the modern version of the - // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). - // If **n** is not specified, returns a single random element. - // The internal `guard` argument allows it to work with `map`. - _.sample = function(obj, n, guard) { - if (n == null || guard) { - if (!isArrayLike(obj)) obj = _.values(obj); - return obj[_.random(obj.length - 1)]; - } - var sample = isArrayLike(obj) ? _.clone(obj) : _.values(obj); - var length = getLength(sample); - n = Math.max(Math.min(n, length), 0); - var last = length - 1; - for (var index = 0; index < n; index++) { - var rand = _.random(index, last); - var temp = sample[index]; - sample[index] = sample[rand]; - sample[rand] = temp; - } - return sample.slice(0, n); - }; - - // Sort the object's values by a criterion produced by an iteratee. - _.sortBy = function(obj, iteratee, context) { - var index = 0; - iteratee = cb(iteratee, context); - return _.pluck(_.map(obj, function(value, key, list) { - return { - value: value, - index: index++, - criteria: iteratee(value, key, list) - }; - }).sort(function(left, right) { - var a = left.criteria; - var b = right.criteria; - if (a !== b) { - if (a > b || a === void 0) return 1; - if (a < b || b === void 0) return -1; - } - return left.index - right.index; - }), 'value'); - }; - - // An internal function used for aggregate "group by" operations. - var group = function(behavior, partition) { - return function(obj, iteratee, context) { - var result = partition ? [[], []] : {}; - iteratee = cb(iteratee, context); - _.each(obj, function(value, index) { - var key = iteratee(value, index, obj); - behavior(result, value, key); - }); - return result; - }; - }; - - // Groups the object's values by a criterion. Pass either a string attribute - // to group by, or a function that returns the criterion. - _.groupBy = group(function(result, value, key) { - if (has(result, key)) result[key].push(value); else result[key] = [value]; - }); - - // Indexes the object's values by a criterion, similar to `groupBy`, but for - // when you know that your index values will be unique. - _.indexBy = group(function(result, value, key) { - result[key] = value; - }); - - // Counts instances of an object that group by a certain criterion. Pass - // either a string attribute to count by, or a function that returns the - // criterion. - _.countBy = group(function(result, value, key) { - if (has(result, key)) result[key]++; else result[key] = 1; - }); - - var reStrSymbol = /[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g; - // Safely create a real, live array from anything iterable. - _.toArray = function(obj) { - if (!obj) return []; - if (_.isArray(obj)) return slice.call(obj); - if (_.isString(obj)) { - // Keep surrogate pair characters together - return obj.match(reStrSymbol); - } - if (isArrayLike(obj)) return _.map(obj, _.identity); - return _.values(obj); - }; - - // Return the number of elements in an object. - _.size = function(obj) { - if (obj == null) return 0; - return isArrayLike(obj) ? obj.length : _.keys(obj).length; - }; - - // Split a collection into two arrays: one whose elements all satisfy the given - // predicate, and one whose elements all do not satisfy the predicate. - _.partition = group(function(result, value, pass) { - result[pass ? 0 : 1].push(value); - }, true); - - // Array Functions - // --------------- - - // Get the first element of an array. Passing **n** will return the first N - // values in the array. Aliased as `head` and `take`. The **guard** check - // allows it to work with `_.map`. - _.first = _.head = _.take = function(array, n, guard) { - if (array == null || array.length < 1) return n == null ? void 0 : []; - if (n == null || guard) return array[0]; - return _.initial(array, array.length - n); - }; - - // Returns everything but the last entry of the array. Especially useful on - // the arguments object. Passing **n** will return all the values in - // the array, excluding the last N. - _.initial = function(array, n, guard) { - return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); - }; - - // Get the last element of an array. Passing **n** will return the last N - // values in the array. - _.last = function(array, n, guard) { - if (array == null || array.length < 1) return n == null ? void 0 : []; - if (n == null || guard) return array[array.length - 1]; - return _.rest(array, Math.max(0, array.length - n)); - }; - - // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. - // Especially useful on the arguments object. Passing an **n** will return - // the rest N values in the array. - _.rest = _.tail = _.drop = function(array, n, guard) { - return slice.call(array, n == null || guard ? 1 : n); - }; - - // Trim out all falsy values from an array. - _.compact = function(array) { - return _.filter(array, Boolean); - }; - - // Internal implementation of a recursive `flatten` function. - var flatten = function(input, shallow, strict, output) { - output = output || []; - var idx = output.length; - for (var i = 0, length = getLength(input); i < length; i++) { - var value = input[i]; - if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { - // Flatten current level of array or arguments object. - if (shallow) { - var j = 0, len = value.length; - while (j < len) output[idx++] = value[j++]; - } else { - flatten(value, shallow, strict, output); - idx = output.length; - } - } else if (!strict) { - output[idx++] = value; - } - } - return output; - }; - - // Flatten out an array, either recursively (by default), or just one level. - _.flatten = function(array, shallow) { - return flatten(array, shallow, false); - }; - - // Return a version of the array that does not contain the specified value(s). - _.without = restArguments(function(array, otherArrays) { - return _.difference(array, otherArrays); - }); - - // Produce a duplicate-free version of the array. If the array has already - // been sorted, you have the option of using a faster algorithm. - // The faster algorithm will not work with an iteratee if the iteratee - // is not a one-to-one function, so providing an iteratee will disable - // the faster algorithm. - // Aliased as `unique`. - _.uniq = _.unique = function(array, isSorted, iteratee, context) { - if (!_.isBoolean(isSorted)) { - context = iteratee; - iteratee = isSorted; - isSorted = false; - } - if (iteratee != null) iteratee = cb(iteratee, context); - var result = []; - var seen = []; - for (var i = 0, length = getLength(array); i < length; i++) { - var value = array[i], - computed = iteratee ? iteratee(value, i, array) : value; - if (isSorted && !iteratee) { - if (!i || seen !== computed) result.push(value); - seen = computed; - } else if (iteratee) { - if (!_.contains(seen, computed)) { - seen.push(computed); - result.push(value); - } - } else if (!_.contains(result, value)) { - result.push(value); - } - } - return result; - }; - - // Produce an array that contains the union: each distinct element from all of - // the passed-in arrays. - _.union = restArguments(function(arrays) { - return _.uniq(flatten(arrays, true, true)); - }); - - // Produce an array that contains every item shared between all the - // passed-in arrays. - _.intersection = function(array) { - var result = []; - var argsLength = arguments.length; - for (var i = 0, length = getLength(array); i < length; i++) { - var item = array[i]; - if (_.contains(result, item)) continue; - var j; - for (j = 1; j < argsLength; j++) { - if (!_.contains(arguments[j], item)) break; - } - if (j === argsLength) result.push(item); - } - return result; - }; - - // Take the difference between one array and a number of other arrays. - // Only the elements present in just the first array will remain. - _.difference = restArguments(function(array, rest) { - rest = flatten(rest, true, true); - return _.filter(array, function(value){ - return !_.contains(rest, value); - }); - }); - - // Complement of _.zip. Unzip accepts an array of arrays and groups - // each array's elements on shared indices. - _.unzip = function(array) { - var length = array && _.max(array, getLength).length || 0; - var result = Array(length); - - for (var index = 0; index < length; index++) { - result[index] = _.pluck(array, index); - } - return result; - }; - - // Zip together multiple lists into a single array -- elements that share - // an index go together. - _.zip = restArguments(_.unzip); - - // Converts lists into objects. Pass either a single array of `[key, value]` - // pairs, or two parallel arrays of the same length -- one of keys, and one of - // the corresponding values. Passing by pairs is the reverse of _.pairs. - _.object = function(list, values) { - var result = {}; - for (var i = 0, length = getLength(list); i < length; i++) { - if (values) { - result[list[i]] = values[i]; - } else { - result[list[i][0]] = list[i][1]; - } - } - return result; - }; - - // Generator function to create the findIndex and findLastIndex functions. - var createPredicateIndexFinder = function(dir) { - return function(array, predicate, context) { - predicate = cb(predicate, context); - var length = getLength(array); - var index = dir > 0 ? 0 : length - 1; - for (; index >= 0 && index < length; index += dir) { - if (predicate(array[index], index, array)) return index; - } - return -1; - }; - }; - - // Returns the first index on an array-like that passes a predicate test. - _.findIndex = createPredicateIndexFinder(1); - _.findLastIndex = createPredicateIndexFinder(-1); - - // Use a comparator function to figure out the smallest index at which - // an object should be inserted so as to maintain order. Uses binary search. - _.sortedIndex = function(array, obj, iteratee, context) { - iteratee = cb(iteratee, context, 1); - var value = iteratee(obj); - var low = 0, high = getLength(array); - while (low < high) { - var mid = Math.floor((low + high) / 2); - if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; - } - return low; - }; - - // Generator function to create the indexOf and lastIndexOf functions. - var createIndexFinder = function(dir, predicateFind, sortedIndex) { - return function(array, item, idx) { - var i = 0, length = getLength(array); - if (typeof idx == 'number') { - if (dir > 0) { - i = idx >= 0 ? idx : Math.max(idx + length, i); - } else { - length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; - } - } else if (sortedIndex && idx && length) { - idx = sortedIndex(array, item); - return array[idx] === item ? idx : -1; - } - if (item !== item) { - idx = predicateFind(slice.call(array, i, length), _.isNaN); - return idx >= 0 ? idx + i : -1; - } - for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { - if (array[idx] === item) return idx; - } - return -1; - }; - }; - - // Return the position of the first occurrence of an item in an array, - // or -1 if the item is not included in the array. - // If the array is large and already in sort order, pass `true` - // for **isSorted** to use binary search. - _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex); - _.lastIndexOf = createIndexFinder(-1, _.findLastIndex); - - // Generate an integer Array containing an arithmetic progression. A port of - // the native Python `range()` function. See - // [the Python documentation](http://docs.python.org/library/functions.html#range). - _.range = function(start, stop, step) { - if (stop == null) { - stop = start || 0; - start = 0; - } - if (!step) { - step = stop < start ? -1 : 1; - } - - var length = Math.max(Math.ceil((stop - start) / step), 0); - var range = Array(length); - - for (var idx = 0; idx < length; idx++, start += step) { - range[idx] = start; - } - - return range; - }; - - // Chunk a single array into multiple arrays, each containing `count` or fewer - // items. - _.chunk = function(array, count) { - if (count == null || count < 1) return []; - var result = []; - var i = 0, length = array.length; - while (i < length) { - result.push(slice.call(array, i, i += count)); - } - return result; - }; - - // Function (ahem) Functions - // ------------------ - - // Determines whether to execute a function as a constructor - // or a normal function with the provided arguments. - var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) { - if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); - var self = baseCreate(sourceFunc.prototype); - var result = sourceFunc.apply(self, args); - if (_.isObject(result)) return result; - return self; - }; - - // Create a function bound to a given object (assigning `this`, and arguments, - // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if - // available. - _.bind = restArguments(function(func, context, args) { - if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function'); - var bound = restArguments(function(callArgs) { - return executeBound(func, bound, context, this, args.concat(callArgs)); - }); - return bound; - }); - - // Partially apply a function by creating a version that has had some of its - // arguments pre-filled, without changing its dynamic `this` context. _ acts - // as a placeholder by default, allowing any combination of arguments to be - // pre-filled. Set `_.partial.placeholder` for a custom placeholder argument. - _.partial = restArguments(function(func, boundArgs) { - var placeholder = _.partial.placeholder; - var bound = function() { - var position = 0, length = boundArgs.length; - var args = Array(length); - for (var i = 0; i < length; i++) { - args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i]; - } - while (position < arguments.length) args.push(arguments[position++]); - return executeBound(func, bound, this, this, args); - }; - return bound; - }); - - _.partial.placeholder = _; - - // Bind a number of an object's methods to that object. Remaining arguments - // are the method names to be bound. Useful for ensuring that all callbacks - // defined on an object belong to it. - _.bindAll = restArguments(function(obj, keys) { - keys = flatten(keys, false, false); - var index = keys.length; - if (index < 1) throw new Error('bindAll must be passed function names'); - while (index--) { - var key = keys[index]; - obj[key] = _.bind(obj[key], obj); - } - }); - - // Memoize an expensive function by storing its results. - _.memoize = function(func, hasher) { - var memoize = function(key) { - var cache = memoize.cache; - var address = '' + (hasher ? hasher.apply(this, arguments) : key); - if (!has(cache, address)) cache[address] = func.apply(this, arguments); - return cache[address]; - }; - memoize.cache = {}; - return memoize; - }; - - // Delays a function for the given number of milliseconds, and then calls - // it with the arguments supplied. - _.delay = restArguments(function(func, wait, args) { - return setTimeout(function() { - return func.apply(null, args); - }, wait); - }); - - // Defers a function, scheduling it to run after the current call stack has - // cleared. - _.defer = _.partial(_.delay, _, 1); - - // Returns a function, that, when invoked, will only be triggered at most once - // during a given window of time. Normally, the throttled function will run - // as much as it can, without ever going more than once per `wait` duration; - // but if you'd like to disable the execution on the leading edge, pass - // `{leading: false}`. To disable execution on the trailing edge, ditto. - _.throttle = function(func, wait, options) { - var timeout, context, args, result; - var previous = 0; - if (!options) options = {}; - - var later = function() { - previous = options.leading === false ? 0 : _.now(); - timeout = null; - result = func.apply(context, args); - if (!timeout) context = args = null; - }; - - var throttled = function() { - var now = _.now(); - if (!previous && options.leading === false) previous = now; - var remaining = wait - (now - previous); - context = this; - args = arguments; - if (remaining <= 0 || remaining > wait) { - if (timeout) { - clearTimeout(timeout); - timeout = null; - } - previous = now; - result = func.apply(context, args); - if (!timeout) context = args = null; - } else if (!timeout && options.trailing !== false) { - timeout = setTimeout(later, remaining); - } - return result; - }; - - throttled.cancel = function() { - clearTimeout(timeout); - previous = 0; - timeout = context = args = null; - }; - - return throttled; - }; - - // Returns a function, that, as long as it continues to be invoked, will not - // be triggered. The function will be called after it stops being called for - // N milliseconds. If `immediate` is passed, trigger the function on the - // leading edge, instead of the trailing. - _.debounce = function(func, wait, immediate) { - var timeout, result; - - var later = function(context, args) { - timeout = null; - if (args) result = func.apply(context, args); - }; - - var debounced = restArguments(function(args) { - if (timeout) clearTimeout(timeout); - if (immediate) { - var callNow = !timeout; - timeout = setTimeout(later, wait); - if (callNow) result = func.apply(this, args); - } else { - timeout = _.delay(later, wait, this, args); - } - - return result; - }); - - debounced.cancel = function() { - clearTimeout(timeout); - timeout = null; - }; - - return debounced; - }; - - // Returns the first function passed as an argument to the second, - // allowing you to adjust arguments, run code before and after, and - // conditionally execute the original function. - _.wrap = function(func, wrapper) { - return _.partial(wrapper, func); - }; - - // Returns a negated version of the passed-in predicate. - _.negate = function(predicate) { - return function() { - return !predicate.apply(this, arguments); - }; - }; - - // Returns a function that is the composition of a list of functions, each - // consuming the return value of the function that follows. - _.compose = function() { - var args = arguments; - var start = args.length - 1; - return function() { - var i = start; - var result = args[start].apply(this, arguments); - while (i--) result = args[i].call(this, result); - return result; - }; - }; - - // Returns a function that will only be executed on and after the Nth call. - _.after = function(times, func) { - return function() { - if (--times < 1) { - return func.apply(this, arguments); - } - }; - }; - - // Returns a function that will only be executed up to (but not including) the Nth call. - _.before = function(times, func) { - var memo; - return function() { - if (--times > 0) { - memo = func.apply(this, arguments); - } - if (times <= 1) func = null; - return memo; - }; - }; - - // Returns a function that will be executed at most one time, no matter how - // often you call it. Useful for lazy initialization. - _.once = _.partial(_.before, 2); - - _.restArguments = restArguments; - - // Object Functions - // ---------------- - - // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. - var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); - var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', - 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; - - var collectNonEnumProps = function(obj, keys) { - var nonEnumIdx = nonEnumerableProps.length; - var constructor = obj.constructor; - var proto = _.isFunction(constructor) && constructor.prototype || ObjProto; - - // Constructor is a special case. - var prop = 'constructor'; - if (has(obj, prop) && !_.contains(keys, prop)) keys.push(prop); - - while (nonEnumIdx--) { - prop = nonEnumerableProps[nonEnumIdx]; - if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) { - keys.push(prop); - } - } - }; - - // Retrieve the names of an object's own properties. - // Delegates to **ECMAScript 5**'s native `Object.keys`. - _.keys = function(obj) { - if (!_.isObject(obj)) return []; - if (nativeKeys) return nativeKeys(obj); - var keys = []; - for (var key in obj) if (has(obj, key)) keys.push(key); - // Ahem, IE < 9. - if (hasEnumBug) collectNonEnumProps(obj, keys); - return keys; - }; - - // Retrieve all the property names of an object. - _.allKeys = function(obj) { - if (!_.isObject(obj)) return []; - var keys = []; - for (var key in obj) keys.push(key); - // Ahem, IE < 9. - if (hasEnumBug) collectNonEnumProps(obj, keys); - return keys; - }; - - // Retrieve the values of an object's properties. - _.values = function(obj) { - var keys = _.keys(obj); - var length = keys.length; - var values = Array(length); - for (var i = 0; i < length; i++) { - values[i] = obj[keys[i]]; - } - return values; - }; - - // Returns the results of applying the iteratee to each element of the object. - // In contrast to _.map it returns an object. - _.mapObject = function(obj, iteratee, context) { - iteratee = cb(iteratee, context); - var keys = _.keys(obj), - length = keys.length, - results = {}; - for (var index = 0; index < length; index++) { - var currentKey = keys[index]; - results[currentKey] = iteratee(obj[currentKey], currentKey, obj); - } - return results; - }; - - // Convert an object into a list of `[key, value]` pairs. - // The opposite of _.object. - _.pairs = function(obj) { - var keys = _.keys(obj); - var length = keys.length; - var pairs = Array(length); - for (var i = 0; i < length; i++) { - pairs[i] = [keys[i], obj[keys[i]]]; - } - return pairs; - }; - - // Invert the keys and values of an object. The values must be serializable. - _.invert = function(obj) { - var result = {}; - var keys = _.keys(obj); - for (var i = 0, length = keys.length; i < length; i++) { - result[obj[keys[i]]] = keys[i]; - } - return result; - }; - - // Return a sorted list of the function names available on the object. - // Aliased as `methods`. - _.functions = _.methods = function(obj) { - var names = []; - for (var key in obj) { - if (_.isFunction(obj[key])) names.push(key); - } - return names.sort(); - }; - - // An internal function for creating assigner functions. - var createAssigner = function(keysFunc, defaults) { - return function(obj) { - var length = arguments.length; - if (defaults) obj = Object(obj); - if (length < 2 || obj == null) return obj; - for (var index = 1; index < length; index++) { - var source = arguments[index], - keys = keysFunc(source), - l = keys.length; - for (var i = 0; i < l; i++) { - var key = keys[i]; - if (!defaults || obj[key] === void 0) obj[key] = source[key]; - } - } - return obj; - }; - }; - - // Extend a given object with all the properties in passed-in object(s). - _.extend = createAssigner(_.allKeys); - - // Assigns a given object with all the own properties in the passed-in object(s). - // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) - _.extendOwn = _.assign = createAssigner(_.keys); - - // Returns the first key on an object that passes a predicate test. - _.findKey = function(obj, predicate, context) { - predicate = cb(predicate, context); - var keys = _.keys(obj), key; - for (var i = 0, length = keys.length; i < length; i++) { - key = keys[i]; - if (predicate(obj[key], key, obj)) return key; - } - }; - - // Internal pick helper function to determine if `obj` has key `key`. - var keyInObj = function(value, key, obj) { - return key in obj; - }; - - // Return a copy of the object only containing the whitelisted properties. - _.pick = restArguments(function(obj, keys) { - var result = {}, iteratee = keys[0]; - if (obj == null) return result; - if (_.isFunction(iteratee)) { - if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]); - keys = _.allKeys(obj); - } else { - iteratee = keyInObj; - keys = flatten(keys, false, false); - obj = Object(obj); - } - for (var i = 0, length = keys.length; i < length; i++) { - var key = keys[i]; - var value = obj[key]; - if (iteratee(value, key, obj)) result[key] = value; - } - return result; - }); - - // Return a copy of the object without the blacklisted properties. - _.omit = restArguments(function(obj, keys) { - var iteratee = keys[0], context; - if (_.isFunction(iteratee)) { - iteratee = _.negate(iteratee); - if (keys.length > 1) context = keys[1]; - } else { - keys = _.map(flatten(keys, false, false), String); - iteratee = function(value, key) { - return !_.contains(keys, key); - }; - } - return _.pick(obj, iteratee, context); - }); - - // Fill in a given object with default properties. - _.defaults = createAssigner(_.allKeys, true); - - // Creates an object that inherits from the given prototype object. - // If additional properties are provided then they will be added to the - // created object. - _.create = function(prototype, props) { - var result = baseCreate(prototype); - if (props) _.extendOwn(result, props); - return result; - }; - - // Create a (shallow-cloned) duplicate of an object. - _.clone = function(obj) { - if (!_.isObject(obj)) return obj; - return _.isArray(obj) ? obj.slice() : _.extend({}, obj); - }; - - // Invokes interceptor with the obj, and then returns obj. - // The primary purpose of this method is to "tap into" a method chain, in - // order to perform operations on intermediate results within the chain. - _.tap = function(obj, interceptor) { - interceptor(obj); - return obj; - }; - - // Returns whether an object has a given set of `key:value` pairs. - _.isMatch = function(object, attrs) { - var keys = _.keys(attrs), length = keys.length; - if (object == null) return !length; - var obj = Object(object); - for (var i = 0; i < length; i++) { - var key = keys[i]; - if (attrs[key] !== obj[key] || !(key in obj)) return false; - } - return true; - }; - - - // Internal recursive comparison function for `isEqual`. - var eq, deepEq; - eq = function(a, b, aStack, bStack) { - // Identical objects are equal. `0 === -0`, but they aren't identical. - // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). - if (a === b) return a !== 0 || 1 / a === 1 / b; - // `null` or `undefined` only equal to itself (strict comparison). - if (a == null || b == null) return false; - // `NaN`s are equivalent, but non-reflexive. - if (a !== a) return b !== b; - // Exhaust primitive checks - var type = typeof a; - if (type !== 'function' && type !== 'object' && typeof b != 'object') return false; - return deepEq(a, b, aStack, bStack); - }; - - // Internal recursive comparison function for `isEqual`. - deepEq = function(a, b, aStack, bStack) { - // Unwrap any wrapped objects. - if (a instanceof _) a = a._wrapped; - if (b instanceof _) b = b._wrapped; - // Compare `[[Class]]` names. - var className = toString.call(a); - if (className !== toString.call(b)) return false; - switch (className) { - // Strings, numbers, regular expressions, dates, and booleans are compared by value. - case '[object RegExp]': - // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') - case '[object String]': - // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is - // equivalent to `new String("5")`. - return '' + a === '' + b; - case '[object Number]': - // `NaN`s are equivalent, but non-reflexive. - // Object(NaN) is equivalent to NaN. - if (+a !== +a) return +b !== +b; - // An `egal` comparison is performed for other numeric values. - return +a === 0 ? 1 / +a === 1 / b : +a === +b; - case '[object Date]': - case '[object Boolean]': - // Coerce dates and booleans to numeric primitive values. Dates are compared by their - // millisecond representations. Note that invalid dates with millisecond representations - // of `NaN` are not equivalent. - return +a === +b; - case '[object Symbol]': - return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b); - } - - var areArrays = className === '[object Array]'; - if (!areArrays) { - if (typeof a != 'object' || typeof b != 'object') return false; - - // Objects with different constructors are not equivalent, but `Object`s or `Array`s - // from different frames are. - var aCtor = a.constructor, bCtor = b.constructor; - if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && - _.isFunction(bCtor) && bCtor instanceof bCtor) - && ('constructor' in a && 'constructor' in b)) { - return false; - } - } - // Assume equality for cyclic structures. The algorithm for detecting cyclic - // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. - - // Initializing stack of traversed objects. - // It's done here since we only need them for objects and arrays comparison. - aStack = aStack || []; - bStack = bStack || []; - var length = aStack.length; - while (length--) { - // Linear search. Performance is inversely proportional to the number of - // unique nested structures. - if (aStack[length] === a) return bStack[length] === b; - } - - // Add the first object to the stack of traversed objects. - aStack.push(a); - bStack.push(b); - - // Recursively compare objects and arrays. - if (areArrays) { - // Compare array lengths to determine if a deep comparison is necessary. - length = a.length; - if (length !== b.length) return false; - // Deep compare the contents, ignoring non-numeric properties. - while (length--) { - if (!eq(a[length], b[length], aStack, bStack)) return false; - } - } else { - // Deep compare objects. - var keys = _.keys(a), key; - length = keys.length; - // Ensure that both objects contain the same number of properties before comparing deep equality. - if (_.keys(b).length !== length) return false; - while (length--) { - // Deep compare each member - key = keys[length]; - if (!(has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; - } - } - // Remove the first object from the stack of traversed objects. - aStack.pop(); - bStack.pop(); - return true; - }; - - // Perform a deep comparison to check if two objects are equal. - _.isEqual = function(a, b) { - return eq(a, b); - }; - - // Is a given array, string, or object empty? - // An "empty" object has no enumerable own-properties. - _.isEmpty = function(obj) { - if (obj == null) return true; - if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; - return _.keys(obj).length === 0; - }; - - // Is a given value a DOM element? - _.isElement = function(obj) { - return !!(obj && obj.nodeType === 1); - }; - - // Is a given value an array? - // Delegates to ECMA5's native Array.isArray - _.isArray = nativeIsArray || function(obj) { - return toString.call(obj) === '[object Array]'; - }; - - // Is a given variable an object? - _.isObject = function(obj) { - var type = typeof obj; - return type === 'function' || type === 'object' && !!obj; - }; - - // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError, isMap, isWeakMap, isSet, isWeakSet. - _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error', 'Symbol', 'Map', 'WeakMap', 'Set', 'WeakSet'], function(name) { - _['is' + name] = function(obj) { - return toString.call(obj) === '[object ' + name + ']'; - }; - }); - - // Define a fallback version of the method in browsers (ahem, IE < 9), where - // there isn't any inspectable "Arguments" type. - if (!_.isArguments(arguments)) { - _.isArguments = function(obj) { - return has(obj, 'callee'); - }; - } - - // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8, - // IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236). - var nodelist = root.document && root.document.childNodes; - if (typeof /./ != 'function' && typeof Int8Array != 'object' && typeof nodelist != 'function') { - _.isFunction = function(obj) { - return typeof obj == 'function' || false; - }; - } - - // Is a given object a finite number? - _.isFinite = function(obj) { - return !_.isSymbol(obj) && isFinite(obj) && !isNaN(parseFloat(obj)); - }; - - // Is the given value `NaN`? - _.isNaN = function(obj) { - return _.isNumber(obj) && isNaN(obj); - }; - - // Is a given value a boolean? - _.isBoolean = function(obj) { - return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; - }; - - // Is a given value equal to null? - _.isNull = function(obj) { - return obj === null; - }; - - // Is a given variable undefined? - _.isUndefined = function(obj) { - return obj === void 0; - }; - - // Shortcut function for checking if an object has a given property directly - // on itself (in other words, not on a prototype). - _.has = function(obj, path) { - if (!_.isArray(path)) { - return has(obj, path); - } - var length = path.length; - for (var i = 0; i < length; i++) { - var key = path[i]; - if (obj == null || !hasOwnProperty.call(obj, key)) { - return false; - } - obj = obj[key]; - } - return !!length; - }; - - // Utility Functions - // ----------------- - - // Run Underscore.js in *noConflict* mode, returning the `_` variable to its - // previous owner. Returns a reference to the Underscore object. - _.noConflict = function() { - root._ = previousUnderscore; - return this; - }; - - // Keep the identity function around for default iteratees. - _.identity = function(value) { - return value; - }; - - // Predicate-generating functions. Often useful outside of Underscore. - _.constant = function(value) { - return function() { - return value; - }; - }; - - _.noop = function(){}; - - // Creates a function that, when passed an object, will traverse that object’s - // properties down the given `path`, specified as an array of keys or indexes. - _.property = function(path) { - if (!_.isArray(path)) { - return shallowProperty(path); - } - return function(obj) { - return deepGet(obj, path); - }; - }; - - // Generates a function for a given object that returns a given property. - _.propertyOf = function(obj) { - if (obj == null) { - return function(){}; - } - return function(path) { - return !_.isArray(path) ? obj[path] : deepGet(obj, path); - }; - }; - - // Returns a predicate for checking whether an object has a given set of - // `key:value` pairs. - _.matcher = _.matches = function(attrs) { - attrs = _.extendOwn({}, attrs); - return function(obj) { - return _.isMatch(obj, attrs); - }; - }; - - // Run a function **n** times. - _.times = function(n, iteratee, context) { - var accum = Array(Math.max(0, n)); - iteratee = optimizeCb(iteratee, context, 1); - for (var i = 0; i < n; i++) accum[i] = iteratee(i); - return accum; - }; - - // Return a random integer between min and max (inclusive). - _.random = function(min, max) { - if (max == null) { - max = min; - min = 0; - } - return min + Math.floor(Math.random() * (max - min + 1)); - }; - - // A (possibly faster) way to get the current timestamp as an integer. - _.now = Date.now || function() { - return new Date().getTime(); - }; - - // List of HTML entities for escaping. - var escapeMap = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '`': '`' - }; - var unescapeMap = _.invert(escapeMap); - - // Functions for escaping and unescaping strings to/from HTML interpolation. - var createEscaper = function(map) { - var escaper = function(match) { - return map[match]; - }; - // Regexes for identifying a key that needs to be escaped. - var source = '(?:' + _.keys(map).join('|') + ')'; - var testRegexp = RegExp(source); - var replaceRegexp = RegExp(source, 'g'); - return function(string) { - string = string == null ? '' : '' + string; - return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; - }; - }; - _.escape = createEscaper(escapeMap); - _.unescape = createEscaper(unescapeMap); - - // Traverses the children of `obj` along `path`. If a child is a function, it - // is invoked with its parent as context. Returns the value of the final - // child, or `fallback` if any child is undefined. - _.result = function(obj, path, fallback) { - if (!_.isArray(path)) path = [path]; - var length = path.length; - if (!length) { - return _.isFunction(fallback) ? fallback.call(obj) : fallback; - } - for (var i = 0; i < length; i++) { - var prop = obj == null ? void 0 : obj[path[i]]; - if (prop === void 0) { - prop = fallback; - i = length; // Ensure we don't continue iterating. - } - obj = _.isFunction(prop) ? prop.call(obj) : prop; - } - return obj; - }; - - // Generate a unique integer id (unique within the entire client session). - // Useful for temporary DOM ids. - var idCounter = 0; - _.uniqueId = function(prefix) { - var id = ++idCounter + ''; - return prefix ? prefix + id : id; - }; - - // By default, Underscore uses ERB-style template delimiters, change the - // following template settings to use alternative delimiters. - _.templateSettings = { - evaluate: /<%([\s\S]+?)%>/g, - interpolate: /<%=([\s\S]+?)%>/g, - escape: /<%-([\s\S]+?)%>/g - }; - - // When customizing `templateSettings`, if you don't want to define an - // interpolation, evaluation or escaping regex, we need one that is - // guaranteed not to match. - var noMatch = /(.)^/; - - // Certain characters need to be escaped so that they can be put into a - // string literal. - var escapes = { - "'": "'", - '\\': '\\', - '\r': 'r', - '\n': 'n', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; - - var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g; - - var escapeChar = function(match) { - return '\\' + escapes[match]; - }; - - // In order to prevent third-party code injection through - // `_.templateSettings.variable`, we test it against the following regular - // expression. It is intentionally a bit more liberal than just matching valid - // identifiers, but still prevents possible loopholes through defaults or - // destructuring assignment. - var bareIdentifier = /^\s*(\w|\$)+\s*$/; - - // JavaScript micro-templating, similar to John Resig's implementation. - // Underscore templating handles arbitrary delimiters, preserves whitespace, - // and correctly escapes quotes within interpolated code. - // NB: `oldSettings` only exists for backwards compatibility. - _.template = function(text, settings, oldSettings) { - if (!settings && oldSettings) settings = oldSettings; - settings = _.defaults({}, settings, _.templateSettings); - - // Combine delimiters into one regular expression via alternation. - var matcher = RegExp([ - (settings.escape || noMatch).source, - (settings.interpolate || noMatch).source, - (settings.evaluate || noMatch).source - ].join('|') + '|$', 'g'); - - // Compile the template source, escaping string literals appropriately. - var index = 0; - var source = "__p+='"; - text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { - source += text.slice(index, offset).replace(escapeRegExp, escapeChar); - index = offset + match.length; - - if (escape) { - source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; - } else if (interpolate) { - source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; - } else if (evaluate) { - source += "';\n" + evaluate + "\n__p+='"; - } - - // Adobe VMs need the match returned to produce the correct offset. - return match; - }); - source += "';\n"; - - var argument = settings.variable; - if (argument) { - // Insure against third-party code injection. - if (!bareIdentifier.test(argument)) throw new Error( - 'variable is not a bare identifier: ' + argument - ); - } else { - // If a variable is not specified, place data values in local scope. - source = 'with(obj||{}){\n' + source + '}\n'; - argument = 'obj'; - } - - source = "var __t,__p='',__j=Array.prototype.join," + - "print=function(){__p+=__j.call(arguments,'');};\n" + - source + 'return __p;\n'; - - var render; - try { - render = new Function(argument, '_', source); - } catch (e) { - e.source = source; - throw e; - } - - var template = function(data) { - return render.call(this, data, _); - }; - - // Provide the compiled source as a convenience for precompilation. - template.source = 'function(' + argument + '){\n' + source + '}'; - - return template; - }; - - // Add a "chain" function. Start chaining a wrapped Underscore object. - _.chain = function(obj) { - var instance = _(obj); - instance._chain = true; - return instance; - }; - - // OOP - // --------------- - // If Underscore is called as a function, it returns a wrapped object that - // can be used OO-style. This wrapper holds altered versions of all the - // underscore functions. Wrapped objects may be chained. - - // Helper function to continue chaining intermediate results. - var chainResult = function(instance, obj) { - return instance._chain ? _(obj).chain() : obj; - }; - - // Add your own custom functions to the Underscore object. - _.mixin = function(obj) { - _.each(_.functions(obj), function(name) { - var func = _[name] = obj[name]; - _.prototype[name] = function() { - var args = [this._wrapped]; - push.apply(args, arguments); - return chainResult(this, func.apply(_, args)); - }; - }); - return _; - }; - - // Add all of the Underscore functions to the wrapper object. - _.mixin(_); - - // Add all mutator Array functions to the wrapper. - _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { - var method = ArrayProto[name]; - _.prototype[name] = function() { - var obj = this._wrapped; - method.apply(obj, arguments); - if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0]; - return chainResult(this, obj); - }; - }); - - // Add all accessor Array functions to the wrapper. - _.each(['concat', 'join', 'slice'], function(name) { - var method = ArrayProto[name]; - _.prototype[name] = function() { - return chainResult(this, method.apply(this._wrapped, arguments)); - }; - }); - - // Extracts the result from a wrapped and chained object. - _.prototype.value = function() { - return this._wrapped; - }; - - // Provide unwrapping proxy for some methods used in engine operations - // such as arithmetic and JSON stringification. - _.prototype.valueOf = _.prototype.toJSON = _.prototype.value; - - _.prototype.toString = function() { - return String(this._wrapped); - }; - - // AMD registration happens at the end for compatibility with AMD loaders - // that may not enforce next-turn semantics on modules. Even though general - // practice for AMD registration is to be anonymous, underscore registers - // as a named module because, like jQuery, it is a base library that is - // popular enough to be bundled in a third party lib, but not be part of - // an AMD load request. Those cases could generate an error when an - // anonymous define() is called outside of a loader request. - if (typeof define == 'function' && define.amd) { - define('underscore', [], function() { - return _; - }); - } -}()); +var n="1.13.1",r="object"==typeof self&&self.self===self&&self||"object"==typeof global&&global.global===global&&global||Function("return this")()||{},t=Array.prototype,e=Object.prototype,u="undefined"!=typeof Symbol?Symbol.prototype:null,o=t.push,i=t.slice,a=e.toString,f=e.hasOwnProperty,c="undefined"!=typeof ArrayBuffer,l="undefined"!=typeof DataView,s=Array.isArray,p=Object.keys,v=Object.create,h=c&&ArrayBuffer.isView,y=isNaN,d=isFinite,g=!{toString:null}.propertyIsEnumerable("toString"),b=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"],m=Math.pow(2,53)-1;function j(n,r){return r=null==r?n.length-1:+r,function(){for(var t=Math.max(arguments.length-r,0),e=Array(t),u=0;u=0&&t<=m}}function J(n){return function(r){return null==r?void 0:r[n]}}var G=J("byteLength"),H=K(G),Q=/\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\]/;var X=c?function(n){return h?h(n)&&!q(n):H(n)&&Q.test(a.call(n))}:C(!1),Y=J("length");function Z(n,r){r=function(n){for(var r={},t=n.length,e=0;e":">",'"':""","'":"'","`":"`"},Cn=Ln($n),Kn=Ln(_n($n)),Jn=tn.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g},Gn=/(.)^/,Hn={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},Qn=/\\|'|\r|\n|\u2028|\u2029/g;function Xn(n){return"\\"+Hn[n]}var Yn=/^\s*(\w|\$)+\s*$/;var Zn=0;function nr(n,r,t,e,u){if(!(e instanceof r))return n.apply(t,u);var o=Mn(n.prototype),i=n.apply(o,u);return _(i)?i:o}var rr=j((function(n,r){var t=rr.placeholder,e=function(){for(var u=0,o=r.length,i=Array(o),a=0;a1)ur(a,r-1,t,e),u=e.length;else for(var f=0,c=a.length;f0&&(t=r.apply(this,arguments)),n<=1&&(r=null),t}}var lr=rr(cr,2);function sr(n,r,t){r=qn(r,t);for(var e,u=nn(n),o=0,i=u.length;o0?0:u-1;o>=0&&o0?a=o>=0?o:Math.max(o+f,a):f=o>=0?Math.min(o+1,f):o+f+1;else if(t&&o&&f)return e[o=t(e,u)]===u?o:-1;if(u!=u)return(o=r(i.call(e,a,f),$))>=0?o+a:-1;for(o=n>0?a:f-1;o>=0&&o0?0:i-1;for(u||(e=r[o?o[a]:a],a+=n);a>=0&&a=3;return r(n,Fn(t,u,4),e,o)}}var Ar=wr(1),xr=wr(-1);function Sr(n,r,t){var e=[];return r=qn(r,t),jr(n,(function(n,t,u){r(n,t,u)&&e.push(n)})),e}function Or(n,r,t){r=qn(r,t);for(var e=!er(n)&&nn(n),u=(e||n).length,o=0;o=0}var Br=j((function(n,r,t){var e,u;return D(r)?u=r:(r=Nn(r),e=r.slice(0,-1),r=r[r.length-1]),_r(n,(function(n){var o=u;if(!o){if(e&&e.length&&(n=In(n,e)),null==n)return;o=n[r]}return null==o?o:o.apply(n,t)}))}));function Nr(n,r){return _r(n,Rn(r))}function Ir(n,r,t){var e,u,o=-1/0,i=-1/0;if(null==r||"number"==typeof r&&"object"!=typeof n[0]&&null!=n)for(var a=0,f=(n=er(n)?n:jn(n)).length;ao&&(o=e);else r=qn(r,t),jr(n,(function(n,t,e){((u=r(n,t,e))>i||u===-1/0&&o===-1/0)&&(o=n,i=u)}));return o}function Tr(n,r,t){if(null==r||t)return er(n)||(n=jn(n)),n[Wn(n.length-1)];var e=er(n)?En(n):jn(n),u=Y(e);r=Math.max(Math.min(r,u),0);for(var o=u-1,i=0;i1&&(e=Fn(e,r[1])),r=an(n)):(e=qr,r=ur(r,!1,!1),n=Object(n));for(var u=0,o=r.length;u1&&(t=r[1])):(r=_r(ur(r,!1,!1),String),e=function(n,t){return!Er(r,t)}),Ur(n,e,t)}));function zr(n,r,t){return i.call(n,0,Math.max(0,n.length-(null==r||t?1:r)))}function Lr(n,r,t){return null==n||n.length<1?null==r||t?void 0:[]:null==r||t?n[0]:zr(n,n.length-r)}function $r(n,r,t){return i.call(n,null==r||t?1:r)}var Cr=j((function(n,r){return r=ur(r,!0,!0),Sr(n,(function(n){return!Er(r,n)}))})),Kr=j((function(n,r){return Cr(n,r)}));function Jr(n,r,t,e){A(r)||(e=t,t=r,r=!1),null!=t&&(t=qn(t,e));for(var u=[],o=[],i=0,a=Y(n);ir?(e&&(clearTimeout(e),e=null),a=c,i=n.apply(u,o),e||(u=o=null)):e||!1===t.trailing||(e=setTimeout(f,l)),i};return c.cancel=function(){clearTimeout(e),a=0,e=u=o=null},c},debounce:function(n,r,t){var e,u,o,i,a,f=function(){var c=zn()-u;r>c?e=setTimeout(f,r-c):(e=null,t||(i=n.apply(a,o)),e||(o=a=null))},c=j((function(c){return a=this,o=c,u=zn(),e||(e=setTimeout(f,r),t&&(i=n.apply(a,o))),i}));return c.cancel=function(){clearTimeout(e),e=o=a=null},c},wrap:function(n,r){return rr(r,n)},negate:fr,compose:function(){var n=arguments,r=n.length-1;return function(){for(var t=r,e=n[r].apply(this,arguments);t--;)e=n[t].call(this,e);return e}},after:function(n,r){return function(){if(--n<1)return r.apply(this,arguments)}},before:cr,once:lr,findKey:sr,findIndex:vr,findLastIndex:hr,sortedIndex:yr,indexOf:gr,lastIndexOf:br,find:mr,detect:mr,findWhere:function(n,r){return mr(n,Dn(r))},each:jr,forEach:jr,map:_r,collect:_r,reduce:Ar,foldl:Ar,inject:Ar,reduceRight:xr,foldr:xr,filter:Sr,select:Sr,reject:function(n,r,t){return Sr(n,fr(qn(r)),t)},every:Or,all:Or,some:Mr,any:Mr,contains:Er,includes:Er,include:Er,invoke:Br,pluck:Nr,where:function(n,r){return Sr(n,Dn(r))},max:Ir,min:function(n,r,t){var e,u,o=1/0,i=1/0;if(null==r||"number"==typeof r&&"object"!=typeof n[0]&&null!=n)for(var a=0,f=(n=er(n)?n:jn(n)).length;ae||void 0===t)return 1;if(tAbout — Netmaker 0.8.5 documentation - - - + About — Netmaker 0.9.0 documentation + + + @@ -81,7 +81,7 @@