.
675 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | SHELL=/bin/bash
2 |
3 | install:
4 | chmod +x occultist.sh
5 | cp occultist.sh /usr/local/bin/occultist
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Occultist
2 |
3 |
4 |
5 |
6 |
7 |
8 | Say goodbye to dependency hell!
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | Occultist dependency manager eliminates the dependency conflicts by isolating the dependencies of
18 | each Chaos spells within its own `spells/` directory.
19 |
20 | [Git](https://git-scm.com/), [Bash](https://www.gnu.org/software/bash/) and [jq](https://stedolan.github.io/jq/)
21 | required to be installed on your system to be able to use the `occultist` commands.
22 |
23 | On Linux and macOS `occultist` will install all the requirements automatically.
24 |
25 | On Windows, use [Git Bash](https://gitforwindows.org/) and install `jq` with [Chocolatey](https://chocolatey.org/): `choco install jq`
26 |
27 | Install **`occultist`** with:
28 |
29 | ```bash
30 | sudo curl -o /usr/local/bin/occultist \
31 | -L https://git.io/Jfv1u && \
32 | sudo chmod +x /usr/local/bin/occultist
33 | ```
34 |
35 | or clone this repository and run: `make`
36 |
37 |
38 |
39 | **Install** a spell:
40 |
41 | ```bash
42 | occultist install math
43 | ```
44 |
45 | Install a **specific version** of the spell:
46 |
47 | ```bash
48 | occultist install math 1.0.1
49 | ```
50 |
51 | Install a spell with **semantic versioning**:
52 |
53 | ```bash
54 | occultist install math 1.x.x
55 | ```
56 |
57 | Install a **specific branch** of the spell:
58 |
59 | ```bash
60 | occultist install math master
61 | ```
62 |
63 |
64 |
65 | Install [**the Chaos language**](https://chaos-lang.org/):
66 |
67 | ```bash
68 | sudo occultist install chaos
69 | ```
70 |
71 |
72 |
73 | **Upgrade** a spell:
74 |
75 | ```bash
76 | occultist upgrade math
77 | ```
78 |
79 | **Remove** a spell:
80 |
81 | ```bash
82 | occultist remove math
83 | ```
84 |
85 |
86 |
87 | **Initialize** a new spell repository:
88 |
89 | ```bash
90 | occultist init
91 | ```
92 |
93 | **Edit** the spell repository:
94 |
95 | ```bash
96 | occultist edit
97 | ```
98 |
99 | **Register** a new spell:
100 |
101 | ```bash
102 | occultist register
103 | ```
104 |
--------------------------------------------------------------------------------
/occultist.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # The spell definition file
4 | JSON_FILE='occultist.json'
5 | LOCK_FILE='occultist-lock.json'
6 | TRACKER_FILE='.occultist-tracker.json'
7 | TMP_FILE='.tmp.json'
8 | HOST='https://occultist.io'
9 | API_BASE="$HOST/api"
10 | PROGRAM='Occultist'
11 | PROGRAM_BINARY='occultist'
12 | PROGRAM_PATH=$(which occultist)
13 | PROGRAM_RAW_URL='https://raw.githubusercontent.com/chaos-lang/occultist/master/occultist.sh'
14 | LANGUAGE_NAME='the Chaos language'
15 | LANGUAGE_NAME_SHORT='Chaos'
16 | LANGUAGE_BINARY='chaos'
17 | LANGUAGE_PATH=$(which chaos)
18 | LANGUAGE_REPO='https://github.com/chaos-lang/chaos.git'
19 | DESCRIPTION="Dependency manager for $LANGUAGE_NAME"
20 | SPELLS_DIR_NAME='spells'
21 | THIS_DIR=$(pwd)
22 | DEPENDENCY_ROOT=$THIS_DIR
23 | COPYRIGHT_NOTICE='Copyright (C) 2019-2021 Chaos Language Development Authority '
24 | LICENSE='GNU General Public License v3.0'
25 | LICENSE_URL='https://raw.githubusercontent.com/chaos-lang/occultist/master/LICENSE'
26 |
27 | # Terminal colors
28 | RED='\033[0;31m'
29 | GREEN='\033[0;32m'
30 | YELLOW='\033[0;33m'
31 | NC='\033[0m' # No Color
32 | BOLD_RED='\033[1;31m'
33 | BOLD_YELLOW='\033[1;33m'
34 | BOLD_PURPLE='\033[1;35m'
35 | BOLD_NC='\033[1m'
36 | UNDERLINED_NC='\033[4m'
37 |
38 | uname_out="$(uname -s)"
39 | case "${uname_out}" in
40 | Linux*) PLATFORM=Linux;;
41 | Darwin*) PLATFORM=Mac;;
42 | CYGWIN*) PLATFORM=Cygwin;;
43 | MINGW*) PLATFORM=MinGw;;
44 | *) PLATFORM="UNKNOWN:${uname_out}"
45 | esac
46 |
47 | if [ ! "$PLATFORM" = "MinGw" ]; then
48 | SUDO='sudo '
49 | else
50 | SUDO=''
51 | fi
52 |
53 | if [ "$#" -lt 1 ] || [ $1 = "-l" ] || [ $1 = "--license" ]; then
54 | wget -q -O- $LICENSE_URL | less
55 | exit 0
56 | fi
57 |
58 | printf "${YELLOW}%s${NC} - %s - ${YELLOW}%s${NC}\n" "$PROGRAM" "$DESCRIPTION" "$HOST"
59 | # Program icon ANSI colors
60 | cat << "EOF"
61 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
62 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;234m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;232m.[39m[38;5;232m.[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;237m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
63 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;233m.[39m[38;5;235m,[39m[38;5;237m:[39m[38;5;239m;[39m[38;5;240mi[39m[38;5;240mi[39m[38;5;239m;[39m[38;5;237m:[39m[38;5;235m,[39m[38;5;233m.[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
64 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;232m [39m[38;5;233m.[39m[38;5;235m,[39m[38;5;237m:[39m[38;5;239mi[39m[38;5;241mi[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;241mi[39m[38;5;239mi[39m[38;5;237m:[39m[38;5;235m,[39m[38;5;233m.[39m[38;5;232m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
65 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;235m,[39m[38;5;238m;[39m[38;5;240mi[39m[38;5;241m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;241m1[39m[38;5;240mi[39m[38;5;238m;[39m[38;5;235m,[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
66 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;234m.[39m[38;5;241m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;241m1[39m[38;5;234m.[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
67 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;232m.[39m[38;5;239mi[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;241m1[39m[38;5;102m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;239mi[39m[38;5;232m.[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
68 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;238m;[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;102m1[39m[38;5;240mi[39m[38;5;59m;[39m[38;5;59m:[39m[38;5;235m,[39m[38;5;59m,[39m[38;5;59m,[39m[38;5;235m,[39m[38;5;59m:[39m[38;5;59m;[39m[38;5;240mi[39m[38;5;241m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;238m;[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
69 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;235m,[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;102mi[39m[38;5;239mi[39m[38;5;237m:[39m[38;5;59m,[39m[38;5;59m,[39m[38;5;59m,[39m[38;5;59m:[39m[38;5;102mi[39m[38;5;144mt[39m[38;5;181mL[39m[38;5;181mL[39m[38;5;144mt[39m[38;5;102mi[39m[38;5;59m:[39m[38;5;59m,[39m[38;5;59m,[39m[38;5;236m,[39m[38;5;59m:[39m[38;5;102m;[39m[38;5;241mi[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;235m,[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
70 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;233m.[39m[38;5;241mi[39m[38;5;241m1[39m[38;5;238m;[39m[38;5;236m:[39m[38;5;234m,[39m[38;5;58m.[39m[38;5;59m:[39m[38;5;59m:[39m[38;5;101mi[39m[38;5;144mt[39m[38;5;181mL[39m[38;5;187mC[39m[38;5;187mG[39m[38;5;187mG[39m[38;5;187mC[39m[38;5;187mC[39m[38;5;187mG[39m[38;5;187mG[39m[38;5;187mC[39m[38;5;181mL[39m[38;5;144mf[39m[38;5;101mi[39m[38;5;59m;[39m[38;5;59m:[39m[38;5;58m.[39m[38;5;234m,[39m[38;5;236m:[39m[38;5;238m;[39m[38;5;241m1[39m[38;5;241mi[39m[38;5;233m.[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
71 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;232m [39m[38;5;239m;[39m[38;5;242m1[39m[38;5;241mi[39m[38;5;236m:[39m[38;5;235m,[39m[38;5;16m [39m[38;5;59m;[39m[38;5;187mC[39m[38;5;138mt[39m[38;5;59m:[39m[38;5;59m:[39m[38;5;59m;[39m[38;5;59m:[39m[38;5;59m:[39m[38;5;59m:[39m[38;5;59m;[39m[38;5;59m;[39m[38;5;59m:[39m[38;5;59m:[39m[38;5;59m:[39m[38;5;59m;[39m[38;5;59m:[39m[38;5;59m:[39m[38;5;138mt[39m[38;5;187mC[39m[38;5;59m;[39m[38;5;16m [39m[38;5;235m,[39m[38;5;236m:[39m[38;5;241mi[39m[38;5;242m1[39m[38;5;239m;[39m[38;5;232m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
72 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;237m:[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;239m;[39m[38;5;16m [39m[38;5;101m;[39m[38;5;187mG[39m[38;5;187mG[39m[38;5;187mC[39m[38;5;181mC[39m[38;5;181mL[39m[38;5;187mC[39m[38;5;187mG[39m[38;5;187mG[39m[38;5;224mG[39m[38;5;224mG[39m[38;5;187mG[39m[38;5;187mG[39m[38;5;187mC[39m[38;5;181mL[39m[38;5;187mC[39m[38;5;187mC[39m[38;5;187mG[39m[38;5;187mG[39m[38;5;101m;[39m[38;5;16m [39m[38;5;239m;[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;237m:[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
73 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;235m,[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;239m;[39m[38;5;16m [39m[38;5;101mi[39m[38;5;230m0[39m[38;5;230m8[39m[38;5;230m8[39m[38;5;230m8[39m[38;5;230m8[39m[38;5;230m8[39m[38;5;230m8[39m[38;5;224m0[39m[38;5;101m;[39m[38;5;101m;[39m[38;5;224m0[39m[38;5;230m8[39m[38;5;230m8[39m[38;5;230m8[39m[38;5;230m8[39m[38;5;230m8[39m[38;5;230m8[39m[38;5;230m0[39m[38;5;101mi[39m[38;5;16m [39m[38;5;239m;[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;235m,[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
74 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;233m.[39m[38;5;238m;[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;241mi[39m[38;5;234m,[39m[38;5;16m.[39m[38;5;144mt[39m[38;5;224m0[39m[38;5;230m8[39m[38;5;230m8[39m[38;5;230m8[39m[38;5;230m8[39m[38;5;230m8[39m[38;5;224m0[39m[38;5;138m1[39m[38;5;138m1[39m[38;5;224m0[39m[38;5;230m8[39m[38;5;230m8[39m[38;5;230m8[39m[38;5;230m8[39m[38;5;230m8[39m[38;5;224m0[39m[38;5;144mt[39m[38;5;16m.[39m[38;5;234m,[39m[38;5;241mi[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;238m;[39m[38;5;233m.[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
75 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;235m,[39m[38;5;239m;[39m[38;5;241m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;241m1[39m[38;5;59m:[39m[38;5;16m.[39m[38;5;95m;[39m[38;5;187mC[39m[38;5;230m8[39m[38;5;230m8[39m[38;5;145mf[39m[38;5;138m1[39m[38;5;138m1[39m[38;5;138mt[39m[38;5;138mt[39m[38;5;138mt[39m[38;5;102mi[39m[38;5;102m1[39m[38;5;224m0[39m[38;5;230m8[39m[38;5;187mC[39m[38;5;95m;[39m[38;5;16m.[39m[38;5;237m:[39m[38;5;241m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;241m1[39m[38;5;239m;[39m[38;5;235m,[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
76 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;232m [39m[38;5;236m,[39m[38;5;239mi[39m[38;5;240mi[39m[38;5;241m1[39m[38;5;242m1[39m[38;5;239mi[39m[38;5;23m.[39m[38;5;59m,[39m[38;5;144mf[39m[38;5;224m0[39m[38;5;145mf[39m[38;5;138m1[39m[38;5;138m1[39m[38;5;138m1[39m[38;5;138m1[39m[38;5;138m1[39m[38;5;138mt[39m[38;5;145mf[39m[38;5;224m0[39m[38;5;144mf[39m[38;5;59m,[39m[38;5;17m.[39m[38;5;239mi[39m[38;5;242m1[39m[38;5;241m1[39m[38;5;240mi[39m[38;5;239mi[39m[38;5;236m,[39m[38;5;232m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
77 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;232m.[39m[38;5;234m.[39m[38;5;235m,[39m[38;5;236m:[39m[38;5;238m;[39m[38;5;239m;[39m[38;5;59m,[39m[38;5;16m.[39m[38;5;101mi[39m[38;5;187mG[39m[38;5;230m8[39m[38;5;230m8[39m[38;5;230m8[39m[38;5;230m8[39m[38;5;230m8[39m[38;5;230m8[39m[38;5;187mG[39m[38;5;101mi[39m[38;5;16m.[39m[38;5;235m,[39m[38;5;239m;[39m[38;5;238m;[39m[38;5;236m:[39m[38;5;235m,[39m[38;5;234m.[39m[38;5;232m.[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
78 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;232m.[39m[38;5;233m.[39m[38;5;16m [39m[38;5;16m [39m[38;5;59m,[39m[38;5;144mf[39m[38;5;187mC[39m[38;5;187mC[39m[38;5;187mC[39m[38;5;187mC[39m[38;5;144mf[39m[38;5;59m,[39m[38;5;16m [39m[38;5;232m [39m[38;5;233m.[39m[38;5;232m.[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
79 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;233m.[39m[38;5;235m,[39m[38;5;236m:[39m[38;5;237m:[39m[38;5;238m;[39m[38;5;238m;[39m[38;5;238m;[39m[38;5;238m;[39m[38;5;238m;[39m[38;5;237m;[39m[38;5;236m:[39m[38;5;234m,[39m[38;5;59m,[39m[38;5;16m.[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m.[39m[38;5;59m,[39m[38;5;234m,[39m[38;5;236m:[39m[38;5;238m;[39m[38;5;238m;[39m[38;5;238m;[39m[38;5;238m;[39m[38;5;238m;[39m[38;5;238m;[39m[38;5;237m:[39m[38;5;236m:[39m[38;5;235m,[39m[38;5;233m.[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
80 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;233m.[39m[38;5;237m:[39m[38;5;239mi[39m[38;5;241m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;241m1[39m[38;5;241mi[39m[38;5;240mi[39m[38;5;234m.[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m.[39m[38;5;240mi[39m[38;5;241mi[39m[38;5;241m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;241m1[39m[38;5;239mi[39m[38;5;237m:[39m[38;5;233m.[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
81 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;233m.[39m[38;5;238m;[39m[38;5;241m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;237m:[39m[38;5;16m [39m[38;5;100m;[39m[38;5;100m;[39m[38;5;16m [39m[38;5;237m:[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;241m1[39m[38;5;238m;[39m[38;5;233m.[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
82 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;235m,[39m[38;5;102mi[39m[38;5;102mi[39m[38;5;102m;[39m[38;5;59m;[39m[38;5;59m;[39m[38;5;66m;[39m[38;5;102mi[39m[38;5;102m1[39m[38;5;102m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;240mi[39m[38;5;16m [39m[38;5;58m,[39m[38;5;215mf[39m[38;5;215mf[39m[38;5;58m,[39m[38;5;16m [39m[38;5;240mi[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;102m1[39m[38;5;102mi[39m[38;5;66m;[39m[38;5;59m;[39m[38;5;59m;[39m[38;5;102m;[39m[38;5;102mi[39m[38;5;102mi[39m[38;5;235m,[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
83 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m.[39m[38;5;59m,[39m[38;5;59m,[39m[38;5;58m,[39m[38;5;58m:[39m[38;5;94m;[39m[38;5;100m;[39m[38;5;94m:[39m[38;5;58m,[39m[38;5;58m,[39m[38;5;59m,[39m[38;5;59m,[39m[38;5;59m:[39m[38;5;59m;[39m[38;5;102mi[39m[38;5;102mi[39m[38;5;241m1[39m[38;5;241m1[39m[38;5;59m,[39m[38;5;16m.[39m[38;5;179mt[39m[38;5;221mL[39m[38;5;221mL[39m[38;5;179mt[39m[38;5;16m.[39m[38;5;59m,[39m[38;5;241m1[39m[38;5;102m1[39m[38;5;102mi[39m[38;5;102mi[39m[38;5;59m;[39m[38;5;59m:[39m[38;5;59m,[39m[38;5;59m,[39m[38;5;58m,[39m[38;5;58m,[39m[38;5;94m:[39m[38;5;100m;[39m[38;5;94m;[39m[38;5;58m:[39m[38;5;58m,[39m[38;5;59m,[39m[38;5;59m,[39m[38;5;16m.[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
84 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;58m,[39m[38;5;94m:[39m[38;5;100m;[39m[38;5;136mi[39m[38;5;137mi[39m[38;5;137mi[39m[38;5;136mi[39m[38;5;100m;[39m[38;5;100m;[39m[38;5;136mi[39m[38;5;137mi[39m[38;5;137mi[39m[38;5;137mi[39m[38;5;136mi[39m[38;5;100m;[39m[38;5;94m:[39m[38;5;58m,[39m[38;5;58m,[39m[38;5;59m,[39m[38;5;59m.[39m[38;5;16m [39m[38;5;100m;[39m[38;5;221mL[39m[38;5;221mL[39m[38;5;221mL[39m[38;5;221mL[39m[38;5;100m;[39m[38;5;16m [39m[38;5;59m.[39m[38;5;59m,[39m[38;5;58m,[39m[38;5;58m,[39m[38;5;94m:[39m[38;5;100m;[39m[38;5;136mi[39m[38;5;137mi[39m[38;5;137mi[39m[38;5;137mi[39m[38;5;136mi[39m[38;5;100m;[39m[38;5;100m;[39m[38;5;136mi[39m[38;5;137mi[39m[38;5;137mi[39m[38;5;136mi[39m[38;5;100m;[39m[38;5;94m:[39m[38;5;58m,[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
85 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;58m.[39m[38;5;94m:[39m[38;5;58m,[39m[38;5;58m,[39m[38;5;58m.[39m[38;5;16m.[39m[38;5;16m [39m[38;5;232m.[39m[38;5;59m:[39m[38;5;59m:[39m[38;5;59m,[39m[38;5;59m,[39m[38;5;59m,[39m[38;5;58m,[39m[38;5;58m,[39m[38;5;58m:[39m[38;5;94m:[39m[38;5;100m;[39m[38;5;100m;[39m[38;5;94m:[39m[38;5;16m [39m[38;5;58m,[39m[38;5;215mf[39m[38;5;221mL[39m[38;5;221mL[39m[38;5;221mL[39m[38;5;221mL[39m[38;5;215mf[39m[38;5;58m,[39m[38;5;16m [39m[38;5;94m:[39m[38;5;100m;[39m[38;5;100m;[39m[38;5;94m:[39m[38;5;58m:[39m[38;5;58m,[39m[38;5;58m,[39m[38;5;58m,[39m[38;5;59m,[39m[38;5;59m,[39m[38;5;59m:[39m[38;5;59m:[39m[38;5;232m.[39m[38;5;16m [39m[38;5;16m.[39m[38;5;58m.[39m[38;5;58m,[39m[38;5;58m,[39m[38;5;94m:[39m[38;5;58m.[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
86 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;232m [39m[38;5;238m;[39m[38;5;241m1[39m[38;5;241m1[39m[38;5;102m1[39m[38;5;241mi[39m[38;5;102mi[39m[38;5;102mi[39m[38;5;102m;[39m[38;5;59m;[39m[38;5;59m:[39m[38;5;16m.[39m[38;5;16m [39m[38;5;16m [39m[38;5;52m.[39m[38;5;179mt[39m[38;5;221mL[39m[38;5;221mL[39m[38;5;221mL[39m[38;5;221mL[39m[38;5;221mL[39m[38;5;221mL[39m[38;5;179mt[39m[38;5;52m.[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m.[39m[38;5;59m:[39m[38;5;59m;[39m[38;5;102m;[39m[38;5;102mi[39m[38;5;102mi[39m[38;5;241mi[39m[38;5;241m1[39m[38;5;241m1[39m[38;5;241mi[39m[38;5;238m;[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
87 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;237m;[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;241m1[39m[38;5;241m1[39m[38;5;241mi[39m[38;5;240mi[39m[38;5;238m;[39m[38;5;234m,[39m[38;5;16m.[39m[38;5;94m:[39m[38;5;179mt[39m[38;5;215mL[39m[38;5;221mL[39m[38;5;221mL[39m[38;5;215mL[39m[38;5;179mt[39m[38;5;94m:[39m[38;5;16m.[39m[38;5;234m,[39m[38;5;238m;[39m[38;5;240mi[39m[38;5;241m1[39m[38;5;241m1[39m[38;5;241m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;237m:[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
88 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;236m:[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;241m1[39m[38;5;102m;[39m[38;5;59m,[39m[38;5;16m.[39m[38;5;94m:[39m[38;5;137m1[39m[38;5;137m1[39m[38;5;94m:[39m[38;5;16m.[39m[38;5;59m,[39m[38;5;102m;[39m[38;5;241m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;236m:[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
89 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;234m,[39m[38;5;241mi[39m[38;5;242m1[39m[38;5;242mi[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242mi[39m[38;5;102m;[39m[38;5;59m,[39m[38;5;16m.[39m[38;5;16m.[39m[38;5;59m,[39m[38;5;102m;[39m[38;5;242mi[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242m1[39m[38;5;242mi[39m[38;5;242m1[39m[38;5;241mi[39m[38;5;234m,[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
90 | [38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;237m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;243m.[39m[38;5;242m.[39m[38;5;59m [39m[38;5;59m [39m[38;5;242m.[39m[38;5;243m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;242m.[39m[38;5;237m.[39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m[38;5;16m [39m
91 | EOF
92 |
93 | echo -e "${BOLD_PURPLE}${COPYRIGHT_NOTICE}${NC}"
94 | echo -e "License: ${BOLD_PURPLE}${LICENSE}${NC}\n"
95 |
96 | spinner() {
97 | i=1
98 | sp="/-\|"
99 | echo -n ' '
100 | while true
101 | do
102 | printf "\b${sp:i++%${#sp}:1}"
103 | sleep .05
104 | done
105 | }
106 |
107 | mingw_is_admin() {
108 | net session > /dev/null 2>&1
109 | if [ $? -eq 0 ]; then echo "admin"
110 | else echo "user"; fi
111 | }
112 |
113 | get_latest_tag_or_default_branch() {
114 | local BRANCH
115 | BRANCH=$(git ls-remote --tags --refs ${1} | tail -n1 | sed 's/.*\///')
116 | if [ -z $BRANCH ]; then
117 | git init &> /dev/null
118 | BRANCH=$(git remote show ${1} | grep "HEAD branch" | cut -d ":" -f 2)
119 | BRANCH="${BRANCH:1}"
120 | fi
121 | echo $BRANCH
122 | }
123 |
124 | make_c() {
125 | if [ ! "$PLATFORM" = "MinGw" ]; then
126 | make $1 && return 0 || return 1
127 | else
128 | ./make.bat $1 && return 0 || return 1
129 | fi
130 | }
131 |
132 | install_language() {
133 | if [ ! "$PLATFORM" = "MinGw" ]; then
134 | if [ "$EUID" -ne 0 ]; then
135 | echo -e "${RED}To install ${LANGUAGE_NAME} you need to run this command as root!${NC}"
136 | exit 10
137 | fi
138 | else
139 | if [ ! "$(mingw_is_admin)" = "admin" ]; then
140 | echo -e "${RED}To install ${LANGUAGE_NAME} you need to run as administrator!${NC}"
141 | exit 10
142 | fi
143 | fi
144 |
145 | if [ -z $1 ]; then
146 | printf "Installing ${BOLD_PURPLE}${LANGUAGE_NAME}${NC} to the system\n"
147 | else
148 | VERSION=$1
149 | VERSION_ORIG=$VERSION
150 | if [[ $VERSION =~ ^[0-9x]+(\.[0-9x]+){0,3}$ ]] || [[ $VERSION =~ ^[0-9x]+(\.[0-9x]+){0,3}-.*$ ]] || [[ $VERSION =~ ^[0-9x]+(\.[0-9x]+){0,3}\+.*$ ]] || [[ $VERSION =~ ^[0-9x]+(\.[0-9x]+){0,3}\..*$ ]]; then
151 | VERSION="v$VERSION"
152 | VERSION=$(echo ${VERSION} | tr x \*)
153 | VERSION=$(git ls-remote --tags --refs ${LANGUAGE_REPO} | sed 's/.*\///' | grep ${VERSION} | tail -n1)
154 | if [ -z $VERSION ]; then
155 | echo -e "${RED}Installation is failed: ${BOLD_PURPLE}${LANGUAGE_NAME}${RED} version ${BOLD_PURPLE}${VERSION_ORIG}${RED} does not exists!${NC}"
156 | exit 13
157 | else
158 | VERSION_ORIG=${VERSION:1}
159 | fi
160 | printf "Installing ${BOLD_PURPLE}${LANGUAGE_NAME}${NC} version ${BOLD_PURPLE}${VERSION_ORIG}${NC} to the system\n"
161 | else
162 | printf "Installing ${BOLD_PURPLE}${LANGUAGE_NAME}${NC} branch ${BOLD_PURPLE}${VERSION_ORIG}${NC} to the system\n"
163 | fi
164 | fi
165 |
166 | spinner &
167 | SPINNER_PID=$!
168 |
169 | INSTALLATION_FAIL=false
170 | OUT_BUFFER=$(mktemp -t occultist-XXXXXXXXXX)
171 | LANGUAGE_CLONE_DIR="/tmp/$LANGUAGE_BINARY.$RANDOM"
172 |
173 | {
174 | if [ -z $VERSION ]; then
175 | BRANCH=$(get_latest_tag_or_default_branch ${LANGUAGE_REPO})
176 | else
177 | BRANCH=$VERSION
178 | fi
179 | git clone --depth=1 --branch $BRANCH $LANGUAGE_REPO $LANGUAGE_CLONE_DIR && \
180 | cd $LANGUAGE_CLONE_DIR && \
181 | if [ "$PLATFORM" = "Mac" ]; then
182 | sudo -u $SUDO_USER make requirements
183 | source ~/.bash_profile
184 | else
185 | make_c requirements
186 | fi
187 | make_c && \
188 | make_c install || INSTALLATION_FAIL=true
189 | cd $THIS_DIR
190 | rm -rf $LANGUAGE_CLONE_DIR
191 | } &> $OUT_BUFFER
192 |
193 | kill -9 $SPINNER_PID
194 | wait $SPINNER_PID 2>/dev/null
195 | printf "\b"
196 |
197 | if [ $INSTALLATION_FAIL = true ]; then
198 | cat $OUT_BUFFER
199 | echo -e "${RED}Installation is failed!${NC}"
200 | exit 11
201 | fi
202 |
203 | echo -e "${GREEN}Installation is successful.${NC}"
204 | return 0
205 | }
206 |
207 | uninstall_language() {
208 | if [ ! "$PLATFORM" = "MinGw" ]; then
209 | if [ "$EUID" -ne 0 ]; then
210 | echo -e "${RED}To uninstall ${LANGUAGE_NAME} you need to run this command as root!${NC}"
211 | exit 10
212 | fi
213 | else
214 | if [ ! "$(mingw_is_admin)" = "admin" ]; then
215 | echo -e "${RED}To uninstall ${LANGUAGE_NAME} you need to run as administrator!${NC}"
216 | exit 10
217 | fi
218 | fi
219 |
220 | UNINSTALLATION_FAIL=false
221 | rm $LANGUAGE_PATH || UNINSTALLATION_FAIL=true
222 | if [ $UNINSTALLATION_FAIL = true ]; then
223 | echo -e "${RED}Uninstallation is failed!${NC}"
224 | exit 12
225 | fi
226 | echo -e "${GREEN}Uninstallation is successful.${NC}"
227 | return 0
228 | }
229 |
230 | install_spell() {
231 | SPELL_NAME=$1
232 | if [ -z $3 ]; then
233 | VERSION=
234 | LOCK=$2
235 | else
236 | VERSION=$2
237 | LOCK=$3
238 | fi
239 | if [ -z $4 ]; then
240 | :
241 | else
242 | DEPENDENCY_ROOT=$4
243 | fi
244 |
245 | if [ ! -f $DEPENDENCY_ROOT/$TRACKER_FILE ]; then
246 | echo -e "[\n]" > $TRACKER_FILE
247 | fi
248 |
249 | if [ -z $VERSION ]; then
250 | printf "Installing spell: ${YELLOW}${SPELL_NAME}${NC}\n"
251 | else
252 | printf "Installing spell: ${YELLOW}${SPELL_NAME}${NC}:${YELLOW}${VERSION}${NC}\n"
253 | fi
254 |
255 | spinner &
256 | SPINNER_PID=$!
257 |
258 | RESPONSE=$(curl -s -w '%{http_code}' -X GET \
259 | $API_BASE/spell/$SPELL_NAME \
260 | -H 'cache-control: no-cache' \
261 | -H 'content-type: application/json')
262 |
263 | STATUS_CODE=$(echo $RESPONSE | tail -c 4)
264 | RESPONSE_LENGTH=${#RESPONSE}
265 | RESPONSE=${RESPONSE:0:RESPONSE_LENGTH-3}
266 | CLONE_FAIL=false
267 | BUILD_FAIL=false
268 |
269 | if [ $STATUS_CODE -eq 200 ]; then
270 | OUT_BUFFER=$(mktemp -t occultist-XXXXXXXXXX)
271 |
272 | {
273 | SPELL_REPO=$(echo ${RESPONSE} | jq -r '.repo')
274 |
275 | if [ -z $VERSION ]; then
276 | BRANCH=$(get_latest_tag_or_default_branch ${SPELL_REPO})
277 | BRANCH_ORIG=$BRANCH
278 | else
279 | if [[ $VERSION =~ ^[0-9x]+(\.[0-9x]+){0,3}$ ]] || [[ $VERSION =~ ^[0-9x]+(\.[0-9x]+){0,3}-.*$ ]] || [[ $VERSION =~ ^[0-9x]+(\.[0-9x]+){0,3}\+.*$ ]] || [[ $VERSION =~ ^[0-9x]+(\.[0-9x]+){0,3}\..*$ ]]; then
280 | BRANCH_ORIG="$VERSION"
281 | BRANCH="v$VERSION"
282 | BRANCH=$(echo ${BRANCH} | tr x \*)
283 | BRANCH=$(git ls-remote --tags --refs ${SPELL_REPO} | sed 's/.*\///' | grep ${BRANCH} | tail -n1)
284 | if [ -z $BRANCH ]; then
285 | BRANCH=$BRANCH_ORIG
286 | CLONE_FAIL=true
287 | fi
288 | else
289 | BRANCH=$VERSION
290 | BRANCH_ORIG=$VERSION
291 | fi
292 | fi
293 |
294 | SPELL_PATH=$(jq -r ".[] | select(.name == \"${SPELL_NAME}\") | select(.version == \"${BRANCH}\") | .path" ${DEPENDENCY_ROOT}/${TRACKER_FILE} | tail -n1)
295 |
296 | mkdir -p $SPELLS_DIR_NAME
297 | cd $SPELLS_DIR_NAME/
298 |
299 | if [ -z $SPELL_PATH ]; then
300 | if [ -d "$SPELL_NAME" ]; then rm -rf $SPELL_NAME; fi
301 | git clone --depth=1 --branch $BRANCH $SPELL_REPO $SPELL_NAME || CLONE_FAIL=true
302 | cd $SPELL_NAME
303 | rm -rf .git/
304 | spell_type=$(jq -r '.type' $JSON_FILE)
305 |
306 | cat $DEPENDENCY_ROOT/$TRACKER_FILE | jq -r ".[. | length] |= . + {\"name\": \"${SPELL_NAME}\"}" > $TMP_FILE && mv $TMP_FILE $DEPENDENCY_ROOT/$TRACKER_FILE
307 | cat $DEPENDENCY_ROOT/$TRACKER_FILE | jq -r ".[. | length - 1] |= . + {\"version\": \"${BRANCH}\"}" > $TMP_FILE && mv $TMP_FILE $DEPENDENCY_ROOT/$TRACKER_FILE
308 | cat $DEPENDENCY_ROOT/$TRACKER_FILE | jq -r ".[. | length - 1] |= . + {\"path\": \"${THIS_DIR}/${SPELLS_DIR_NAME}/${SPELL_NAME}\"}" > $TMP_FILE && mv $TMP_FILE $DEPENDENCY_ROOT/$TRACKER_FILE
309 |
310 | if [ $spell_type = "extension" ]; then
311 | make_c || BUILD_FAIL=true
312 | elif [ $spell_type = "module" ]; then
313 | $PROGRAM_BINARY install $PROGRAM_BINARY $DEPENDENCY_ROOT || BUILD_FAIL=true
314 | fi
315 | else
316 | ln -s $SPELL_PATH $SPELL_NAME
317 | fi
318 |
319 | cd $THIS_DIR
320 |
321 | if [ $CLONE_FAIL = false ] && [ $BUILD_FAIL = false ]; then
322 | if [ $LOCK = false ]; then
323 | cat $JSON_FILE | jq -r ".dependencies += {\"${SPELL_NAME}\": \"${BRANCH_ORIG}\"}" > $TMP_FILE && mv $TMP_FILE $JSON_FILE
324 | fi
325 | cat $LOCK_FILE | jq -r ".dependencies += {\"${SPELL_NAME}\": \"${BRANCH}\"}" > $TMP_FILE && mv $TMP_FILE $LOCK_FILE
326 | fi
327 | } &> $OUT_BUFFER
328 |
329 | kill -9 $SPINNER_PID
330 | wait $SPINNER_PID 2>/dev/null
331 | printf "\b"
332 |
333 | if [ $CLONE_FAIL = true ]; then
334 | echo -e "${RED}Installation of ${YELLOW}${SPELL_NAME}${RED} is failed: Version ${YELLOW}${BRANCH}${RED} does not exists!${NC}"
335 | exit 3
336 | elif [ $BUILD_FAIL = true ]; then
337 | rm -rf $SPELLS_DIR_NAME/$SPELL_NAME
338 | cat $OUT_BUFFER
339 | echo -e "${RED}Installation of ${YELLOW}${SPELL_NAME}${NC}:${YELLOW}${BRANCH}${RED} is failed: Build failure!${NC}"
340 | exit 4
341 | fi
342 |
343 | echo -e "${GREEN}The spell ${YELLOW}${SPELL_NAME}${NC}:${YELLOW}${BRANCH}${GREEN} is successfully installed.${NC}"
344 | curl -s -o /dev/null -X GET \
345 | $API_BASE/spell/install/$SPELL_NAME \
346 | -H 'cache-control: no-cache' \
347 | -H 'content-type: application/json'
348 | elif [ $STATUS_CODE -eq 404 ]; then
349 | kill -9 $SPINNER_PID
350 | wait $SPINNER_PID 2>/dev/null
351 | printf "\b"
352 | echo -e "${RED}Couldn't find ${YELLOW}${SPELL_NAME}${RED} in the spell index!${NC}"
353 | exit 5
354 | else
355 | kill -9 $SPINNER_PID
356 | wait $SPINNER_PID 2>/dev/null
357 | printf "\b"
358 | echo -e "${RED}Search for the spell is failed!${NC}"
359 | exit 6
360 | fi
361 |
362 | if [ -z $4 ]; then
363 | rm $DEPENDENCY_ROOT/$TRACKER_FILE
364 | fi
365 | }
366 |
367 | print_help_text() {
368 | read -r -d '' HELP_TEXT << EOF
369 |
370 | ${YELLOW}Usage:${NC}
371 | ${PROGRAM_BINARY} [options] [commands]
372 | ${PROGRAM_BINARY} ${GREEN}install${NC} [spell]
373 | ${PROGRAM_BINARY} ${GREEN}install${NC} [spell] [version]
374 | ${PROGRAM_BINARY} ${GREEN}install${NC} [spell] [branch]
375 | ${PROGRAM_BINARY} ${GREEN}upgrade${NC} [spell]
376 | ${PROGRAM_BINARY} ${RED}remove${NC} [spell]
377 | ${PROGRAM_BINARY} init
378 | ${PROGRAM_BINARY} edit
379 | ${PROGRAM_BINARY} ${YELLOW}register${NC}
380 |
381 | ${YELLOW}Special commands:${NC}
382 | ${BOLD_RED}${SUDO}${NC}${PROGRAM_BINARY} ${GREEN}install${NC} ${BOLD_PURPLE}${LANGUAGE_BINARY}${NC}
383 | ${BOLD_RED}${SUDO}${NC}${PROGRAM_BINARY} ${GREEN}upgrade${NC} ${BOLD_PURPLE}${LANGUAGE_BINARY}${NC}
384 | ${BOLD_RED}${SUDO}${NC}${PROGRAM_BINARY} ${RED}remove${NC} ${BOLD_PURPLE}${LANGUAGE_BINARY}${NC}
385 | ${BOLD_RED}${SUDO}${NC}${PROGRAM_BINARY} ${GREEN}upgrade${NC} ${BOLD_YELLOW}${PROGRAM_BINARY}${NC}
386 | ${BOLD_RED}${SUDO}${NC}${PROGRAM_BINARY} ${RED}remove${NC} ${BOLD_YELLOW}${PROGRAM_BINARY}${NC}
387 |
388 | ${YELLOW}Options:${NC}
389 | ${GREEN} -h, --help ${NC}Display this help message.
390 | ${GREEN} -l, --license ${NC}Display the license.
391 | ${GREEN} -n, --no-update ${NC}Disable check for updates.
392 |
393 | ${YELLOW}Command Descriptions:${NC}
394 | ${GREEN} install ${NC}Install a spell. Optionally specify version or branch.
395 | ${GREEN} upgrade ${NC}Upgrade the spell according to the version in ${JSON_FILE} file.
396 | ${GREEN} remove ${NC}Uninstall a spell.
397 | ${GREEN} init ${NC}Generate a new ${JSON_FILE} file automatically by answering the questions.
398 | ${GREEN} edit ${NC}Edit an existing ${JSON_FILE} file.
399 | ${GREEN} register ${NC}Register a new spell to The ${LANGUAGE_NAME_SHORT} Spell Index.
400 | EOF
401 | echo -e "$HELP_TEXT"
402 | exit 0
403 | }
404 |
405 | check_for_updates() {
406 | printf "Checking for updates...\n"
407 |
408 | spinner &
409 | SPINNER_PID=$!
410 |
411 | curl -s -o /tmp/${PROGRAM_BINARY} -L ${PROGRAM_RAW_URL}
412 | checksum1=$(md5sum ${PROGRAM_PATH} | awk '{ print $1 }')
413 | checksum2=$(md5sum /tmp/${PROGRAM_BINARY} | awk '{ print $1 }')
414 |
415 | kill -9 $SPINNER_PID
416 | wait $SPINNER_PID 2>/dev/null
417 | printf "\b"
418 |
419 | if [ ! "$checksum1" = "$checksum2" ]; then
420 | read -r -d '' UPGRADE_TEXT << EOF
421 | ${RED}A new version of ${PROGRAM} is available! Run:${NC}
422 |
423 | ${SUDO}${PROGRAM_BINARY} upgrade ${PROGRAM_BINARY}\n
424 | EOF
425 | echo -e "$UPGRADE_TEXT"
426 | exit 15
427 | else
428 | echo -e "${GREEN}${PROGRAM} is up to date.${NC}"
429 | fi
430 | }
431 |
432 | install_requirements() {
433 | if [[ "$OSTYPE" == "linux"* ]]; then
434 | if [ "$EUID" -ne 0 ]; then
435 | echo -e "${RED}There are missing requirements for ${PROGRAM}!${NC}"
436 | echo -e "${RED}To install the requirements you need to run this command as root!${NC}"
437 | exit 17
438 | fi
439 |
440 | printf "Installing requirements...\n"
441 |
442 | spinner &
443 | SPINNER_PID=$!
444 |
445 | {
446 | APT_CMD=$(which apt)
447 | APT_GET_CMD=$(which apt-get)
448 | YUM_CMD=$(which yum)
449 | DNF_CMD=$(which dnf)
450 | PACMAN_CMD=$(which pacman)
451 | APK_CMD=$(which apk)
452 |
453 | REQUIREMENTS='git jq curl'
454 |
455 | if [[ ! -z $APT_CMD ]]; then
456 | apt update && \
457 | apt install -y $REQUIREMENTS
458 | elif [[ ! -z $APT_GET_CMD ]]; then
459 | apt-get update && \
460 | apt-get install -y $REQUIREMENTS
461 | elif [[ ! -z $YUM_CMD ]]; then
462 | yum install -y $REQUIREMENTS
463 | elif [[ ! -z $DNF_CMD ]]; then
464 | dnf install -y $REQUIREMENTS
465 | elif [[ ! -z $PACMAN_CMD ]]; then
466 | pacman -Syu --noconfirm && \
467 | pacman -S --noconfirm $REQUIREMENTS
468 | elif [[ ! -z $APK_CMD ]]; then
469 | apk update && \
470 | apk add $REQUIREMENTS
471 | else
472 | echo "Error: Automatic detection of default package manager is failed!"
473 | exit 1;
474 | fi
475 | } &> /dev/null
476 |
477 | kill -9 $SPINNER_PID
478 | wait $SPINNER_PID 2>/dev/null
479 | printf "\b"
480 | elif [[ "$OSTYPE" == "darwin"* ]]; then
481 | printf "Installing requirements...\n"
482 |
483 | spinner &
484 | SPINNER_PID=$!
485 |
486 | {
487 | brew update
488 | brew install git jq md5sha1sum curl
489 | } &> /dev/null
490 |
491 | kill -9 $SPINNER_PID
492 | wait $SPINNER_PID 2>/dev/null
493 | printf "\b"
494 | fi
495 | }
496 |
497 | check_requirements() {
498 | which git &>/dev/null
499 | CHECK_GIT=$?
500 | which jq &>/dev/null
501 | CHECK_JQ=$?
502 | which md5sum &>/dev/null
503 | CHECK_MD5SUM=$?
504 | which curl &>/dev/null
505 | CHECK_CURL=$?
506 |
507 | if [ ! $CHECK_GIT -eq 0 ] || [ ! $CHECK_JQ -eq 0 ] || [ ! $CHECK_MD5SUM -eq 0 ] || [ ! $CHECK_CURL -eq 0 ]; then
508 | install_requirements
509 | fi
510 | }
511 |
512 | upgrade_dependency_manager() {
513 | if [ ! "$PLATFORM" = "MinGw" ]; then
514 | if [ "$EUID" -ne 0 ]; then
515 | echo -e "${RED}To remove ${PROGRAM} you need to run this command as root!${NC}"
516 | exit 16
517 | fi
518 | else
519 | if [ ! "$(mingw_is_admin)" = "admin" ]; then
520 | echo -e "${RED}To remove ${PROGRAM} you need to run as administrator!${NC}"
521 | exit 10
522 | fi
523 | fi
524 |
525 | printf "Upgrading ${YELLOW}${PROGRAM_BINARY}${NC}...\n"
526 |
527 | TMP_DOWNLOAD_PATH=$(mktemp -t occultist-XXXXXXXXXX)
528 |
529 | spinner &
530 | SPINNER_PID=$!
531 |
532 | curl -s -o ${TMP_DOWNLOAD_PATH} -L ${PROGRAM_RAW_URL}
533 |
534 | kill -9 $SPINNER_PID
535 | wait $SPINNER_PID 2>/dev/null
536 | printf "\b"
537 |
538 | echo -e "${GREEN}${PROGRAM} is successfully upgraded.${NC}"
539 | chmod u=rwx,g=rx,o=rx ${TMP_DOWNLOAD_PATH}
540 | mv ${TMP_DOWNLOAD_PATH} ${PROGRAM_PATH}
541 | }
542 |
543 | remove_dependency_manager() {
544 | if [ ! "$PLATFORM" = "MinGw" ]; then
545 | if [ "$EUID" -ne 0 ]; then
546 | echo -e "${RED}To upgrade ${PROGRAM} you need to run this command as root!${NC}"
547 | exit 16
548 | fi
549 | else
550 | if [ ! "$(mingw_is_admin)" = "admin" ]; then
551 | echo -e "${RED}To upgrade ${PROGRAM} you need to run as administrator!${NC}"
552 | exit 10
553 | fi
554 | fi
555 |
556 | REMOVE_FAIL=false
557 | rm $PROGRAM_PATH || REMOVE_FAIL=true
558 | if [ $REMOVE_FAIL = true ]; then
559 | echo -e "${RED}Failed to remove ${PROGRAM}!${NC}"
560 | exit 17
561 | fi
562 | echo -e "${GREEN}${PROGRAM} is successfully removed.${NC}"
563 | return 0
564 | }
565 |
566 | if [ "$#" -lt 1 ] || [ $1 = "-h" ] || [ $1 = "--help" ]; then
567 | print_help_text
568 | fi
569 |
570 | if [ "$#" -lt 2 ] || [ ! $1 = "upgrade" ] || [ ! $2 = "$PROGRAM_BINARY" ]; then
571 | check_requirements
572 | if [ "$1" = "-n" ] || [ "$1" = "--no-update" ]; then
573 | shift
574 | else
575 | check_for_updates
576 | fi
577 | fi
578 |
579 | # Create or edit $JSON_FILE
580 | if [ $1 = "init" ] || [ $1 = "edit" ] || [ $1 = "create" ]; then
581 | if [ ! -f $JSON_FILE ]; then
582 | echo -e "{\n}" > $JSON_FILE
583 | fi
584 | {
585 | if cat $JSON_FILE | jq -e 'has("dependencies")'; then
586 | :
587 | else
588 | cat $JSON_FILE | jq -r '. += {"dependencies": {}}' > $TMP_FILE && mv $TMP_FILE $JSON_FILE
589 | fi
590 | } &> /dev/null
591 |
592 | read -p "$(echo -e ${YELLOW}Spell name: ${NC}${BOLD_NC})" spell_name
593 | read -p "$(echo -e ${YELLOW}Spell version: ${NC}${BOLD_NC})" spell_version
594 | read -p "$(echo -e ${YELLOW}Spell description: ${NC}${BOLD_NC})" spell_description
595 |
596 | echo -e "${UNDERLINED_NC}Select the spell type${NC}"
597 | PS3="Pick an option: "
598 | options=("module" "extension")
599 | select opt in "${options[@]}"; do
600 | case "$REPLY" in
601 | 1 ) spell_type=$opt; echo -e "${YELLOW}Spell type: ${NC}${BOLD_NC}${opt}${NC}"; break;;
602 | 2 ) spell_type=$opt; echo -e "${YELLOW}Spell type: ${NC}${BOLD_NC}${opt}${NC}"; break;;
603 |
604 | *) echo "Invalid option. Try another one.";continue;;
605 | esac
606 | done
607 |
608 | read -p "$(echo -e ${YELLOW}License: ${NC}${BOLD_NC})" license
609 | read -p "$(echo -e ${YELLOW}Author name: ${NC}${BOLD_NC})" author_name
610 | read -p "$(echo -e ${YELLOW}Author email: ${NC}${BOLD_NC})" author_email
611 |
612 | echo -e "${UNDERLINED_NC}Select the author's role${NC}"
613 | PS3="Pick an option: "
614 | options=("maintainer" "developer")
615 | select opt in "${options[@]}"; do
616 | case "$REPLY" in
617 | 1 ) author_role=$opt; echo -e "${YELLOW}Author role: ${NC}${BOLD_NC}${opt}${NC}"; break;;
618 | 2 ) author_role=$opt; echo -e "${YELLOW}Author role: ${NC}${BOLD_NC}${opt}${NC}"; break;;
619 |
620 | *) echo "Invalid option. Try another one.";continue;;
621 | esac
622 | done
623 |
624 | cat $JSON_FILE | jq -r ". += {\"name\": \"${spell_name}\"}" > $TMP_FILE && mv $TMP_FILE $JSON_FILE
625 | cat $JSON_FILE | jq -r ". += {\"version\": \"${spell_version}\"}" > $TMP_FILE && mv $TMP_FILE $JSON_FILE
626 | cat $JSON_FILE | jq -r ". += {\"description\": \"${spell_description}\"}" > $TMP_FILE && mv $TMP_FILE $JSON_FILE
627 | cat $JSON_FILE | jq -r ". += {\"tags\": []}" > $TMP_FILE && mv $TMP_FILE $JSON_FILE
628 | cat $JSON_FILE | jq -r ". += {\"type\": \"${spell_type}\"}" > $TMP_FILE && mv $TMP_FILE $JSON_FILE
629 | cat $JSON_FILE | jq -r ". += {\"license\": \"${license}\"}" > $TMP_FILE && mv $TMP_FILE $JSON_FILE
630 | cat $JSON_FILE | jq -r ". += {\"authors\": []}" > $TMP_FILE && mv $TMP_FILE $JSON_FILE
631 | cat $JSON_FILE | jq -r ".authors[0] += {\"name\": \"${author_name}\"}" > $TMP_FILE && mv $TMP_FILE $JSON_FILE
632 | cat $JSON_FILE | jq -r ".authors[0] += {\"email\": \"${author_email}\"}" > $TMP_FILE && mv $TMP_FILE $JSON_FILE
633 | cat $JSON_FILE | jq -r ".authors[0] += {\"role\": \"${author_role}\"}" > $TMP_FILE && mv $TMP_FILE $JSON_FILE
634 |
635 | dependencies=$(jq -r '.dependencies' $JSON_FILE)
636 | jq -M "del(.dependencies)" $JSON_FILE > tmp && mv tmp $JSON_FILE
637 | cat $JSON_FILE | jq -r ". += {\"dependencies\": ${dependencies}}" > $TMP_FILE && mv $TMP_FILE $JSON_FILE
638 |
639 | # Register the spell
640 | elif [ $1 = "register" ]; then
641 | SPELL_NAME=$(jq -r '.name' $JSON_FILE)
642 | SPELL_VERSION=$(jq -r '.version' $JSON_FILE)
643 | SPELL_DESCRIPTION=$(jq -r '.description' $JSON_FILE)
644 | SPELL_TAGS_READABLE=$(jq -r '.tags | reduce .[1:][] as $i ("\(.[0])"; . + ", \($i)" )' $JSON_FILE)
645 | SPELL_TYPE=$(jq -r '.type' $JSON_FILE)
646 | SPELL_LICENSE=$(jq -r '.license' $JSON_FILE)
647 | SPELL_REPO=$(git config --get remote.origin.url)
648 | printf "%-20s ${YELLOW}%-20s${NC}\n" "Spell name:" "$SPELL_NAME"
649 | printf "%-20s ${YELLOW}%-20s${NC}\n" "Spell version:" "$SPELL_VERSION"
650 | printf "%-20s ${YELLOW}%-20s${NC}\n" "Spell description:" "$SPELL_DESCRIPTION"
651 | printf "%-20s ${YELLOW}%-20s${NC}\n" "Spell tags:" "$SPELL_TAGS_READABLE"
652 | printf "%-20s ${YELLOW}%-20s${NC}\n" "Spell type:" "$SPELL_TYPE"
653 | printf "%-20s ${YELLOW}%-20s${NC}\n" "Spell license:" "$SPELL_LICENSE"
654 | printf "%-20s ${YELLOW}%-20s${NC}\n" "Spell repository:" "$SPELL_REPO"
655 |
656 | spinner &
657 | SPINNER_PID=$!
658 |
659 | STATUS_CODE=$(curl -s -o /dev/null -w '%{http_code}' -X POST \
660 | $API_BASE/spell/create \
661 | -H 'cache-control: no-cache' \
662 | -H 'content-type: application/json' \
663 | -d "{
664 | \"name\": \"$SPELL_NAME\",
665 | \"repo\": \"$SPELL_REPO\"
666 | }")
667 |
668 | kill -9 $SPINNER_PID
669 | wait $SPINNER_PID 2>/dev/null
670 | printf "\b \n"
671 |
672 | if [ $STATUS_CODE -eq 200 ]; then
673 | echo -e "${GREEN}The spell is successfully registered!${NC}"
674 | exit 0
675 | elif [ $STATUS_CODE -eq 409 ]; then
676 | echo -e "${YELLOW}The spell is already registered!${NC}"
677 | exit 2
678 | else
679 | echo -e "${RED}Spell registration is failed!${NC}"
680 | exit 1
681 | fi
682 |
683 | # Install spells
684 | elif [ $1 = "install" ]; then
685 | if [ ! -f $JSON_FILE ]; then
686 | echo -e "{\n}" > $JSON_FILE
687 | fi
688 | {
689 | if cat $JSON_FILE | jq -e 'has("dependencies")'; then
690 | :
691 | else
692 | cat $JSON_FILE | jq -r '. += {"dependencies": {}}' > $TMP_FILE && mv $TMP_FILE $JSON_FILE
693 | fi
694 |
695 | LOCK=true
696 | if [ ! -f $LOCK_FILE ]; then
697 | echo -e "{\n}" > $LOCK_FILE
698 | LOCK=false
699 | fi
700 | if cat $LOCK_FILE | jq -e 'has("dependencies")'; then
701 | :
702 | else
703 | cat $LOCK_FILE | jq -r '. += {"dependencies": {}}' > $TMP_FILE && mv $TMP_FILE $LOCK_FILE
704 | fi
705 | } &> /dev/null
706 |
707 | # Install all the dependencies
708 | if [ -z $2 ] || [ $2 = "$PROGRAM_BINARY" ]; then
709 | if [ $LOCK = true ]; then
710 | SUBJECT_FILE=$LOCK_FILE
711 | else
712 | SUBJECT_FILE=$JSON_FILE
713 | fi
714 | while IFS== read -r key value; do
715 | install_spell $key $value $LOCK $3
716 | done < <(jq -r '.dependencies | to_entries | .[] | .key + "=" + .value ' $SUBJECT_FILE)
717 | # Install and save a specific spell
718 | else
719 | if [ $2 = $LANGUAGE_BINARY ]; then
720 | install_language $3
721 | else
722 | install_spell $2 $3 false
723 | fi
724 | fi
725 |
726 | # Upgrade the spells
727 | elif [ $1 = "upgrade" ]; then
728 | LOCK=false
729 | # Upgrade all the dependencies
730 | if [ -z $2 ]; then
731 | while IFS== read -r key value; do
732 | install_spell $key $value $LOCK
733 | done < <(jq -r '.dependencies | to_entries | .[] | .key + "=" + .value ' $JSON_FILE)
734 | # Upgrade and save a specific spell
735 | else
736 | if [ $2 = $LANGUAGE_BINARY ]; then
737 | install_language $3
738 | elif [ $2 = $PROGRAM_BINARY ]; then
739 | upgrade_dependency_manager
740 | else
741 | SPELL_NAME=$2
742 | BRANCH=$(jq -r ".dependencies.${SPELL_NAME}" $JSON_FILE)
743 | install_spell $SPELL_NAME $BRANCH $LOCK
744 | fi
745 | fi
746 |
747 | # Remove a spell
748 | elif [ $1 = "remove" ]; then
749 | LOCK=false
750 | if [ -z $2 ]; then
751 | echo -e "\n${RED}You have to specifiy a spell name!${NC}\n"
752 | exit 7
753 | else
754 | if [ $2 = $LANGUAGE_BINARY ]; then
755 | uninstall_language
756 | elif [ $2 = $PROGRAM_BINARY ]; then
757 | remove_dependency_manager
758 | else
759 | SPELL_NAME=$2
760 | IS_SPELL_EXISTS=false
761 | {
762 | IS_SPELL_EXISTS=$(cat $JSON_FILE | jq -e ".dependencies | has(\"${SPELL_NAME}\")")
763 | } &> /dev/null
764 | if [ $IS_SPELL_EXISTS = "true" ]; then
765 | cd $SPELLS_DIR_NAME/ && \
766 | rm -rf $SPELL_NAME && \
767 | cd $THIS_DIR && \
768 | rmdir $SPELLS_DIR_NAME/ &> /dev/null
769 | jq -M "del(.dependencies.${SPELL_NAME})" $LOCK_FILE > $TMP_FILE && mv $TMP_FILE $LOCK_FILE && \
770 | jq -M "del(.dependencies.${SPELL_NAME})" $JSON_FILE > $TMP_FILE && mv $TMP_FILE $JSON_FILE && \
771 | echo -e "${GREEN}The spell ${YELLOW}${SPELL_NAME}${GREEN} is successfully removed.${NC}" || \
772 | echo -e "${RED}Failed to remove spell ${YELLOW}${SPELL_NAME}${RED}!${NC}" || \
773 | exit 9
774 | else
775 | echo -e "${RED}Spell ${YELLOW}${SPELL_NAME}${RED} is already removed!${NC}"
776 | exit 8
777 | fi
778 | fi
779 | fi
780 | fi
781 |
--------------------------------------------------------------------------------