22 - python & all web labs
@@ -1,8 +1,10 @@
|
||||
M
|
||||
|
||||
M M M
|
||||
M M M
|
||||
M M M
|
||||
M M MMM
|
||||
MMMM
|
||||
MMM M M M
|
||||
M M
|
||||
MM M MM
|
||||
MM MMMMM
|
||||
|
||||
M M MMM
|
||||
M M
|
||||
M M MMM
|
||||
|
||||
@@ -1,65 +1,239 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import heapq
|
||||
import os
|
||||
import random
|
||||
|
||||
|
||||
def create_file():
|
||||
n = random.randint(5, 10)
|
||||
maze = []
|
||||
for _ in range(n):
|
||||
row = "".join(["M" if random.random() < 0.3 else " " for _ in range(n)])
|
||||
maze.append(row)
|
||||
with open("maze.txt", "w") as f:
|
||||
for row in maze:
|
||||
f.write(row + "\n")
|
||||
return n
|
||||
WALL = "M"
|
||||
|
||||
|
||||
def read_maze():
|
||||
with open("maze.txt") as f:
|
||||
maze = [list(line.rstrip("\n")) for line in f]
|
||||
return maze
|
||||
|
||||
|
||||
def solve(maze, x, y, xc, yc, visited, length, best):
|
||||
n = len(maze)
|
||||
if x < 0 or y < 0 or x >= n or y >= n:
|
||||
return
|
||||
if maze[x][y] == "M" or visited[x][y]:
|
||||
return
|
||||
if length >= best[0]:
|
||||
return
|
||||
if x == xc and y == yc:
|
||||
best[0] = min(best[0], length)
|
||||
return
|
||||
visited[x][y] = True
|
||||
solve(maze, x + 1, y, xc, yc, visited, length + 1, best)
|
||||
solve(maze, x - 1, y, xc, yc, visited, length + 1, best)
|
||||
solve(maze, x, y + 1, xc, yc, visited, length + 1, best)
|
||||
solve(maze, x, y - 1, xc, yc, visited, length + 1, best)
|
||||
visited[x][y] = False
|
||||
def _maze_path() -> str:
|
||||
return os.path.join(os.path.dirname(__file__), "maze.txt")
|
||||
|
||||
|
||||
def _read_int(
|
||||
prompt: str, *, min_value: int | None = None, max_value: int | None = None
|
||||
) -> int:
|
||||
while True:
|
||||
print("\n1 - создать лабиринт\n2 - решить\n0 - выход")
|
||||
try:
|
||||
c = input("Выбор: ")
|
||||
if c == "1":
|
||||
n = create_file()
|
||||
print("Файл создан. Размер:", n)
|
||||
elif c == "2":
|
||||
maze = read_maze()
|
||||
n = len(maze)
|
||||
x = int(input("Старт X: "))
|
||||
y = int(input("Старт Y: "))
|
||||
xc = int(input("Сыр X: "))
|
||||
yc = int(input("Сыр Y: "))
|
||||
visited = [[False] * n for _ in range(n)]
|
||||
best = [10**9]
|
||||
solve(maze, x, y, xc, yc, visited, 0, best)
|
||||
if best[0] == 10**9:
|
||||
print("Путь не найден")
|
||||
s = input(prompt).strip()
|
||||
except EOFError:
|
||||
raise
|
||||
try:
|
||||
v = int(s)
|
||||
except ValueError:
|
||||
print("Ошибка: нужно целое число.")
|
||||
continue
|
||||
if min_value is not None and v < min_value:
|
||||
print(f"Ошибка: число должно быть не меньше {min_value}.")
|
||||
continue
|
||||
if max_value is not None and v > max_value:
|
||||
print(f"Ошибка: число должно быть не больше {max_value}.")
|
||||
continue
|
||||
return v
|
||||
|
||||
|
||||
def _normalize_grid(rows: list[str], n: int) -> list[str]:
|
||||
if len(rows) != n:
|
||||
raise ValueError(f"Ожидалось {n} строк, получено {len(rows)}.")
|
||||
grid = [(r[:n] + (" " * max(0, n - len(r)))) for r in rows]
|
||||
return grid
|
||||
|
||||
|
||||
def read_maze_from_file(n: int) -> list[str]:
|
||||
path = _maze_path()
|
||||
if not os.path.exists(path):
|
||||
raise FileNotFoundError("Файл maze.txt не найден.")
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
rows = [ln.rstrip("\n") for ln in f.readlines()]
|
||||
rows = rows[:n]
|
||||
return _normalize_grid(rows, n)
|
||||
|
||||
|
||||
def write_maze_to_file(grid: list[str]) -> None:
|
||||
path = _maze_path()
|
||||
with open(path, "w", encoding="utf-8") as f:
|
||||
for r in grid:
|
||||
f.write(r + "\n")
|
||||
|
||||
|
||||
def print_maze_with_coords(grid: list[str]) -> None:
|
||||
n = len(grid)
|
||||
|
||||
# Заголовок столбцов
|
||||
print(" ", end="")
|
||||
for j in range(n):
|
||||
print(f"{j + 1:2}", end=" ")
|
||||
print()
|
||||
|
||||
# Лабиринт с номерами строк
|
||||
for i, row in enumerate(grid):
|
||||
print(f"{i + 1:2} ", end="")
|
||||
for cell in row:
|
||||
print(f" {cell if cell != ' ' else '.'}", end=" ")
|
||||
print()
|
||||
|
||||
|
||||
def _is_exit(grid: list[str], i: int, j: int) -> bool:
|
||||
n = len(grid)
|
||||
return (i == 0 or j == 0 or i == n - 1 or j == n - 1) and grid[i][j] != WALL
|
||||
|
||||
|
||||
def a_star_shortest_path(grid: list[str], start: tuple[int, int]) -> str:
|
||||
n = len(grid)
|
||||
sx, sy = start
|
||||
if not (0 <= sx < n and 0 <= sy < n):
|
||||
raise ValueError("Стартовые координаты вне лабиринта.")
|
||||
if grid[sx][sy] == WALL:
|
||||
raise ValueError("Стартовая клетка является стеной.")
|
||||
|
||||
exits = [(i, j) for i in range(n) for j in range(n) if _is_exit(grid, i, j)]
|
||||
if not exits:
|
||||
raise ValueError("В лабиринте нет выходов.")
|
||||
if _is_exit(grid, sx, sy):
|
||||
return ""
|
||||
|
||||
def h(i: int, j: int) -> int:
|
||||
return min(abs(i - ei) + abs(j - ej) for ei, ej in exits)
|
||||
|
||||
inf = 10**9
|
||||
gscore = [[inf] * n for _ in range(n)]
|
||||
gscore[sx][sy] = 0
|
||||
|
||||
prev: list[list[tuple[int, int] | None]] = [[None] * n for _ in range(n)]
|
||||
prev_move: list[list[str | None]] = [[None] * n for _ in range(n)]
|
||||
|
||||
heap: list[tuple[int, int, int, int]] = [(h(sx, sy), 0, sx, sy)]
|
||||
closed = [[False] * n for _ in range(n)]
|
||||
dirs = ((0, -1, "L"), (0, 1, "R"), (-1, 0, "U"), (1, 0, "D"))
|
||||
|
||||
while heap:
|
||||
_, g, i, j = heapq.heappop(heap)
|
||||
if closed[i][j]:
|
||||
continue
|
||||
closed[i][j] = True
|
||||
|
||||
if _is_exit(grid, i, j):
|
||||
path: list[str] = []
|
||||
ci, cj = i, j
|
||||
while (ci, cj) != (sx, sy):
|
||||
mv = prev_move[ci][cj]
|
||||
p = prev[ci][cj]
|
||||
if mv is None or p is None:
|
||||
raise RuntimeError("Ошибка восстановления пути.")
|
||||
path.append(mv)
|
||||
ci, cj = p
|
||||
path.reverse()
|
||||
return "".join(path)
|
||||
|
||||
for di, dj, mv in dirs:
|
||||
ni, nj = i + di, j + dj
|
||||
if not (0 <= ni < n and 0 <= nj < n):
|
||||
continue
|
||||
if grid[ni][nj] == WALL:
|
||||
continue
|
||||
ng = g + 1
|
||||
if ng < gscore[ni][nj]:
|
||||
gscore[ni][nj] = ng
|
||||
prev[ni][nj] = (i, j)
|
||||
prev_move[ni][nj] = mv
|
||||
heapq.heappush(heap, (ng + h(ni, nj), ng, ni, nj))
|
||||
|
||||
raise ValueError("Пути к выходу нет.")
|
||||
|
||||
|
||||
def _random_grid(n: int, wall_percent: int) -> list[str]:
|
||||
p = wall_percent / 100.0
|
||||
rows: list[str] = []
|
||||
for i in range(n):
|
||||
row_chars: list[str] = []
|
||||
for j in range(n):
|
||||
if random.random() < p:
|
||||
row_chars.append(WALL)
|
||||
else:
|
||||
print("Кратчайший путь:", best[0])
|
||||
elif c == "0":
|
||||
break
|
||||
except:
|
||||
print("Ошибка ввода")
|
||||
row_chars.append(" ")
|
||||
rows.append("".join(row_chars))
|
||||
return rows
|
||||
|
||||
|
||||
def _random_passage_cell(grid: list[str]) -> tuple[int, int]:
|
||||
n = len(grid)
|
||||
cells = [(i, j) for i in range(n) for j in range(n) if grid[i][j] != WALL]
|
||||
if not cells:
|
||||
raise ValueError("В лабиринте нет проходов.")
|
||||
return random.choice(cells)
|
||||
|
||||
|
||||
def generate_maze_file_interactive() -> None:
|
||||
n = _read_int("Введите N (1..15): ", min_value=1, max_value=15)
|
||||
wall_percent = _read_int(
|
||||
"Введите процент стен M (0..90): ", min_value=0, max_value=90
|
||||
)
|
||||
tries = 0
|
||||
while True:
|
||||
tries += 1
|
||||
grid = _random_grid(n, wall_percent)
|
||||
for j in range(n):
|
||||
if random.random() < 0.25:
|
||||
grid[0] = grid[0][:j] + " " + grid[0][j + 1 :]
|
||||
start = _random_passage_cell(grid)
|
||||
try:
|
||||
_ = a_star_shortest_path(grid, start)
|
||||
write_maze_to_file(grid)
|
||||
print(
|
||||
f"Файл maze.txt создан. N={n}. Старт: X={start[0] + 1} Y={start[1] + 1}."
|
||||
)
|
||||
print_maze_with_coords(grid)
|
||||
return
|
||||
except Exception:
|
||||
if tries >= 500:
|
||||
raise ValueError("Не удалось сгенерировать лабиринт.")
|
||||
|
||||
|
||||
def print_maze_file_interactive() -> None:
|
||||
n = _read_int("Введите N (1..15): ", min_value=1, max_value=15)
|
||||
grid = read_maze_from_file(n)
|
||||
print("maze.txt:")
|
||||
print_maze_with_coords(grid)
|
||||
|
||||
|
||||
def solve_from_file_interactive() -> None:
|
||||
n = _read_int("Введите N (1..15): ", min_value=1, max_value=15)
|
||||
grid = read_maze_from_file(n)
|
||||
print_maze_with_coords(grid)
|
||||
x = _read_int("Введите строку (1..N): ", min_value=1, max_value=n)
|
||||
y = _read_int("Введите колонку (1..N): ", min_value=1, max_value=n)
|
||||
start = (x - 1, y - 1)
|
||||
path = a_star_shortest_path(grid, start)
|
||||
print("Путь:", path)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
while True:
|
||||
print()
|
||||
print("Меню:")
|
||||
print("1) Создать лабиринт")
|
||||
print("2) Показать лабиринт")
|
||||
print("3) Найти путь")
|
||||
print("0) Выход")
|
||||
try:
|
||||
choice = input("Выберите пункт: ").strip()
|
||||
except EOFError:
|
||||
return
|
||||
try:
|
||||
if choice == "0":
|
||||
return
|
||||
if choice == "1":
|
||||
generate_maze_file_interactive()
|
||||
elif choice == "2":
|
||||
print_maze_file_interactive()
|
||||
elif choice == "3":
|
||||
solve_from_file_interactive()
|
||||
else:
|
||||
print("Неизвестный пункт меню.")
|
||||
except Exception as e:
|
||||
print(f"Ошибка: {e}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -1,37 +1,75 @@
|
||||
print("task: 6r\nВставка + и - между цифрами для получения числа N")
|
||||
# task: Счастливый билет
|
||||
# Дано шестизначное число и число N. Между цифрами можно вставлять +, -, ничего.
|
||||
# Нужно вывести все выражения, равные N, либо сообщение об отсутствии решений.
|
||||
|
||||
import itertools
|
||||
|
||||
|
||||
def generate(s, pos, expr, target, results):
|
||||
if pos == len(s):
|
||||
def generate_expressions(digits):
|
||||
ops = ["+", "-", ""]
|
||||
for comb in itertools.product(ops, repeat=5):
|
||||
expr = digits[0]
|
||||
for i in range(5):
|
||||
expr += comb[i] + digits[i + 1]
|
||||
yield expr
|
||||
|
||||
|
||||
def safe_eval(expr):
|
||||
try:
|
||||
if eval(expr) == target:
|
||||
results.append(expr + "=" + str(target))
|
||||
return eval(expr)
|
||||
except:
|
||||
pass
|
||||
return
|
||||
generate(s, pos + 1, expr + "+" + s[pos], target, results)
|
||||
generate(s, pos + 1, expr + "-" + s[pos], target, results)
|
||||
generate(s, pos + 1, expr + s[pos], target, results)
|
||||
return None
|
||||
|
||||
|
||||
def solve(ticket, target):
|
||||
results = []
|
||||
digits = list(ticket)
|
||||
for expr in generate_expressions(digits):
|
||||
val = safe_eval(expr)
|
||||
if val == target:
|
||||
results.append(f"{expr}={target}")
|
||||
return results
|
||||
|
||||
|
||||
def is_valid_ticket(ticket):
|
||||
return ticket.isdigit() and len(ticket) == 6 and int(ticket) > 0
|
||||
|
||||
|
||||
def is_valid_target(target):
|
||||
return target.isdigit() and 0 < int(target) < 10**9
|
||||
|
||||
|
||||
while True:
|
||||
print("\n1 - решить\n0 - выход")
|
||||
try:
|
||||
c = input("Выбор: ")
|
||||
if c == "1":
|
||||
s, target = input("Введите число и N: ").split()
|
||||
target = int(target)
|
||||
results = []
|
||||
generate(s, 1, s[0], target, results)
|
||||
with open("result.txt", "w") as f:
|
||||
if results:
|
||||
for r in results:
|
||||
print(r)
|
||||
f.write(r + "\n")
|
||||
else:
|
||||
print("Решение не существует")
|
||||
f.write("Решение не существует")
|
||||
elif c == "0":
|
||||
print("\nВыберите действие:")
|
||||
print("1 - Ввести данные")
|
||||
print("2 - Выход")
|
||||
|
||||
choice = input("Ваш выбор: ").strip()
|
||||
|
||||
if choice == "2":
|
||||
print("Выход из программы.")
|
||||
break
|
||||
except:
|
||||
print("Ошибка ввода")
|
||||
elif choice == "1":
|
||||
ticket = input("Введите шестизначный номер билета: ").strip()
|
||||
target = input("Введите число N (0 < N < 1e9): ").strip()
|
||||
|
||||
if not is_valid_ticket(ticket):
|
||||
print("Ошибка: билет должен быть шестизначным натуральным числом.")
|
||||
continue
|
||||
|
||||
if not is_valid_target(target):
|
||||
print("Ошибка: N должно быть натуральным числом (0 < N < 1e9).")
|
||||
continue
|
||||
|
||||
target = int(target)
|
||||
solutions = solve(ticket, target)
|
||||
|
||||
if solutions:
|
||||
print("\nНайденные решения:")
|
||||
for s in solutions:
|
||||
print(s)
|
||||
else:
|
||||
print("Решение не существует.")
|
||||
|
||||
else:
|
||||
print("Некорректный выбор. Попробуйте снова.")
|
||||
|
||||
29
labPython/lab21/task_1.py
Normal file
@@ -0,0 +1,29 @@
|
||||
import math
|
||||
|
||||
|
||||
def simple_gen5(lst):
|
||||
for x in lst:
|
||||
if x >= 0:
|
||||
yield math.sqrt(x)
|
||||
else:
|
||||
yield None
|
||||
|
||||
|
||||
while True:
|
||||
print("генерация квадратных корней")
|
||||
print("1 - Ввести список")
|
||||
print("0 - Выход")
|
||||
choice = input("Выбор: ")
|
||||
|
||||
if choice == "0":
|
||||
break
|
||||
|
||||
if choice == "1":
|
||||
try:
|
||||
data = list(map(int, input("Введите числа через пробел: ").split()))
|
||||
gen = simple_gen5(data)
|
||||
print("Результат:")
|
||||
for val in gen:
|
||||
print(val)
|
||||
except:
|
||||
print("Ошибка ввода")
|
||||
25
labPython/lab21/task_2.py
Normal file
@@ -0,0 +1,25 @@
|
||||
def filter_gen5(s):
|
||||
vowels = "aeiouAEIOU"
|
||||
for ch in s:
|
||||
if ch in vowels:
|
||||
yield ch
|
||||
|
||||
|
||||
while True:
|
||||
print("фильтрация гласных")
|
||||
print("1 - Ввести строку")
|
||||
print("0 - Выход")
|
||||
choice = input("Выбор: ")
|
||||
|
||||
if choice == "0":
|
||||
break
|
||||
|
||||
if choice == "1":
|
||||
try:
|
||||
s = input("Введите строку: ")
|
||||
gen = filter_gen5(s)
|
||||
print("Результат:")
|
||||
for ch in gen:
|
||||
print(ch)
|
||||
except:
|
||||
print("Ошибка")
|
||||
26
labPython/lab21/task_3.py
Normal file
@@ -0,0 +1,26 @@
|
||||
def calc_gen4(a, r):
|
||||
current = a
|
||||
while True:
|
||||
yield current
|
||||
current *= r
|
||||
|
||||
|
||||
while True:
|
||||
print("геометрическая прогрессия")
|
||||
print("1 - Запустить")
|
||||
print("0 - Выход")
|
||||
choice = input("Выбор: ")
|
||||
|
||||
if choice == "0":
|
||||
break
|
||||
|
||||
if choice == "1":
|
||||
try:
|
||||
a = float(input("Первый член: "))
|
||||
r = float(input("Знаменатель: "))
|
||||
n = int(input("Сколько элементов вывести: "))
|
||||
gen = calc_gen4(a, r)
|
||||
for _ in range(n):
|
||||
print(next(gen))
|
||||
except:
|
||||
print("Ошибка ввода")
|
||||
36
labPython/lab21/task_4.py
Normal file
@@ -0,0 +1,36 @@
|
||||
class SimpleIter4:
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
self.result = []
|
||||
evens = [data[i] for i in range(0, len(data), 2)][::-1]
|
||||
odds = [data[i] for i in range(1, len(data), 2)]
|
||||
self.result = evens + odds
|
||||
self.index = 0
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
if self.index >= len(self.result):
|
||||
raise StopIteration
|
||||
val = self.result[self.index]
|
||||
self.index += 1
|
||||
return val
|
||||
|
||||
|
||||
while True:
|
||||
print("1 - Ввести список")
|
||||
print("0 - Выход")
|
||||
choice = input("Выбор: ")
|
||||
|
||||
if choice == "0":
|
||||
break
|
||||
|
||||
if choice == "1":
|
||||
try:
|
||||
data = input("Введите элементы через пробел: ").split()
|
||||
it = SimpleIter4(data)
|
||||
for x in it:
|
||||
print(x)
|
||||
except:
|
||||
print("Ошибка")
|
||||
64
labPython/lab21/task_5.py
Normal file
@@ -0,0 +1,64 @@
|
||||
class Node:
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
self.next = None
|
||||
self.prev = None
|
||||
|
||||
|
||||
class DoublyCircularList:
|
||||
def __init__(self):
|
||||
self.head = None
|
||||
|
||||
def append(self, value):
|
||||
new_node = Node(value)
|
||||
if not self.head:
|
||||
self.head = new_node
|
||||
new_node.next = new_node
|
||||
new_node.prev = new_node
|
||||
else:
|
||||
tail = self.head.prev
|
||||
tail.next = new_node
|
||||
new_node.prev = tail
|
||||
new_node.next = self.head
|
||||
self.head.prev = new_node
|
||||
|
||||
def __iter__(self):
|
||||
return ReverseIterator(self.head)
|
||||
|
||||
|
||||
class ReverseIterator:
|
||||
def __init__(self, head):
|
||||
self.current = head.prev if head else None
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
if not self.current:
|
||||
raise StopIteration
|
||||
val = self.current.value
|
||||
self.current = self.current.prev
|
||||
return val
|
||||
|
||||
|
||||
while True:
|
||||
print("1 - Создать список и начать итерацию")
|
||||
print("0 - Выход")
|
||||
choice = input("Выбор: ")
|
||||
|
||||
if choice == "0":
|
||||
break
|
||||
|
||||
if choice == "1":
|
||||
try:
|
||||
data = input("Введите элементы через пробел: ").split()
|
||||
lst = DoublyCircularList()
|
||||
for x in data:
|
||||
lst.append(x)
|
||||
|
||||
it = iter(lst)
|
||||
n = int(input("Сколько элементов вывести: "))
|
||||
for _ in range(n):
|
||||
print(next(it))
|
||||
except:
|
||||
print("Ошибка")
|
||||
6
labPython/lab22/FileName
Normal file
@@ -0,0 +1,6 @@
|
||||
5
|
||||
1 1 0 1 1
|
||||
0 0 0 0 0
|
||||
0 1 1 1 0
|
||||
0 0 0 1 0
|
||||
0 0 1 1 1
|
||||
5
labPython/lab22/FileName1
Normal file
@@ -0,0 +1,5 @@
|
||||
4
|
||||
1 0 1 1
|
||||
1 0 0 1
|
||||
1 1 0 1
|
||||
1 1 0 0
|
||||
4
labPython/lab22/FileName2
Normal file
@@ -0,0 +1,4 @@
|
||||
3
|
||||
1 4
|
||||
1 3 4
|
||||
1 3 2 4
|
||||
70
labPython/lab22/task_1.py
Normal file
@@ -0,0 +1,70 @@
|
||||
print(
|
||||
"task: Graf2\nПостроение матрицы инцидентности неориентированного графа по матрице смежности"
|
||||
)
|
||||
|
||||
import random
|
||||
|
||||
|
||||
def create_file():
|
||||
n = random.randint(3, 6)
|
||||
with open("FileName1", "w") as f:
|
||||
f.write(str(n) + "\n")
|
||||
for i in range(n):
|
||||
row = []
|
||||
for j in range(n):
|
||||
if i == j:
|
||||
row.append("0")
|
||||
else:
|
||||
row.append(str(random.randint(0, 1)))
|
||||
f.write(" ".join(row) + "\n")
|
||||
|
||||
|
||||
def read_graph():
|
||||
try:
|
||||
with open("FileName1") as f:
|
||||
n = int(f.readline())
|
||||
a = [list(map(int, f.readline().split())) for _ in range(n)]
|
||||
return n, a
|
||||
except:
|
||||
return None, None
|
||||
|
||||
|
||||
def build_incidence(n, a):
|
||||
edges = []
|
||||
for i in range(n):
|
||||
for j in range(i, n):
|
||||
if a[i][j] != 0:
|
||||
edges.append((i, j))
|
||||
m = len(edges)
|
||||
b = [[0] * m for _ in range(n)]
|
||||
for idx, (i, j) in enumerate(edges):
|
||||
b[i][idx] = 1
|
||||
b[j][idx] = 1
|
||||
return m, b
|
||||
|
||||
|
||||
def write_result(n, m, b):
|
||||
with open("FileName2", "w") as f:
|
||||
f.write(f"{n} {m}\n")
|
||||
for row in b:
|
||||
f.write(" ".join(map(str, row)) + "\n")
|
||||
|
||||
|
||||
while True:
|
||||
print("\n1 - создать файл FileName1")
|
||||
print("2 - выполнить задачу (результат в FileName2)")
|
||||
print("0 - выход")
|
||||
c = input(">> ")
|
||||
if c == "1":
|
||||
create_file()
|
||||
print("FileName1 создан")
|
||||
elif c == "2":
|
||||
n, a = read_graph()
|
||||
if n is None:
|
||||
print("ошибка чтения FileName1")
|
||||
continue
|
||||
m, b = build_incidence(n, a)
|
||||
write_result(n, m, b)
|
||||
print("результат записан в FileName2")
|
||||
elif c == "0":
|
||||
break
|
||||
66
labPython/lab22/task_2.py
Normal file
@@ -0,0 +1,66 @@
|
||||
import random
|
||||
from collections import deque
|
||||
|
||||
|
||||
def create_file():
|
||||
n = random.randint(4, 7)
|
||||
with open("FileName", "w") as f:
|
||||
f.write(str(n) + "\n")
|
||||
for i in range(n):
|
||||
row = [str(random.randint(0, 1)) for _ in range(n)]
|
||||
f.write(" ".join(row) + "\n")
|
||||
|
||||
|
||||
def read_graph():
|
||||
try:
|
||||
with open("FileName") as f:
|
||||
n = int(f.readline())
|
||||
m = [list(map(int, f.readline().split())) for _ in range(n)]
|
||||
return n, m
|
||||
except:
|
||||
return None, None
|
||||
|
||||
|
||||
def bfs(n, m, start, L):
|
||||
dist = [-1] * n
|
||||
q = deque([start])
|
||||
dist[start] = 0
|
||||
while q:
|
||||
v = q.popleft()
|
||||
for u in range(n):
|
||||
if m[v][u] == 1 and dist[u] == -1:
|
||||
dist[u] = dist[v] + 1
|
||||
if dist[u] <= L:
|
||||
q.append(u)
|
||||
return {i for i in range(n) if dist[i] != -1 and dist[i] <= L}
|
||||
|
||||
|
||||
while True:
|
||||
print("\n1 - создать файл")
|
||||
print("2 - выполнить задачу")
|
||||
print("0 - выход")
|
||||
c = input(">> ")
|
||||
if c == "1":
|
||||
create_file()
|
||||
print("FileName создан")
|
||||
elif c == "2":
|
||||
n, m = read_graph()
|
||||
if n is None:
|
||||
print("ошибка чтения FileName")
|
||||
continue
|
||||
try:
|
||||
k1 = int(input("K1: ")) - 1
|
||||
k2 = int(input("K2: ")) - 1
|
||||
L = int(input("L: "))
|
||||
except:
|
||||
print("ошибка ввода")
|
||||
continue
|
||||
s1 = bfs(n, m, k1, L)
|
||||
s2 = bfs(n, m, k2, L)
|
||||
res = sorted([x + 1 for x in s1 & s2])
|
||||
if res:
|
||||
print("результат:", *res)
|
||||
else:
|
||||
print(-1)
|
||||
elif c == "0":
|
||||
break
|
||||
80
labPython/lab22/task_3.py
Normal file
@@ -0,0 +1,80 @@
|
||||
print(
|
||||
"task: Graf10\nПоиск всех маршрутов между городами с сортировкой по длине и лексикографически"
|
||||
)
|
||||
|
||||
import random
|
||||
|
||||
|
||||
def create_file():
|
||||
n = random.randint(4, 6)
|
||||
with open("FileName1", "w") as f:
|
||||
f.write(str(n) + "\n")
|
||||
for i in range(n):
|
||||
row = [str(random.randint(0, 1)) for _ in range(n)]
|
||||
f.write(" ".join(row) + "\n")
|
||||
|
||||
|
||||
def read_graph():
|
||||
try:
|
||||
with open("FileName1") as f:
|
||||
n = int(f.readline())
|
||||
m = [list(map(int, f.readline().split())) for _ in range(n)]
|
||||
return n, m
|
||||
except:
|
||||
return None, None
|
||||
|
||||
|
||||
def dfs(m, v, target, visited, path, all_paths):
|
||||
if v == target:
|
||||
all_paths.append(path[:])
|
||||
return
|
||||
for u in range(len(m)):
|
||||
if m[v][u] == 1 and u not in visited:
|
||||
visited.add(u)
|
||||
path.append(u)
|
||||
dfs(m, u, target, visited, path, all_paths)
|
||||
path.pop()
|
||||
visited.remove(u)
|
||||
|
||||
|
||||
def solve(n, m, k1, k2):
|
||||
paths = []
|
||||
dfs(m, k1, k2, {k1}, [k1], paths)
|
||||
paths.sort(key=lambda x: (len(x), x))
|
||||
return paths
|
||||
|
||||
|
||||
def write(paths):
|
||||
with open("FileName2", "w") as f:
|
||||
if not paths:
|
||||
f.write("-1\n")
|
||||
else:
|
||||
f.write(str(len(paths)) + "\n")
|
||||
for p in paths:
|
||||
f.write(" ".join(str(x + 1) for x in p) + "\n")
|
||||
|
||||
|
||||
while True:
|
||||
print("\n1 - создать файл FileName1")
|
||||
print("2 - выполнить задачу (результат в FileName2)")
|
||||
print("0 - выход")
|
||||
c = input(">> ")
|
||||
if c == "1":
|
||||
create_file()
|
||||
print("FileName1 создан")
|
||||
elif c == "2":
|
||||
n, m = read_graph()
|
||||
if n is None:
|
||||
print("ошибка чтения FileName1")
|
||||
continue
|
||||
try:
|
||||
k1 = int(input("K1: ")) - 1
|
||||
k2 = int(input("K2: ")) - 1
|
||||
except:
|
||||
print("ошибка ввода")
|
||||
continue
|
||||
paths = solve(n, m, k1, k2)
|
||||
write(paths)
|
||||
print("результат записан в FileName2")
|
||||
elif c == "0":
|
||||
break
|
||||
94
labWeb/kt_3/booking.html
Normal file
@@ -0,0 +1,94 @@
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Вокруг Света | Заявка</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<header class="site-header">
|
||||
<div class="container header-inner">
|
||||
<a class="logo" href="index.html">Вокруг Света</a>
|
||||
<button id="burger" class="burger" aria-label="Меню">☰</button>
|
||||
<nav id="siteNav" class="site-nav">
|
||||
<ul>
|
||||
<li><a href="index.html">Главная</a></li>
|
||||
<li><a href="news.html">Новости</a></li>
|
||||
<li><a href="cards.html">Направления</a></li>
|
||||
<li><a href="tours.html">Расписание</a></li>
|
||||
<li><a class="active" href="booking.html">Заявка</a></li>
|
||||
<li><a href="contacts.html">Контакты</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="container">
|
||||
<h1>Форма заявки на тур</h1>
|
||||
<p>Заполните заявку, и менеджер свяжется с вами для уточнения деталей и подбора оптимального варианта поездки.</p>
|
||||
<div class="card">
|
||||
<form id="bookingForm">
|
||||
<div>
|
||||
<label for="firstName">Имя</label>
|
||||
<input id="firstName" name="firstName" required>
|
||||
</div>
|
||||
<div>
|
||||
<label for="lastName">Фамилия</label>
|
||||
<input id="lastName" name="lastName" required>
|
||||
</div>
|
||||
<div>
|
||||
<label for="email">Email</label>
|
||||
<input id="email" type="email" name="email" required>
|
||||
</div>
|
||||
<div>
|
||||
<label for="phone">Телефон</label>
|
||||
<input id="phone" name="phone" required>
|
||||
</div>
|
||||
<div>
|
||||
<label for="city">Город вылета</label>
|
||||
<input id="city" name="city" required>
|
||||
</div>
|
||||
<div>
|
||||
<label for="direction">Направление</label>
|
||||
<select id="direction" name="direction">
|
||||
<option>Турция</option>
|
||||
<option>Италия</option>
|
||||
<option>Норвегия</option>
|
||||
<option>Исландия</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="startDate">Дата начала</label>
|
||||
<input id="startDate" type="date" name="startDate">
|
||||
</div>
|
||||
<div>
|
||||
<label for="endDate">Дата окончания</label>
|
||||
<input id="endDate" type="date" name="endDate">
|
||||
</div>
|
||||
<div>
|
||||
<label for="people">Количество человек</label>
|
||||
<input id="people" type="number" min="1" name="people">
|
||||
</div>
|
||||
<div>
|
||||
<label for="budget">Бюджет (руб.)</label>
|
||||
<input id="budget" type="number" min="10000" name="budget">
|
||||
</div>
|
||||
<div class="form-full">
|
||||
<label for="comment">Комментарий</label>
|
||||
<textarea id="comment" name="comment"></textarea>
|
||||
</div>
|
||||
<div class="form-full">
|
||||
<button class="btn" type="submit">Отправить</button>
|
||||
</div>
|
||||
</form>
|
||||
<div id="formResult" class="result">После отправки вы увидите краткую сводку по вашей заявке.</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="container">ООО "Вокруг Света" | Москва, ул. Примерная, 10 | +7 (900) 123-45-67 | info@tour-example.ru</div>
|
||||
</footer>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
49
labWeb/kt_3/cards.html
Normal file
@@ -0,0 +1,49 @@
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Вокруг Света | Направления</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<header class="site-header">
|
||||
<div class="container header-inner">
|
||||
<a class="logo" href="index.html">Вокруг Света</a>
|
||||
<button id="burger" class="burger" aria-label="Меню">☰</button>
|
||||
<nav id="siteNav" class="site-nav">
|
||||
<ul>
|
||||
<li><a href="index.html">Главная</a></li>
|
||||
<li><a href="news.html">Новости</a></li>
|
||||
<li><a class="active" href="cards.html">Направления</a></li>
|
||||
<li><a href="tours.html">Расписание</a></li>
|
||||
<li><a href="booking.html">Заявка</a></li>
|
||||
<li><a href="contacts.html">Контакты</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="container">
|
||||
<h1>Популярные направления</h1>
|
||||
<p>Подборка направлений для спокойного отдыха, активных поездок и насыщенных экскурсионных программ.</p>
|
||||
<section class="cards-flex">
|
||||
<article class="tour-card"><img src="images/photo1.jpg" alt=""><div class="tour-card-body"><h3>Турция</h3><p>Комфортные отели у моря, тёплый климат и удобный формат отдыха для всей семьи.</p></div></article>
|
||||
<article class="tour-card"><img src="images/photo2.jpeg" alt=""><div class="tour-card-body"><h3>Грузия</h3><p>Горные маршруты, уютные старые кварталы и национальная кухня с местным колоритом.</p></div></article>
|
||||
<article class="tour-card"><img src="images/photo3.jpeg" alt=""><div class="tour-card-body"><h3>Япония</h3><p>Технологичные мегаполисы, древние храмы и сезон цветения сакуры в лучших локациях.</p></div></article>
|
||||
<article class="tour-card"><img src="images/photo4.jpeg" alt=""><div class="tour-card-body"><h3>Италия</h3><p>Классические экскурсии, гастрономические маршруты и прогулки по историческим центрам.</p></div></article>
|
||||
<article class="tour-card"><img src="images/photo5.jpeg" alt=""><div class="tour-card-body"><h3>Исландия</h3><p>Ледники, вулканические пейзажи и насыщенная программа для любителей природы.</p></div></article>
|
||||
<article class="tour-card"><img src="images/photo6.jpeg" alt=""><div class="tour-card-body"><h3>Франция</h3><p>Париж, Прованс и Лазурный берег с насыщенными экскурсиями и свободным временем.</p></div></article>
|
||||
<article class="tour-card"><img src="images/photo7.webp" alt=""><div class="tour-card-body"><h3>Испания</h3><p>Пляжный сезон почти круглый год, яркие фестивали и интересные городские маршруты.</p></div></article>
|
||||
<article class="tour-card"><img src="images/photo8.jpg" alt=""><div class="tour-card-body"><h3>Норвегия</h3><p>Фьорды, северная природа и круизы с остановками в самых красивых портах.</p></div></article>
|
||||
<article class="tour-card"><img src="images/photo9.jpg" alt=""><div class="tour-card-body"><h3>Марокко</h3><p>Старинные медины, рынки ремесленников и поездки по пустынным ландшафтам.</p></div></article>
|
||||
<article class="tour-card"><img src="images/photo10.webp" alt=""><div class="tour-card-body"><h3>Португалия</h3><p>Атлантическое побережье, винные регионы и уютные города с богатой историей.</p></div></article>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="container">ООО "Вокруг Света" | Москва, ул. Примерная, 10 | +7 (900) 123-45-67 | info@tour-example.ru</div>
|
||||
</footer>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
44
labWeb/kt_3/contacts.html
Normal file
@@ -0,0 +1,44 @@
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Вокруг Света | Контакты</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<header class="site-header">
|
||||
<div class="container header-inner">
|
||||
<a class="logo" href="index.html">Вокруг Света</a>
|
||||
<button id="burger" class="burger" aria-label="Меню">☰</button>
|
||||
<nav id="siteNav" class="site-nav">
|
||||
<ul>
|
||||
<li><a href="index.html">Главная</a></li>
|
||||
<li><a href="news.html">Новости</a></li>
|
||||
<li><a href="cards.html">Направления</a></li>
|
||||
<li><a href="tours.html">Расписание</a></li>
|
||||
<li><a href="booking.html">Заявка</a></li>
|
||||
<li><a class="active" href="contacts.html">Контакты</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="container">
|
||||
<h1>Контакты</h1>
|
||||
<section class="card">
|
||||
<h2>Наш офис</h2>
|
||||
<p>Мы работаем ежедневно и помогаем подобрать туры для отпуска, командировок и семейных поездок.</p>
|
||||
<p><b>Адрес:</b> Москва, ул. Примерная, 10</p>
|
||||
<p><b>Телефон:</b> +7 (900) 123-45-67</p>
|
||||
<p><b>Email:</b> info@tour-example.ru</p>
|
||||
<p id="geoResult"></p>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="container">ООО "Вокруг Света" | Москва, ул. Примерная, 10 | +7 (900) 123-45-67 | info@tour-example.ru</div>
|
||||
</footer>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
7
labWeb/kt_3/figma-link.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Макет главной страницы в Figma:
|
||||
https://www.figma.com/file/example123/Vokrug-Sveta-Main-Page
|
||||
|
||||
Описание макета:
|
||||
- Первый экран с заголовком, текущей датой и кнопкой перехода к заявке
|
||||
- Блок с ключевыми преимуществами агентства
|
||||
- Секция со слайдером туристических направлений
|
||||
BIN
labWeb/kt_3/images/photo1.jpg
Normal file
|
After Width: | Height: | Size: 172 KiB |
BIN
labWeb/kt_3/images/photo10.webp
Normal file
|
After Width: | Height: | Size: 66 KiB |
BIN
labWeb/kt_3/images/photo2.jpeg
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
labWeb/kt_3/images/photo3.jpeg
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
labWeb/kt_3/images/photo4.jpeg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
labWeb/kt_3/images/photo5.jpeg
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
labWeb/kt_3/images/photo6.jpeg
Normal file
|
After Width: | Height: | Size: 9.7 KiB |
BIN
labWeb/kt_3/images/photo7.webp
Normal file
|
After Width: | Height: | Size: 76 KiB |
BIN
labWeb/kt_3/images/photo8.jpg
Normal file
|
After Width: | Height: | Size: 113 KiB |
BIN
labWeb/kt_3/images/photo9.jpg
Normal file
|
After Width: | Height: | Size: 77 KiB |
76
labWeb/kt_3/index.html
Normal file
@@ -0,0 +1,76 @@
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Вокруг Света | Главная</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<header class="site-header">
|
||||
<div class="container header-inner">
|
||||
<a class="logo" href="index.html">Вокруг Света</a>
|
||||
<button id="burger" class="burger" aria-label="Меню">☰</button>
|
||||
<nav id="siteNav" class="site-nav">
|
||||
<ul>
|
||||
<li><a class="active" href="index.html">Главная</a></li>
|
||||
<li><a href="news.html">Новости</a></li>
|
||||
<li><a href="cards.html">Направления</a></li>
|
||||
<li><a href="tours.html">Расписание</a></li>
|
||||
<li><a href="booking.html">Заявка</a></li>
|
||||
<li><a href="contacts.html">Контакты</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="container">
|
||||
<section class="hero">
|
||||
<h1>Туристическое агентство "Вокруг Света"</h1>
|
||||
<p>Помогаем подобрать поездки под ваш стиль отдыха: от коротких городских уикендов до больших путешествий на 10-14 дней.</p>
|
||||
<p><b>Сегодня:</b> <span id="todayDate"></span></p>
|
||||
<p>Макет главной страницы в Figma: <a href="#" title="Добавьте свою ссылку Figma">посмотреть</a></p>
|
||||
</section>
|
||||
|
||||
<section class="grid-home">
|
||||
<article class="card">
|
||||
<h2>Куда можно поехать</h2>
|
||||
<p>В каталоге есть пляжные, экскурсионные и комбинированные туры с разным бюджетом и длительностью.</p>
|
||||
<p>Мы обновляем подборку каждую неделю, чтобы в ней были только актуальные предложения.</p>
|
||||
</article>
|
||||
|
||||
<article class="card">
|
||||
<h2>Быстрые ссылки</h2>
|
||||
<ul>
|
||||
<li><a href="news.html">Открыть новости</a></li>
|
||||
<li><a href="booking.html">Оставить заявку</a></li>
|
||||
<li><a href="contacts.html">Наши контакты</a></li>
|
||||
</ul>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="card">
|
||||
<h2>Идеи для следующей поездки</h2>
|
||||
<div class="slider">
|
||||
<div class="slide active">
|
||||
<img src="images/photo1.jpg" alt="Горы">
|
||||
<div class="slide-caption">Горные приключения</div>
|
||||
</div>
|
||||
<div class="slide">
|
||||
<img src="images/photo10.webp" alt="Пляж">
|
||||
<div class="slide-caption">Пляжный отдых</div>
|
||||
</div>
|
||||
<div class="slide">
|
||||
<img src="images/photo8.jpg" alt="Город">
|
||||
<div class="slide-caption">Экскурсии по городам</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="container">ООО "Вокруг Света" | Москва, ул. Примерная, 10 | +7 (900) 123-45-67 | info@tour-example.ru</div>
|
||||
</footer>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
97
labWeb/kt_3/news.html
Normal file
@@ -0,0 +1,97 @@
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Вокруг Света | Новости</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<header class="site-header">
|
||||
<div class="container header-inner">
|
||||
<a class="logo" href="index.html">Вокруг Света</a>
|
||||
<button id="burger" class="burger" aria-label="Меню">☰</button>
|
||||
<nav id="siteNav" class="site-nav">
|
||||
<ul>
|
||||
<li><a href="index.html">Главная</a></li>
|
||||
<li><a class="active" href="news.html">Новости</a></li>
|
||||
<li><a href="cards.html">Направления</a></li>
|
||||
<li><a href="tours.html">Расписание</a></li>
|
||||
<li><a href="booking.html">Заявка</a></li>
|
||||
<li><a href="contacts.html">Контакты</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="container">
|
||||
<h1>Новости туризма</h1>
|
||||
<p>Следим за обновлениями в отрасли и публикуем важные изменения по направлениям, ценам и условиям поездок.</p>
|
||||
<section class="news-grid">
|
||||
<article class="news-item">
|
||||
<img src="images/photo1.jpg" alt="Новость 1">
|
||||
<div class="news-item-content">
|
||||
<h3>Открыт новый маршрут в Исландию</h3>
|
||||
<p>Маршрут включает ледники, водопады и вулканические зоны.</p>
|
||||
<button class="btn open-news" data-title="Открыт новый маршрут в Исландию" data-full="С мая 2026 года запускается недельный тур по Исландии с гидом. Программа включает экскурсии к водопадам, посещение ледниковой лагуны и наблюдение северного сияния в вечернее время.">Читать полностью</button>
|
||||
</div>
|
||||
</article>
|
||||
<article class="news-item">
|
||||
<img src="images/photo2.jpeg" alt="Новость 2">
|
||||
<div class="news-item-content">
|
||||
<h3>Снижены цены на летние туры</h3>
|
||||
<p>Раннее бронирование позволяет сэкономить до 25%.</p>
|
||||
<button class="btn open-news" data-title="Снижены цены на летние туры" data-full="До конца месяца действует акция на летние направления: Турция, Греция и Черногория. При бронировании заранее доступны расширенные условия отмены и бесплатный трансфер от аэропорта.">Читать полностью</button>
|
||||
</div>
|
||||
</article>
|
||||
<article class="news-item">
|
||||
<img src="images/photo3.jpeg" alt="Новость 3">
|
||||
<div class="news-item-content">
|
||||
<h3>Новые экскурсии по историческим местам</h3>
|
||||
<p>Добавлены программы с профессиональными гидами.</p>
|
||||
<button class="btn open-news" data-title="Новые экскурсии по историческим местам" data-full="В разделе экскурсионных туров появились новые маршруты по Европе и Азии. Участники смогут посетить музеи, архитектурные памятники и местные фестивали с русскоязычным сопровождением.">Читать полностью</button>
|
||||
</div>
|
||||
</article>
|
||||
<article class="news-item">
|
||||
<img src="images/photo4.jpeg" alt="Новость 4">
|
||||
<div class="news-item-content">
|
||||
<h3>Запущена программа семейных туров</h3>
|
||||
<p>Специальные условия для семей с детьми до 12 лет.</p>
|
||||
<button class="btn open-news" data-title="Запущена программа семейных туров" data-full="Новая программа ориентирована на спокойный отдых с детьми. В стоимость включены детские активности, анимация в отелях и скидки на второй номер для большой семьи.">Читать полностью</button>
|
||||
</div>
|
||||
</article>
|
||||
<article class="news-item">
|
||||
<img src="images/photo5.jpeg" alt="Новость 5">
|
||||
<div class="news-item-content">
|
||||
<h3>Появились зимние туры на Байкал</h3>
|
||||
<p>Катание на коньках, фототуры и горячие источники.</p>
|
||||
<button class="btn open-news" data-title="Появились зимние туры на Байкал" data-full="Компания подготовила зимнюю программу на Байкале: прозрачный лед, фотосессии, катание на снегоходах и посещение термальных источников. Доступны туры на 5 и 8 дней.">Читать полностью</button>
|
||||
</div>
|
||||
</article>
|
||||
<article class="news-item">
|
||||
<img src="images/photo6.jpeg" alt="Новость 6">
|
||||
<div class="news-item-content">
|
||||
<h3>Обновлены правила страхования</h3>
|
||||
<p>Включена расширенная медицинская поддержка.</p>
|
||||
<button class="btn open-news" data-title="Обновлены правила страхования" data-full="Во всех пакетных турах теперь действует обновленная страховка. Она покрывает экстренную медицинскую помощь, задержки рейсов и дополнительные расходы при вынужденном продлении поездки.">Читать полностью</button>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<div id="newsModal" class="modal-overlay">
|
||||
<div class="modal">
|
||||
<div class="modal-head">
|
||||
<h2 id="modalTitle">Новость</h2>
|
||||
<button id="closeModal" class="close-btn">Закрыть</button>
|
||||
</div>
|
||||
<p id="modalText"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="container">ООО "Вокруг Света" | Москва, ул. Примерная, 10 | +7 (900) 123-45-67 | info@tour-example.ru</div>
|
||||
</footer>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
117
labWeb/kt_3/script.js
Normal file
@@ -0,0 +1,117 @@
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const burger = document.getElementById("burger");
|
||||
const nav = document.getElementById("siteNav");
|
||||
if (burger && nav) {
|
||||
burger.addEventListener("click", function () {
|
||||
nav.classList.toggle("open");
|
||||
});
|
||||
}
|
||||
|
||||
const dateBox = document.getElementById("todayDate");
|
||||
if (dateBox) {
|
||||
const now = new Date();
|
||||
dateBox.textContent = now.toLocaleDateString("ru-RU", {
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
weekday: "long"
|
||||
});
|
||||
}
|
||||
|
||||
const slides = Array.from(document.querySelectorAll(".slide"));
|
||||
if (slides.length > 0) {
|
||||
let slideIndex = 0;
|
||||
setInterval(function () {
|
||||
slides[slideIndex].classList.remove("active");
|
||||
slideIndex = (slideIndex + 1) % slides.length;
|
||||
slides[slideIndex].classList.add("active");
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
const newsModal = document.getElementById("newsModal");
|
||||
const modalTitle = document.getElementById("modalTitle");
|
||||
const modalText = document.getElementById("modalText");
|
||||
const closeModalBtn = document.getElementById("closeModal");
|
||||
const newsButtons = document.querySelectorAll(".open-news");
|
||||
|
||||
if (newsModal && modalTitle && modalText && closeModalBtn && newsButtons.length) {
|
||||
newsButtons.forEach(function (btn) {
|
||||
btn.addEventListener("click", function () {
|
||||
modalTitle.textContent = btn.dataset.title || "Новость";
|
||||
modalText.textContent = btn.dataset.full || "";
|
||||
newsModal.classList.add("open");
|
||||
});
|
||||
});
|
||||
|
||||
closeModalBtn.addEventListener("click", function () {
|
||||
newsModal.classList.remove("open");
|
||||
});
|
||||
|
||||
newsModal.addEventListener("click", function (event) {
|
||||
if (event.target === newsModal) {
|
||||
newsModal.classList.remove("open");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const geoBtn = document.getElementById("geoBtn");
|
||||
const geoResult = document.getElementById("geoResult");
|
||||
if (geoBtn && geoResult) {
|
||||
geoBtn.addEventListener("click", function () {
|
||||
if (!navigator.geolocation) {
|
||||
geoResult.textContent = "Геолокация не поддерживается.";
|
||||
return;
|
||||
}
|
||||
geoResult.textContent = "Определяем координаты...";
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
function (position) {
|
||||
const lat = position.coords.latitude.toFixed(5);
|
||||
const lon = position.coords.longitude.toFixed(5);
|
||||
geoResult.textContent = "Ваши координаты: " + lat + ", " + lon;
|
||||
},
|
||||
function () {
|
||||
geoResult.textContent = "Не удалось получить геолокацию.";
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
const bookingForm = document.getElementById("bookingForm");
|
||||
const formResult = document.getElementById("formResult");
|
||||
if (bookingForm && formResult) {
|
||||
const saved = localStorage.getItem("bookingData");
|
||||
if (saved) {
|
||||
const parsed = JSON.parse(saved);
|
||||
for (const key in parsed) {
|
||||
const el = bookingForm.elements[key];
|
||||
if (el) {
|
||||
el.value = parsed[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bookingForm.addEventListener("submit", function (event) {
|
||||
event.preventDefault();
|
||||
const formData = new FormData(bookingForm);
|
||||
const dataObj = {};
|
||||
formData.forEach(function (value, key) {
|
||||
dataObj[key] = value;
|
||||
});
|
||||
|
||||
localStorage.setItem("bookingData", JSON.stringify(dataObj));
|
||||
formResult.innerHTML =
|
||||
"<h3>Результат обработки формы</h3>" +
|
||||
"<p><b>Имя:</b> " + (dataObj.firstName || "") + "</p>" +
|
||||
"<p><b>Фамилия:</b> " + (dataObj.lastName || "") + "</p>" +
|
||||
"<p><b>Email:</b> " + (dataObj.email || "") + "</p>" +
|
||||
"<p><b>Телефон:</b> " + (dataObj.phone || "") + "</p>" +
|
||||
"<p><b>Город вылета:</b> " + (dataObj.city || "") + "</p>" +
|
||||
"<p><b>Направление:</b> " + (dataObj.direction || "") + "</p>" +
|
||||
"<p><b>Дата старта:</b> " + (dataObj.startDate || "") + "</p>" +
|
||||
"<p><b>Дата возврата:</b> " + (dataObj.endDate || "") + "</p>" +
|
||||
"<p><b>Количество человек:</b> " + (dataObj.people || "") + "</p>" +
|
||||
"<p><b>Бюджет:</b> " + (dataObj.budget || "") + " руб.</p>" +
|
||||
"<p><b>Комментарий:</b> " + (dataObj.comment || "") + "</p>";
|
||||
});
|
||||
}
|
||||
});
|
||||
375
labWeb/kt_3/styles.css
Normal file
@@ -0,0 +1,375 @@
|
||||
:root {
|
||||
--bg: #f6f7fb;
|
||||
--card: #ffffff;
|
||||
--text: #222;
|
||||
--muted: #667085;
|
||||
--accent: #3b82f6;
|
||||
--accent-dark: #1d4ed8;
|
||||
--border: #e5e7eb;
|
||||
--shadow: 0 10px 20px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: Arial, sans-serif;
|
||||
color: var(--text);
|
||||
background: var(--bg);
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
main {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: min(1100px, 92%);
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.site-header {
|
||||
background: #0f172a;
|
||||
color: #fff;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 30;
|
||||
}
|
||||
|
||||
.header-inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
min-height: 64px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.burger {
|
||||
display: none;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: #fff;
|
||||
font-size: 26px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.site-nav ul {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
gap: 18px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.site-nav a {
|
||||
color: #fff;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.site-nav a:hover,
|
||||
.site-nav a.active {
|
||||
opacity: 1;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.hero {
|
||||
margin-top: 20px;
|
||||
background: linear-gradient(120deg, #dbeafe, #f0f9ff);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 14px;
|
||||
padding: 26px;
|
||||
}
|
||||
|
||||
.hero h1 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.grid-home {
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 1fr;
|
||||
gap: 18px;
|
||||
margin: 20px 0 30px;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: var(--card);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
padding: 16px;
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.slider {
|
||||
overflow: hidden;
|
||||
border-radius: 10px;
|
||||
position: relative;
|
||||
min-height: 240px;
|
||||
}
|
||||
|
||||
.slide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.slide.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.slide img {
|
||||
width: 100%;
|
||||
height: 240px;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.slide-caption {
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
right: 8px;
|
||||
bottom: 8px;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
color: #fff;
|
||||
padding: 8px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
background: var(--accent);
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
padding: 9px 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background: var(--accent-dark);
|
||||
}
|
||||
|
||||
.news-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 14px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.news-item {
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
border: 1px solid var(--border);
|
||||
overflow: hidden;
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.news-item img {
|
||||
width: 100%;
|
||||
height: 160px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.news-item-content {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.cards-flex {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 14px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.tour-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: calc(25% - 11px);
|
||||
background: #fff;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tour-card img {
|
||||
width: 100%;
|
||||
height: 140px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.tour-card-body {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
border: 1px solid var(--border);
|
||||
padding: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
th {
|
||||
background: #e2e8f0;
|
||||
}
|
||||
|
||||
form {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
color: var(--muted);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
width: 100%;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 7px;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
textarea {
|
||||
min-height: 90px;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
.form-full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.result {
|
||||
margin-top: 16px;
|
||||
background: #fff;
|
||||
border: 1px dashed #94a3b8;
|
||||
border-radius: 10px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.map-wrap iframe {
|
||||
width: 100%;
|
||||
border: 0;
|
||||
border-radius: 10px;
|
||||
min-height: 300px;
|
||||
}
|
||||
|
||||
.modal-overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.65);
|
||||
z-index: 100;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.modal-overlay.open {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.modal {
|
||||
width: min(720px, 100%);
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.modal-head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
border: 0;
|
||||
background: #e2e8f0;
|
||||
border-radius: 6px;
|
||||
padding: 6px 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.site-footer {
|
||||
margin-top: 30px;
|
||||
background: #0f172a;
|
||||
color: #fff;
|
||||
padding: 14px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media (max-width: 960px) {
|
||||
.news-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.tour-card {
|
||||
width: calc(33.333% - 10px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 760px) {
|
||||
.burger {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.site-nav {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 64px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: #0f172a;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.16);
|
||||
}
|
||||
|
||||
.site-nav.open {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.site-nav ul {
|
||||
flex-direction: column;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.grid-home {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.news-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.tour-card {
|
||||
width: calc(50% - 7px);
|
||||
}
|
||||
|
||||
form {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.tour-card {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
58
labWeb/kt_3/tours.html
Normal file
@@ -0,0 +1,58 @@
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Вокруг Света | Расписание</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<header class="site-header">
|
||||
<div class="container header-inner">
|
||||
<a class="logo" href="index.html">Вокруг Света</a>
|
||||
<button id="burger" class="burger" aria-label="Меню">☰</button>
|
||||
<nav id="siteNav" class="site-nav">
|
||||
<ul>
|
||||
<li><a href="index.html">Главная</a></li>
|
||||
<li><a href="news.html">Новости</a></li>
|
||||
<li><a href="cards.html">Направления</a></li>
|
||||
<li><a class="active" href="tours.html">Расписание</a></li>
|
||||
<li><a href="booking.html">Заявка</a></li>
|
||||
<li><a href="contacts.html">Контакты</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="container">
|
||||
<h1>Расписание туров на месяц</h1>
|
||||
<p>Ниже представлены ближайшие выезды по популярным направлениям с актуальными ценами и количеством свободных мест.</p>
|
||||
<div class="card">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Дата</th>
|
||||
<th>Направление</th>
|
||||
<th>Длительность</th>
|
||||
<th>Цена</th>
|
||||
<th>Свободные места</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>05.05.2026</td><td>Турция</td><td>7 дней</td><td>58 000</td><td>12</td></tr>
|
||||
<tr><td>08.05.2026</td><td>Италия</td><td>8 дней</td><td>84 000</td><td>6</td></tr>
|
||||
<tr><td>10.05.2026</td><td>Грузия</td><td>6 дней</td><td>49 000</td><td>9</td></tr>
|
||||
<tr><td>13.05.2026</td><td>Франция</td><td>9 дней</td><td>102 000</td><td>4</td></tr>
|
||||
<tr><td>17.05.2026</td><td>Исландия</td><td>7 дней</td><td>120 000</td><td>5</td></tr>
|
||||
<tr><td>20.05.2026</td><td>Норвегия</td><td>8 дней</td><td>111 000</td><td>7</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="container">ООО "Вокруг Света" | Москва, ул. Примерная, 10 | +7 (900) 123-45-67 | info@tour-example.ru</div>
|
||||
</footer>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
84
labWeb/lab3/index.html
Normal file
@@ -0,0 +1,84 @@
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Озеро Байкал</title>
|
||||
<link rel="stylesheet" href="./style.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="page">
|
||||
<main class="card">
|
||||
<header class="card__header">
|
||||
<h1 class="title">Озеро Байкал</h1>
|
||||
</header>
|
||||
|
||||
<section class="card__body" aria-label="Информация об озере Байкал">
|
||||
<p class="p p--highlight">
|
||||
<strong>Байкал</strong> (бур. <em>Байгал далай</em>) — озеро тектонического происхождения в южной части
|
||||
Восточной Сибири площадью 31 722 км², самое глубокое озеро на планете, крупнейший природный резервуар пресной
|
||||
воды и самое большое по площади пресноводное озеро Евразии.
|
||||
</p>
|
||||
|
||||
<p class="p">
|
||||
Находится в центре Азии на границе
|
||||
<a class="a" href="https://ru.wikipedia.org/wiki/%D0%98%D1%80%D0%BA%D1%83%D1%82%D1%81%D0%BA%D0%B0%D1%8F_%D0%BE%D0%B1%D0%BB%D0%B0%D1%81%D1%82%D1%8C" target="_blank" rel="noreferrer noopener"
|
||||
>Иркутской области</a
|
||||
>
|
||||
и
|
||||
<a class="a" href="https://ru.wikipedia.org/wiki/%D0%A0%D0%B5%D1%81%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0_%D0%91%D1%83%D1%80%D1%8F%D1%82%D0%B8%D1%8F" target="_blank" rel="noreferrer noopener"
|
||||
>Республики Бурятия</a
|
||||
>
|
||||
в Российской Федерации. Озеро протянулось с юго-запада на северо-восток на 636 км в виде гигантского
|
||||
полумесяца. Ширина водоёма колеблется в пределах от 24 до 79 км. Дно Байкала в самой глубокой его части на
|
||||
1187 метров ниже уровня Мирового океана. Высотная отметка уреза воды Байкала установлена (так как Байкал
|
||||
зарегулирован) в пределе 456—457 метров над уровнем моря, но в Тихоокеанской системе высот. В результате
|
||||
«реальный» уровень Байкала фактически неизвестен.
|
||||
</p>
|
||||
|
||||
<p class="p">
|
||||
Площадь водной поверхности Байкала — 31 722 км² (без учёта островов), что примерно равно площади таких стран,
|
||||
как Бельгия или Нидерланды. По площади водного зеркала Байкал занимает седьмое место среди крупнейших озёр
|
||||
мира. Площадь водосборного бассейна — 571 тыс. км². Длина береговой линии — 2000 км.
|
||||
</p>
|
||||
|
||||
<p class="p">
|
||||
Озеро находится в своеобразной котловине, со всех сторон окружённой горными хребтами и сопками. При этом
|
||||
западное побережье — скалистое и обрывистое, рельеф восточного побережья — более пологий (местами горы
|
||||
отступают от берега на десятки километров).
|
||||
</p>
|
||||
|
||||
<p class="p">
|
||||
Запасы воды в Байкале гигантские — <strong>23 615,39 км³</strong> (около <em>19 %</em> от 123 тыс. км³ всех мировых запасов
|
||||
озёрной пресной воды). По объёму запасов пресной воды Байкал занимает первое место в мире среди озёр. В Байкале
|
||||
воды больше, чем во всех вместе взятых пяти
|
||||
<a class="a" href="https://ru.wikipedia.org/wiki/%D0%92%D0%B5%D0%BB%D0%B8%D0%BA%D0%B8%D0%B5_%D0%BE%D0%B7%D1%91%D1%80%D0%B0" target="_blank" rel="noreferrer noopener"
|
||||
>Великих озёрах</a
|
||||
>
|
||||
Северной Америки (Верхнее, Мичиган, Гурон, Эри, Онтарио), и в 25 раз больше, чем в Ладожском озере. Если же
|
||||
брать абсолютную величину среди всех озёр мира, то Байкал по объёму воды уступает разве что
|
||||
<a class="a" href="https://ru.wikipedia.org/wiki/%D0%9A%D0%B0%D1%81%D0%BF%D0%B8%D0%B9%D1%81%D0%BA%D0%BE%D0%B5_%D0%BC%D0%BE%D1%80%D0%B5" target="_blank" rel="noreferrer noopener"
|
||||
>Каспийскому морю</a
|
||||
>.
|
||||
</p>
|
||||
|
||||
<p class="p">
|
||||
По данным исследований И. Д. Черского (XIX век) в Байкал впадало 336 рек и ручьё, и это число учитывало
|
||||
только постоянные притоки. Более современных данных по данному вопросу нет, однако иногда приводятся цифры в
|
||||
544 или 1123 (которые приведены в результате подсчёта распадков, а не постоянных водотоков). Также считается,
|
||||
что вследствие антропогенного воздействия и изменения климата на Байкале с XIX века по современное время
|
||||
могло пропасть порядка 150 водотоков.
|
||||
</p>
|
||||
|
||||
<p class="p p--highlight">
|
||||
Самые крупные реки, впадающие в Байкал — это Селенга, Верхняя Ангара, Баргузин, Турка, Снежная, Кичера, Тыя,
|
||||
Голоустная, Бугульдейка. Из озера вытекает только одна река —
|
||||
<a class="a" href="https://ru.wikipedia.org/wiki/%D0%90%D0%BD%D0%B3%D0%B0%D1%80%D0%B0" target="_blank" rel="noreferrer noopener"
|
||||
>Ангара</a
|
||||
>.
|
||||
</p>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
89
labWeb/lab3/style.css
Normal file
@@ -0,0 +1,89 @@
|
||||
|
||||
|
||||
:root {
|
||||
--maroon: #9f2b2b;
|
||||
--maroon-dark: #7e1f1f;
|
||||
--paper: #ffffff;
|
||||
--highlight: #f7e3c1;
|
||||
--text: #111111;
|
||||
--link: #6b3e1e;
|
||||
--link-hover: #b84c1b;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 24px 0;
|
||||
background: var(--paper);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.page {
|
||||
width: min(980px, calc(100% - 32px));
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.note {
|
||||
margin: 0 0 10px;
|
||||
font: 700 14pt/1.2 "Times New Roman", Times, serif;
|
||||
color: var(--maroon);
|
||||
}
|
||||
|
||||
.card {
|
||||
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.card__header {
|
||||
padding: 10px 14px;
|
||||
background: var(--maroon);
|
||||
border-bottom: 2px solid var(--maroon-dark);
|
||||
}
|
||||
|
||||
.title {
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-family: Cambria, Georgia, "Times New Roman", serif;
|
||||
font-size: 24pt;
|
||||
line-height: 1.1;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.card__body {
|
||||
padding: 10px 12px 12px;
|
||||
}
|
||||
|
||||
.p {
|
||||
margin: 0 0 10px;
|
||||
font-family: "Times New Roman", Times, serif;
|
||||
font-size: 14pt;
|
||||
line-height: 1.35;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
.p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.p--highlight {
|
||||
background: var(--highlight);
|
||||
padding: 6px 8px;
|
||||
}
|
||||
|
||||
.a {
|
||||
color: var(--link);
|
||||
text-decoration: underline;
|
||||
text-decoration-thickness: 1px;
|
||||
text-underline-offset: 2px;
|
||||
transition: color 120ms ease-in-out;
|
||||
}
|
||||
|
||||
.a:hover,
|
||||
.a:focus-visible {
|
||||
color: var(--link-hover);
|
||||
}
|
||||
|
||||
194
labWeb/lab4-6/contacts.html
Normal file
@@ -0,0 +1,194 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Контакты | МедСэйв</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
body { font-family: 'Inter', sans-serif; }
|
||||
.gradient-bg { background: linear-gradient(135deg, #0ea5e9 0%, #0284c7 100%); }
|
||||
.medical-pattern { background-image: radial-gradient(circle at 1px 1px, rgba(255,255,255,0.15) 1px, transparent 0); background-size: 20px 20px; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-slate-50 text-slate-800">
|
||||
|
||||
|
||||
<header class="bg-sky-100 medical-pattern text-sky-900 shadow-lg sticky top-0 z-50">
|
||||
<div class="container mx-auto px-4 py-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="bg-sky-200 p-2 rounded-xl">
|
||||
<i data-lucide="heart-pulse" class="w-8 h-8 text-sky-700"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold tracking-tight">МедСэйв</h1>
|
||||
<p class="text-sky-600 text-sm">Медицинский центр</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="hidden md:flex items-center space-x-1">
|
||||
<a href="index.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Новости</a>
|
||||
<a href="doctors.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Наши врачи</a>
|
||||
<a href="prices.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Цены</a>
|
||||
<a href="schedule.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Расписание</a>
|
||||
<a href="contacts.html" class="px-4 py-2 rounded-lg bg-sky-200 font-medium transition hover:bg-sky-300 text-sky-900">Контакты</a>
|
||||
</nav>
|
||||
|
||||
<button onclick="toggleMobileMenu()" class="md:hidden p-2 rounded-lg bg-sky-200 hover:bg-sky-300 transition text-sky-900">
|
||||
<i data-lucide="menu" class="w-6 h-6"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div id="mobileMenu" class="hidden md:hidden mt-4 pb-4 space-y-2 border-t border-sky-300 pt-4">
|
||||
<a href="index.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Новости</a>
|
||||
<a href="doctors.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Наши врачи</a>
|
||||
<a href="prices.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Цены</a>
|
||||
<a href="schedule.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Расписание</a>
|
||||
<a href="contacts.html" class="block px-4 py-2 rounded-lg bg-sky-200 font-medium text-sky-900">Контакты</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="container mx-auto px-4 py-8 max-w-6xl">
|
||||
<div class="mb-8">
|
||||
<h2 class="text-3xl font-bold text-slate-800">Контакты</h2>
|
||||
<p class="text-slate-600 mt-2">Мы всегда рады помочь вам. Свяжитесь с нами удобным способом.</p>
|
||||
</div>
|
||||
|
||||
<div class="grid lg:grid-cols-2 gap-8">
|
||||
|
||||
<div class="space-y-6">
|
||||
<div class="bg-white rounded-2xl shadow-lg p-6 border border-slate-100">
|
||||
<div class="flex items-start space-x-4 mb-6">
|
||||
<div class="w-12 h-12 bg-sky-100 rounded-xl flex items-center justify-center flex-shrink-0">
|
||||
<i data-lucide="map-pin" class="w-6 h-6 text-sky-600"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="font-semibold text-lg text-slate-800 mb-1">Адрес</h3>
|
||||
<p class="text-slate-600">г. Москва, ул. Здоровья, д. 15, корп. 2</p>
|
||||
<p class="text-slate-500 text-sm mt-1">Ближайшее метро: Медицинская (5 мин. пешком)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-start space-x-4 mb-6">
|
||||
<div class="w-12 h-12 bg-emerald-100 rounded-xl flex items-center justify-center flex-shrink-0">
|
||||
<i data-lucide="phone" class="w-6 h-6 text-emerald-600"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="font-semibold text-lg text-slate-800 mb-1">Телефоны</h3>
|
||||
<p class="text-slate-600 text-lg font-medium">+7 (495) 123-45-67</p>
|
||||
<p class="text-slate-600">+7 (495) 987-65-43</p>
|
||||
<p class="text-slate-500 text-sm mt-1">Единый колл-центр: круглосуточно</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-start space-x-4 mb-6">
|
||||
<div class="w-12 h-12 bg-rose-100 rounded-xl flex items-center justify-center flex-shrink-0">
|
||||
<i data-lucide="mail" class="w-6 h-6 text-rose-600"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="font-semibold text-lg text-slate-800 mb-1">Email</h3>
|
||||
<p class="text-slate-600">info@medsave.ru</p>
|
||||
<p class="text-slate-600">appointments@medsave.ru</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-start space-x-4">
|
||||
<div class="w-12 h-12 bg-amber-100 rounded-xl flex items-center justify-center flex-shrink-0">
|
||||
<i data-lucide="clock" class="w-6 h-6 text-amber-600"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="font-semibold text-lg text-slate-800 mb-1">Режим работы</h3>
|
||||
<p class="text-slate-600">Пн-Пт: 8:00 - 20:00</p>
|
||||
<p class="text-slate-600">Сб-Вс: 9:00 - 18:00</p>
|
||||
<p class="text-slate-500 text-sm mt-1">Без выходных</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="bg-white rounded-2xl shadow-lg p-6 border border-slate-100">
|
||||
<h3 class="font-semibold text-lg text-slate-800 mb-4">Мы в соцсетях и мессенджерах</h3>
|
||||
<div class="flex flex-wrap gap-3">
|
||||
<a href="#" class="flex items-center space-x-2 px-4 py-2 bg-blue-400 text-white rounded-lg hover:bg-blue-500 transition">
|
||||
<i data-lucide="send" class="w-5 h-5"></i>
|
||||
<span>Telegram</span>
|
||||
</a>
|
||||
<a href="#" class="flex items-center space-x-2 px-4 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 transition">
|
||||
<i data-lucide="message-circle" class="w-5 h-5"></i>
|
||||
<span>WhatsApp</span>
|
||||
</a>
|
||||
<a href="#" class="flex items-center space-x-2 px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition">
|
||||
<i data-lucide="smartphone" class="w-5 h-5"></i>
|
||||
<span>Viber</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="space-y-6">
|
||||
<div class="bg-white rounded-2xl shadow-lg overflow-hidden border border-slate-100">
|
||||
<img src="https://static.photos/medical/1024x576/501" alt="Здание клиники МедСэйв" class="w-full h-80 object-cover">
|
||||
<div class="p-6">
|
||||
<h3 class="font-semibold text-lg text-slate-800 mb-2">Наша клиника</h3>
|
||||
<p class="text-slate-600 text-sm">Современное здание медицинского центра оснащено всем необходимым для комфортного приема пациентов. Доступно бесплатная парковка для клиентов.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-gradient-to-br from-sky-500 to-blue-600 rounded-2xl shadow-lg p-6 text-white">
|
||||
<h3 class="font-semibold text-lg mb-4">Экстренная помощь</h3>
|
||||
<p class="text-sky-100 mb-4 text-sm">При острых состояниях звоните на горячую линию немедленно:</p>
|
||||
<div class="flex items-center space-x-3 text-2xl font-bold">
|
||||
<i data-lucide="phone-call" class="w-8 h-8"></i>
|
||||
<span>+7 (495) 123-45-67</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="bg-slate-900 text-slate-300 mt-16">
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="flex flex-col md:flex-row items-center justify-between gap-4">
|
||||
<div class="flex items-center space-x-3">
|
||||
<i data-lucide="heart-pulse" class="w-6 h-6 text-sky-400"></i>
|
||||
<span class="font-semibold text-white">МедСэйв</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2 text-slate-300">
|
||||
<i data-lucide="phone" class="w-4 h-4 text-sky-400"></i>
|
||||
<span class="font-medium text-white">+7 (123) 123-12-31</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center space-x-4">
|
||||
<span class="text-sm">Мы в соцсетях:</span>
|
||||
<div class="flex space-x-3">
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-sky-500 hover:text-white transition" title="Telegram">
|
||||
<i data-lucide="send" class="w-5 h-5"></i>
|
||||
</a>
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-green-500 hover:text-white transition" title="WhatsApp">
|
||||
<i data-lucide="message-circle" class="w-5 h-5"></i>
|
||||
</a>
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-purple-600 hover:text-white transition" title="Viber">
|
||||
<i data-lucide="phone-call" class="w-5 h-5"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="text-sm text-slate-500">© 2024 МедСэйв. Все права защищены.</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
lucide.createIcons();
|
||||
function toggleMobileMenu() {
|
||||
document.getElementById('mobileMenu').classList.toggle('hidden');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
227
labWeb/lab4-6/doctors.html
Normal file
@@ -0,0 +1,227 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Наши врачи | МедСэйв</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
body { font-family: 'Inter', sans-serif; }
|
||||
.gradient-bg { background: linear-gradient(135deg, #0ea5e9 0%, #0284c7 100%); }
|
||||
.medical-pattern { background-image: radial-gradient(circle at 1px 1px, rgba(255,255,255,0.15) 1px, transparent 0); background-size: 20px 20px; }
|
||||
|
||||
|
||||
ol.doctor-categories {
|
||||
list-style: none;
|
||||
counter-reset: category;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
ol.doctor-categories > li {
|
||||
counter-increment: category;
|
||||
position: relative;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
ol.doctor-categories > li::before {
|
||||
content: counter(category);
|
||||
display: inline-block;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background-image: url('https://static.photos/medical/200x200/777');
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
line-height: 32px;
|
||||
margin-right: 12px;
|
||||
vertical-align: middle;
|
||||
border-radius: 50%;
|
||||
font-size: 14px;
|
||||
text-shadow: 0 1px 2px rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
|
||||
ul.doctor-list {
|
||||
list-style: none;
|
||||
padding-left: 3rem;
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
|
||||
ul.doctor-list li {
|
||||
position: relative;
|
||||
padding-left: 1.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
color: #475569;
|
||||
}
|
||||
|
||||
ul.doctor-list li::before {
|
||||
content: "✓";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
color: #0ea5e9;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-slate-50 text-slate-800">
|
||||
|
||||
|
||||
<header class="bg-sky-100 medical-pattern text-sky-900 shadow-lg sticky top-0 z-50">
|
||||
<div class="container mx-auto px-4 py-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="bg-sky-200 p-2 rounded-xl">
|
||||
<i data-lucide="heart-pulse" class="w-8 h-8 text-sky-700"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold tracking-tight">МедСэйв</h1>
|
||||
<p class="text-sky-600 text-sm">Медицинский центр</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="hidden md:flex items-center space-x-1">
|
||||
<a href="index.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Новости</a>
|
||||
<a href="doctors.html" class="px-4 py-2 rounded-lg bg-sky-200 font-medium transition hover:bg-sky-300 text-sky-900">Наши врачи</a>
|
||||
<a href="prices.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Цены</a>
|
||||
<a href="schedule.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Расписание</a>
|
||||
<a href="contacts.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Контакты</a>
|
||||
</nav>
|
||||
|
||||
<button onclick="toggleMobileMenu()" class="md:hidden p-2 rounded-lg bg-sky-200 hover:bg-sky-300 transition text-sky-900">
|
||||
<i data-lucide="menu" class="w-6 h-6"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div id="mobileMenu" class="hidden md:hidden mt-4 pb-4 space-y-2 border-t border-sky-300 pt-4">
|
||||
<a href="index.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Новости</a>
|
||||
<a href="doctors.html" class="block px-4 py-2 rounded-lg bg-sky-200 font-medium text-sky-900">Наши врачи</a>
|
||||
<a href="prices.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Цены</a>
|
||||
<a href="schedule.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Расписание</a>
|
||||
<a href="contacts.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Контакты</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="container mx-auto px-4 py-8 max-w-4xl">
|
||||
<div class="mb-8">
|
||||
<h2 class="text-3xl font-bold text-slate-800 mb-2">Наши специалисты</h2>
|
||||
<p class="text-slate-600">Квалифицированные врачи с многолетним опытом работы</p>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-2xl shadow-lg p-8 border border-slate-100">
|
||||
<ol class="doctor-categories">
|
||||
<li>
|
||||
<span class="text-xl font-semibold text-slate-800">Терапевты</span>
|
||||
<ul class="doctor-list">
|
||||
<li>Иванов И.И.</li>
|
||||
<li>Сидорова Е.Л.</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<span class="text-xl font-semibold text-slate-800">Неврологи</span>
|
||||
<ul class="doctor-list">
|
||||
<li>Петрова Л.Д.</li>
|
||||
<li>Орлова Г.Д.</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<span class="text-xl font-semibold text-slate-800">УЗИ-специалисты</span>
|
||||
<ul class="doctor-list">
|
||||
<li>Гордеев О.Т.</li>
|
||||
<li>Арбатова Е.К.</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<span class="text-xl font-semibold text-slate-800">Кардиологи</span>
|
||||
<ul class="doctor-list">
|
||||
<li>Смирнов А.В.</li>
|
||||
<li>Козлова Н.П.</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<span class="text-xl font-semibold text-slate-800">Эндокринологи</span>
|
||||
<ul class="doctor-list">
|
||||
<li>Морозов П.С.</li>
|
||||
<li>Васильева Т.А.</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<span class="text-xl font-semibold text-slate-800">Хирурги</span>
|
||||
<ul class="doctor-list">
|
||||
<li>Новиков Д.Г.</li>
|
||||
<li>Лебедева С.М.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 grid md:grid-cols-2 gap-6">
|
||||
<div class="bg-gradient-to-br from-sky-500 to-blue-600 rounded-2xl shadow-lg p-6 text-white">
|
||||
<h3 class="font-semibold text-lg mb-3 flex items-center gap-2">
|
||||
<i data-lucide="graduation-cap" class="w-5 h-5"></i>
|
||||
Высшая категория
|
||||
</h3>
|
||||
<p class="text-sky-100 text-sm">Более 70% наших врачей имеют высшую и первую квалификационную категорию.</p>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-2xl shadow-lg p-6 border border-slate-100">
|
||||
<h3 class="font-semibold text-lg mb-3 flex items-center gap-2 text-slate-800">
|
||||
<i data-lucide="calendar-check" class="w-5 h-5 text-sky-600"></i>
|
||||
Запись к врачу
|
||||
</h3>
|
||||
<p class="text-slate-600 text-sm mb-4">Запишитесь на прием к нужному специалисту через наш колл-центр.</p>
|
||||
<a href="contacts.html" class="inline-flex items-center text-sky-600 font-medium hover:text-sky-700 transition">
|
||||
Перейти к контактам <i data-lucide="arrow-right" class="w-4 h-4 ml-2"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="bg-slate-900 text-slate-300 mt-16">
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="flex flex-col md:flex-row items-center justify-between gap-4">
|
||||
<div class="flex items-center space-x-3">
|
||||
<i data-lucide="heart-pulse" class="w-6 h-6 text-sky-400"></i>
|
||||
<span class="font-semibold text-white">МедСэйв</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-slate-300 mb-2 md:mb-0">
|
||||
<i data-lucide="phone" class="w-4 h-4 text-sky-400"></i>
|
||||
<span class="font-medium text-white">+7 (123) 123-12-31</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center space-x-4">
|
||||
<span class="text-sm">Мы в социальных сетях:</span>
|
||||
<div class="flex space-x-3">
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-sky-500 hover:text-white transition" title="Telegram">
|
||||
<i data-lucide="send" class="w-5 h-5"></i>
|
||||
</a>
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-green-500 hover:text-white transition" title="WhatsApp">
|
||||
<i data-lucide="message-circle" class="w-5 h-5"></i>
|
||||
</a>
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-purple-600 hover:text-white transition" title="Viber">
|
||||
<i data-lucide="phone-call" class="w-5 h-5"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-sm text-slate-500">© 2024 МедСэйв. Все права защищены.</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
lucide.createIcons();
|
||||
function toggleMobileMenu() {
|
||||
document.getElementById('mobileMenu').classList.toggle('hidden');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
200
labWeb/lab4-6/index.html
Normal file
@@ -0,0 +1,200 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>МедСэйв - Главная | Медицинский центр</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
body { font-family: 'Inter', sans-serif; }
|
||||
.gradient-bg { background: linear-gradient(135deg, #0ea5e9 0%, #0284c7 100%); }
|
||||
.medical-pattern { background-image: radial-gradient(circle at 1px 1px, rgba(255,255,255,0.15) 1px, transparent 0); background-size: 20px 20px; }
|
||||
.glass-effect { background: rgba(255, 255, 255, 0.95); backdrop-filter: blur(10px); }
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-slate-50 text-slate-800">
|
||||
|
||||
|
||||
<header class="bg-sky-100 medical-pattern text-sky-900 shadow-lg sticky top-0 z-50">
|
||||
<div class="container mx-auto px-4 py-4">
|
||||
<div class="flex items-center justify-between">
|
||||
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="bg-sky-200 p-2 rounded-xl">
|
||||
<i data-lucide="heart-pulse" class="w-8 h-8 text-sky-700"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold tracking-tight">МедСэйв</h1>
|
||||
<p class="text-sky-600 text-sm">Медицинский центр</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<nav class="hidden md:flex items-center space-x-1">
|
||||
<a href="index.html" class="px-4 py-2 rounded-lg bg-sky-200 font-medium transition hover:bg-sky-300 text-sky-900">Новости</a>
|
||||
<a href="doctors.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Наши врачи</a>
|
||||
<a href="prices.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Цены</a>
|
||||
<a href="schedule.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Расписание</a>
|
||||
<a href="contacts.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Контакты</a>
|
||||
</nav>
|
||||
|
||||
|
||||
<button onclick="toggleMobileMenu()" class="md:hidden p-2 rounded-lg bg-sky-200 hover:bg-sky-300 transition text-sky-900">
|
||||
<i data-lucide="menu" class="w-6 h-6"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="mobileMenu" class="hidden md:hidden mt-4 pb-4 space-y-2 border-t border-sky-300 pt-4">
|
||||
<a href="index.html" class="block px-4 py-2 rounded-lg bg-sky-200 font-medium text-sky-900">Новости</a>
|
||||
<a href="doctors.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Наши врачи</a>
|
||||
<a href="prices.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Цены</a>
|
||||
<a href="schedule.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Расписание</a>
|
||||
<a href="contacts.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Контакты</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
<main class="container mx-auto px-4 py-8 max-w-6xl">
|
||||
|
||||
|
||||
<section class="mb-12">
|
||||
<div class="grid md:grid-cols-3 gap-6">
|
||||
<div class="glass-effect rounded-2xl p-6 shadow-lg border border-slate-200 hover:shadow-xl transition">
|
||||
<div class="w-12 h-12 bg-sky-100 rounded-xl flex items-center justify-center mb-4">
|
||||
<i data-lucide="stethoscope" class="w-6 h-6 text-sky-600"></i>
|
||||
</div>
|
||||
<h3 class="text-lg font-semibold mb-2 text-slate-800">Профессиональная диагностика</h3>
|
||||
<p class="text-slate-600 text-sm leading-relaxed">Современное оборудование и квалифицированные специалисты для точной постановки диагноза и эффективного лечения.</p>
|
||||
</div>
|
||||
|
||||
<div class="glass-effect rounded-2xl p-6 shadow-lg border border-slate-200 hover:shadow-xl transition">
|
||||
<div class="w-12 h-12 bg-emerald-100 rounded-xl flex items-center justify-center mb-4">
|
||||
<i data-lucide="shield-check" class="w-6 h-6 text-emerald-600"></i>
|
||||
</div>
|
||||
<h3 class="text-lg font-semibold mb-2 text-slate-800">Безопасность и забота</h3>
|
||||
<p class="text-slate-600 text-sm leading-relaxed">Индивидуальный подход к каждому пациенту, строгие санитарные нормы и комфортная обстановка в клинике.</p>
|
||||
</div>
|
||||
|
||||
<div class="glass-effect rounded-2xl p-6 shadow-lg border border-slate-200 hover:shadow-xl transition">
|
||||
<div class="w-12 h-12 bg-rose-100 rounded-xl flex items-center justify-center mb-4">
|
||||
<i data-lucide="clock" class="w-6 h-6 text-rose-600"></i>
|
||||
</div>
|
||||
<h3 class="text-lg font-semibold mb-2 text-slate-800">Удобное расписание</h3>
|
||||
<p class="text-slate-600 text-sm leading-relaxed">Работаем ежедневно без выходных. Запись на прием онлайн и по телефону. Минимальное время ожидания.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<section>
|
||||
<div class="flex items-center justify-between mb-8">
|
||||
<h2 class="text-3xl font-bold text-slate-800">Новости клиники</h2>
|
||||
<span class="bg-sky-100 text-sky-700 px-3 py-1 rounded-full text-sm font-medium">Актуальное</span>
|
||||
</div>
|
||||
|
||||
<div class="grid md:grid-cols-3 gap-8">
|
||||
|
||||
<article class="bg-white rounded-2xl shadow-lg overflow-hidden hover:shadow-2xl transition duration-300 border border-slate-100">
|
||||
<div class="h-48 overflow-hidden">
|
||||
<img src="https://static.photos/medical/640x360/101" alt="Новое оборудование" class="w-full h-full object-cover hover:scale-105 transition duration-500">
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<div class="flex items-center gap-2 mb-3 text-sm text-slate-500">
|
||||
<i data-lucide="calendar" class="w-4 h-4"></i>
|
||||
<span>15 января 2024</span>
|
||||
</div>
|
||||
<h3 class="text-xl font-bold mb-3 text-slate-800 hover:text-sky-600 transition">Новое диагностическое оборудование</h3>
|
||||
<p class="text-slate-600 text-sm leading-relaxed mb-4">В нашей клинике установлен современный аппарат УЗИ экспертного класса. Теперь диагностика стала еще точнее и комфортнее для пациентов.</p>
|
||||
<a href="#" class="inline-flex items-center text-sky-600 font-medium hover:text-sky-700 transition">
|
||||
Подробнее <i data-lucide="arrow-right" class="w-4 h-4 ml-2"></i>
|
||||
</a>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
|
||||
<article class="bg-white rounded-2xl shadow-lg overflow-hidden hover:shadow-2xl transition duration-300 border border-slate-100">
|
||||
<div class="h-48 overflow-hidden">
|
||||
<img src="https://static.photos/medical/640x360/202" alt="Новый врач" class="w-full h-full object-cover hover:scale-105 transition duration-500">
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<div class="flex items-center gap-2 mb-3 text-sm text-slate-500">
|
||||
<i data-lucide="calendar" class="w-4 h-4"></i>
|
||||
<span>10 января 2024</span>
|
||||
</div>
|
||||
<h3 class="text-xl font-bold mb-3 text-slate-800 hover:text-sky-600 transition">Пополнение в команде специалистов</h3>
|
||||
<p class="text-slate-600 text-sm leading-relaxed mb-4">Врач-невролог Петрова Людмила Дмитриевна присоединилась к нашей команде. Записаться на консультацию можно уже сейчас.</p>
|
||||
<a href="#" class="inline-flex items-center text-sky-600 font-medium hover:text-sky-700 transition">
|
||||
Подробнее <i data-lucide="arrow-right" class="w-4 h-4 ml-2"></i>
|
||||
</a>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
|
||||
<article class="bg-white rounded-2xl shadow-lg overflow-hidden hover:shadow-2xl transition duration-300 border border-slate-100">
|
||||
<div class="h-48 overflow-hidden">
|
||||
<img src="https://static.photos/medical/640x360/303" alt="Акция" class="w-full h-full object-cover hover:scale-105 transition duration-500">
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<div class="flex items-center gap-2 mb-3 text-sm text-slate-500">
|
||||
<i data-lucide="calendar" class="w-4 h-4"></i>
|
||||
<span>5 января 2024</span>
|
||||
</div>
|
||||
<h3 class="text-xl font-bold mb-3 text-slate-800 hover:text-sky-600 transition">Акция: комплексное обследование</h3>
|
||||
<p class="text-slate-600 text-sm leading-relaxed mb-4">В январе действует скидка 20% на комплексное обследование организма. Успейте позаботиться о своем здоровье выгодно!</p>
|
||||
<a href="#" class="inline-flex items-center text-sky-600 font-medium hover:text-sky-700 transition">
|
||||
Подробнее <i data-lucide="arrow-right" class="w-4 h-4 ml-2"></i>
|
||||
</a>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
|
||||
<footer class="bg-slate-900 text-slate-300 mt-16">
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="flex flex-col md:flex-row items-center justify-between gap-4">
|
||||
<div class="flex items-center space-x-3">
|
||||
<i data-lucide="heart-pulse" class="w-6 h-6 text-sky-400"></i>
|
||||
<span class="font-semibold text-white">МедСэйв</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2 text-slate-300 mb-2 md:mb-0">
|
||||
<i data-lucide="phone" class="w-4 h-4 text-sky-400"></i>
|
||||
<span class="font-medium text-white">+7 (123) 123-12-31</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center space-x-4">
|
||||
<span class="text-sm">Мы в социальных сетях:</span>
|
||||
<div class="flex space-x-3">
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-sky-500 hover:text-white transition" title="Telegram">
|
||||
<i data-lucide="send" class="w-5 h-5"></i>
|
||||
</a>
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-green-500 hover:text-white transition" title="WhatsApp">
|
||||
<i data-lucide="message-circle" class="w-5 h-5"></i>
|
||||
</a>
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-purple-600 hover:text-white transition" title="Viber">
|
||||
<i data-lucide="phone-call" class="w-5 h-5"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="text-sm text-slate-500">© 2024 МедСэйв. Все права защищены.</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
lucide.createIcons();
|
||||
function toggleMobileMenu() {
|
||||
const menu = document.getElementById('mobileMenu');
|
||||
menu.classList.toggle('hidden');
|
||||
}
|
||||
</script>
|
||||
<script src="https://deepsite.hf.co/deepsite-badge.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
214
labWeb/lab4-6/prices.html
Normal file
@@ -0,0 +1,214 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Цены на услуги | МедСэйв</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
body { font-family: 'Inter', sans-serif; }
|
||||
.gradient-bg { background: linear-gradient(135deg, #0ea5e9 0%, #0284c7 100%); }
|
||||
.medical-pattern { background-image: radial-gradient(circle at 1px 1px, rgba(255,255,255,0.15) 1px, transparent 0); background-size: 20px 20px; }
|
||||
|
||||
ol.medical-list {
|
||||
counter-reset: item;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
ol.medical-list > li {
|
||||
counter-increment: item;
|
||||
position: relative;
|
||||
padding-left: 3rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
ol.medical-list > li::before {
|
||||
content: counter(item);
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
background: linear-gradient(135deg, #0ea5e9 0%, #0284c7 100%);
|
||||
color: white;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: 600;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-slate-50 text-slate-800">
|
||||
|
||||
|
||||
<header class="bg-sky-100 medical-pattern text-sky-900 shadow-lg sticky top-0 z-50">
|
||||
<div class="container mx-auto px-4 py-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="bg-sky-200 p-2 rounded-xl">
|
||||
<i data-lucide="heart-pulse" class="w-8 h-8 text-sky-700"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold tracking-tight">МедСэйв</h1>
|
||||
<p class="text-sky-600 text-sm">Медицинский центр</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="hidden md:flex items-center space-x-1">
|
||||
<a href="index.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Новости</a>
|
||||
<a href="doctors.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Наши врачи</a>
|
||||
<a href="prices.html" class="px-4 py-2 rounded-lg bg-sky-200 font-medium transition hover:bg-sky-300 text-sky-900">Цены</a>
|
||||
<a href="schedule.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Расписание</a>
|
||||
<a href="contacts.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Контакты</a>
|
||||
</nav>
|
||||
|
||||
<button onclick="toggleMobileMenu()" class="md:hidden p-2 rounded-lg bg-sky-200 hover:bg-sky-300 transition text-sky-900">
|
||||
<i data-lucide="menu" class="w-6 h-6"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div id="mobileMenu" class="hidden md:hidden mt-4 pb-4 space-y-2 border-t border-sky-300 pt-4">
|
||||
<a href="index.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Новости</a>
|
||||
<a href="doctors.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Наши врачи</a>
|
||||
<a href="prices.html" class="block px-4 py-2 rounded-lg bg-sky-200 font-medium text-sky-900">Цены</a>
|
||||
<a href="schedule.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Расписание</a>
|
||||
<a href="contacts.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Контакты</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="container mx-auto px-4 py-8 max-w-4xl">
|
||||
<div class="mb-8 text-center">
|
||||
<h2 class="text-3xl font-bold text-slate-800 mb-2">Прайс-лист на услуги</h2>
|
||||
<p class="text-slate-600">Актуальные цены на медицинские услуги клиники МедСэйв</p>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-2xl shadow-lg p-8 border border-slate-100">
|
||||
<div class="flex items-center gap-3 mb-6 pb-6 border-b border-slate-100">
|
||||
<div class="w-12 h-12 bg-sky-100 rounded-xl flex items-center justify-center">
|
||||
<i data-lucide="banknote" class="w-6 h-6 text-sky-600"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="font-semibold text-lg text-slate-800">Стоимость консультаций и процедур</h3>
|
||||
<p class="text-sm text-slate-500">Цены указаны в рублях (₽)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ol class="medical-list space-y-4">
|
||||
<li class="flex justify-between items-center p-4 bg-slate-50 rounded-xl hover:bg-sky-50 transition group">
|
||||
<div>
|
||||
<span class="font-medium text-slate-800 group-hover:text-sky-700">Первичная консультация терапевта</span>
|
||||
<p class="text-sm text-slate-500 mt-1">Осмотр, назначение лечения, рекомендации</p>
|
||||
</div>
|
||||
<span class="font-bold text-sky-600 text-lg">2 500 ₽</span>
|
||||
</li>
|
||||
|
||||
<li class="flex justify-between items-center p-4 bg-slate-50 rounded-xl hover:bg-sky-50 transition group">
|
||||
<div>
|
||||
<span class="font-medium text-slate-800 group-hover:text-sky-700">Повторная консультация терапевта</span>
|
||||
<p class="text-sm text-slate-500 mt-1">Корректировка лечения, контроль динамики</p>
|
||||
</div>
|
||||
<span class="font-bold text-sky-600 text-lg">1 800 ₽</span>
|
||||
</li>
|
||||
|
||||
<li class="flex justify-between items-center p-4 bg-slate-50 rounded-xl hover:bg-sky-50 transition group">
|
||||
<div>
|
||||
<span class="font-medium text-slate-800 group-hover:text-sky-700">Консультация невролога</span>
|
||||
<p class="text-sm text-slate-500 mt-1">Неврологическое обследование, рекомендации</p>
|
||||
</div>
|
||||
<span class="font-bold text-sky-600 text-lg">3 200 ₽</span>
|
||||
</li>
|
||||
|
||||
<li class="flex justify-between items-center p-4 bg-slate-50 rounded-xl hover:bg-sky-50 transition group">
|
||||
<div>
|
||||
<span class="font-medium text-slate-800 group-hover:text-sky-700">УЗИ органов брюшной полости</span>
|
||||
<p class="text-sm text-slate-500 mt-1">Комплексное обследование печени, желчного, селезенки</p>
|
||||
</div>
|
||||
<span class="font-bold text-sky-600 text-lg">2 800 ₽</span>
|
||||
</li>
|
||||
|
||||
<li class="flex justify-between items-center p-4 bg-slate-50 rounded-xl hover:bg-sky-50 transition group">
|
||||
<div>
|
||||
<span class="font-medium text-slate-800 group-hover:text-sky-700">УЗИ щитовидной железы</span>
|
||||
<p class="text-sm text-slate-500 mt-1">Оценка структуры и размеров железы</p>
|
||||
</div>
|
||||
<span class="font-bold text-sky-600 text-lg">1 500 ₽</span>
|
||||
</li>
|
||||
|
||||
<li class="flex justify-between items-center p-4 bg-slate-50 rounded-xl hover:bg-sky-50 transition group">
|
||||
<div>
|
||||
<span class="font-medium text-slate-800 group-hover:text-sky-700">ЭКГ с расшифровкой</span>
|
||||
<p class="text-sm text-slate-500 mt-1">Электрокардиография с заключением врача</p>
|
||||
</div>
|
||||
<span class="font-bold text-sky-600 text-lg">1 200 ₽</span>
|
||||
</li>
|
||||
|
||||
<li class="flex justify-between items-center p-4 bg-slate-50 rounded-xl hover:bg-sky-50 transition group">
|
||||
<div>
|
||||
<span class="font-medium text-slate-800 group-hover:text-sky-700">Общий анализ крови</span>
|
||||
<p class="text-sm text-slate-500 mt-1">Забор крови из вены, лабораторное исследование</p>
|
||||
</div>
|
||||
<span class="font-bold text-sky-600 text-lg">650 ₽</span>
|
||||
</li>
|
||||
|
||||
<li class="flex justify-between items-center p-4 bg-slate-50 rounded-xl hover:bg-sky-50 transition group">
|
||||
<div>
|
||||
<span class="font-medium text-slate-800 group-hover:text-sky-700">Комплексное обследование (Check-up)</span>
|
||||
<p class="text-sm text-slate-500 mt-1">Полное обследование организма (консультации + анализы)</p>
|
||||
</div>
|
||||
<span class="font-bold text-emerald-600 text-lg">15 000 ₽</span>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<div class="mt-8 p-4 bg-amber-50 border border-amber-200 rounded-xl flex items-start gap-3">
|
||||
<i data-lucide="info" class="w-5 h-5 text-amber-600 flex-shrink-0 mt-0.5"></i>
|
||||
<p class="text-sm text-amber-800">
|
||||
<strong>Важно:</strong> Цены могут изменяться. Уточняйте актуальную стоимость при записи на прием.
|
||||
Действуют скидки для пенсионеров и инвалидов — 10% на все услуги.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="bg-slate-900 text-slate-300 mt-16">
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="flex flex-col md:flex-row items-center justify-between gap-4">
|
||||
<div class="flex items-center space-x-3">
|
||||
<i data-lucide="heart-pulse" class="w-6 h-6 text-sky-400"></i>
|
||||
<span class="font-semibold text-white">МедСэйв</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-slate-300 mb-2 md:mb-0">
|
||||
<i data-lucide="phone" class="w-4 h-4 text-sky-400"></i>
|
||||
<span class="font-medium text-white">+7 (123) 123-12-31</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center space-x-4">
|
||||
<span class="text-sm">Мы в социальных сетях:</span>
|
||||
<div class="flex space-x-3">
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-sky-500 hover:text-white transition" title="Telegram">
|
||||
<i data-lucide="send" class="w-5 h-5"></i>
|
||||
</a>
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-green-500 hover:text-white transition" title="WhatsApp">
|
||||
<i data-lucide="message-circle" class="w-5 h-5"></i>
|
||||
</a>
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-purple-600 hover:text-white transition" title="Viber">
|
||||
<i data-lucide="phone-call" class="w-5 h-5"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-sm text-slate-500">© 2024 МедСэйв. Все права защищены.</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
lucide.createIcons();
|
||||
function toggleMobileMenu() {
|
||||
document.getElementById('mobileMenu').classList.toggle('hidden');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
317
labWeb/lab4-6/schedule.html
Normal file
@@ -0,0 +1,317 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Расписание специалистов | МедСэйв</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
body { font-family: 'Inter', sans-serif; }
|
||||
.gradient-bg { background: linear-gradient(135deg, #0ea5e9 0%, #0284c7 100%); }
|
||||
.medical-pattern { background-image: radial-gradient(circle at 1px 1px, rgba(255,255,255,0.15) 1px, transparent 0); background-size: 20px 20px; }
|
||||
|
||||
|
||||
.schedule-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.schedule-table th {
|
||||
background: linear-gradient(135deg, #0ea5e9 0%, #0284c7 100%);
|
||||
color: white;
|
||||
padding: 1rem;
|
||||
text-align: left;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.schedule-table td {
|
||||
padding: 1rem;
|
||||
border-bottom: 1px solid #e2e8f0;
|
||||
}
|
||||
|
||||
.schedule-table tr:hover td {
|
||||
background-color: #f8fafc;
|
||||
}
|
||||
|
||||
.schedule-table tr:nth-child(even) {
|
||||
background-color: #f1f5f9;
|
||||
}
|
||||
|
||||
.cell-merged {
|
||||
background-color: #e0f2fe;
|
||||
font-weight: 600;
|
||||
color: #0369a1;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.time-slot {
|
||||
font-family: monospace;
|
||||
color: #64748b;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-slate-50 text-slate-800">
|
||||
|
||||
|
||||
<header class="bg-sky-100 medical-pattern text-sky-900 shadow-lg sticky top-0 z-50">
|
||||
<div class="container mx-auto px-4 py-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="bg-sky-200 p-2 rounded-xl">
|
||||
<i data-lucide="heart-pulse" class="w-8 h-8 text-sky-700"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold tracking-tight">МедСэйв</h1>
|
||||
<p class="text-sky-600 text-sm">Медицинский центр</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="hidden md:flex items-center space-x-1">
|
||||
<a href="index.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Новости</a>
|
||||
<a href="doctors.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Наши врачи</a>
|
||||
<a href="prices.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Цены</a>
|
||||
<a href="schedule.html" class="px-4 py-2 rounded-lg bg-sky-200 font-medium transition hover:bg-sky-300 text-sky-900">Расписание</a>
|
||||
<a href="contacts.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Контакты</a>
|
||||
</nav>
|
||||
|
||||
<button onclick="toggleMobileMenu()" class="md:hidden p-2 rounded-lg bg-sky-200 hover:bg-sky-300 transition text-sky-900">
|
||||
<i data-lucide="menu" class="w-6 h-6"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div id="mobileMenu" class="hidden md:hidden mt-4 pb-4 space-y-2 border-t border-sky-300 pt-4">
|
||||
<a href="index.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Новости</a>
|
||||
<a href="doctors.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Наши врачи</a>
|
||||
<a href="prices.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Цены</a>
|
||||
<a href="schedule.html" class="block px-4 py-2 rounded-lg bg-sky-200 font-medium text-sky-900">Расписание</a>
|
||||
<a href="contacts.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Контакты</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="container mx-auto px-4 py-8 max-w-6xl">
|
||||
<div class="mb-8">
|
||||
<h2 class="text-3xl font-bold text-slate-800 mb-2">Расписание приема специалистов</h2>
|
||||
<p class="text-slate-600">График работы врачей на текущую неделю</p>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-2xl shadow-lg overflow-hidden border border-slate-100">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="schedule-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="rounded-tl-2xl">Специальность</th>
|
||||
<th>Врач</th>
|
||||
<th>Понедельник</th>
|
||||
<th>Вторник</th>
|
||||
<th>Среда</th>
|
||||
<th>Четверг</th>
|
||||
<th>Пятница</th>
|
||||
<th class="rounded-tr-2xl">Выходные</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr>
|
||||
<td rowspan="2" class="cell-merged border-r-2 border-sky-200">Терапевты</td>
|
||||
<td class="font-medium">Иванов И.И.</td>
|
||||
<td class="time-slot">09:00-13:00</td>
|
||||
<td class="time-slot">14:00-18:00</td>
|
||||
<td class="time-slot">09:00-13:00</td>
|
||||
<td class="time-slot">14:00-18:00</td>
|
||||
<td class="time-slot">09:00-13:00</td>
|
||||
<td rowspan="6" class="cell-merged text-center">
|
||||
<div class="flex flex-col items-center gap-2">
|
||||
<i data-lucide="calendar-x" class="w-8 h-8 text-sky-400"></i>
|
||||
<span>Приема нет</span>
|
||||
<span class="text-xs font-normal text-slate-500">(только экстренные случаи)</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-medium">Сидорова Е.Л.</td>
|
||||
<td class="time-slot">14:00-18:00</td>
|
||||
<td class="time-slot">09:00-13:00</td>
|
||||
<td class="time-slot">14:00-18:00</td>
|
||||
<td class="time-slot">09:00-13:00</td>
|
||||
<td class="time-slot">14:00-18:00</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td rowspan="2" class="cell-merged border-r-2 border-sky-200">Неврологи</td>
|
||||
<td class="font-medium">Петрова Л.Д.</td>
|
||||
<td class="time-slot">10:00-16:00</td>
|
||||
<td class="time-slot text-slate-400">—</td>
|
||||
<td class="time-slot">10:00-16:00</td>
|
||||
<td class="time-slot text-slate-400">—</td>
|
||||
<td class="time-slot">10:00-16:00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-medium">Орлова Г.Д.</td>
|
||||
<td class="time-slot text-slate-400">—</td>
|
||||
<td class="time-slot">10:00-16:00</td>
|
||||
<td class="time-slot text-slate-400">—</td>
|
||||
<td class="time-slot">10:00-16:00</td>
|
||||
<td class="time-slot text-slate-400">—</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td rowspan="2" class="cell-merged border-r-2 border-sky-200">УЗИ</td>
|
||||
<td class="font-medium">Гордеев О.Т</td>
|
||||
<td colspan="2" class="text-center text-emerald-600 font-medium bg-emerald-50">
|
||||
<i data-lucide="check-circle" class="w-4 h-4 inline mr-1"></i>
|
||||
08:00-14:00
|
||||
</td>
|
||||
<td class="time-slot text-slate-400">—</td>
|
||||
<td colspan="2" class="text-center text-emerald-600 font-medium bg-emerald-50">
|
||||
<i data-lucide="check-circle" class="w-4 h-4 inline mr-1"></i>
|
||||
08:00-14:00
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-medium">Арбатова Е.К.</td>
|
||||
<td class="time-slot text-slate-400">—</td>
|
||||
<td colspan="2" class="text-center text-emerald-600 font-medium bg-emerald-50">
|
||||
<i data-lucide="check-circle" class="w-4 h-4 inline mr-1"></i>
|
||||
12:00-18:00
|
||||
</td>
|
||||
<td class="time-slot text-slate-400">—</td>
|
||||
<td class="time-slot">12:00-16:00</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td class="cell-merged border-r-2 border-sky-200">Кардиологи</td>
|
||||
<td class="font-medium">Смирнов А.В.</td>
|
||||
<td class="time-slot">09:00-15:00</td>
|
||||
<td class="time-slot">09:00-15:00</td>
|
||||
<td class="time-slot">09:00-15:00</td>
|
||||
<td class="time-slot">09:00-15:00</td>
|
||||
<td class="time-slot">09:00-15:00</td>
|
||||
<td class="cell-merged text-center text-slate-400">
|
||||
<i data-lucide="x-circle" class="w-5 h-5 inline"></i>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td rowspan="2" class="cell-merged border-r-2 border-sky-200 rounded-bl-2xl">Эндокринологи</td>
|
||||
<td class="font-medium">Морозов П.С.</td>
|
||||
<td class="time-slot">11:00-17:00</td>
|
||||
<td class="time-slot text-slate-400">—</td>
|
||||
<td class="time-slot">11:00-17:00</td>
|
||||
<td class="time-slot text-slate-400">—</td>
|
||||
<td class="time-slot">11:00-17:00</td>
|
||||
<td rowspan="2" class="cell-merged text-center rounded-br-2xl text-slate-400">
|
||||
<i data-lucide="x-circle" class="w-5 h-5 inline"></i>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-medium">Васильева Т.А.</td>
|
||||
<td class="time-slot text-slate-400">—</td>
|
||||
<td class="time-slot">11:00-17:00</td>
|
||||
<td class="time-slot text-slate-400">—</td>
|
||||
<td class="time-slot">11:00-17:00</td>
|
||||
<td class="time-slot text-slate-400">—</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="p-6 bg-slate-50 border-t border-slate-200">
|
||||
<div class="flex flex-wrap gap-6 text-sm text-slate-600">
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="w-4 h-4 bg-emerald-50 border border-emerald-200 rounded"></div>
|
||||
<span>Усиленный прием</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="w-4 h-4 bg-sky-100 border border-sky-200 rounded"></div>
|
||||
<span>Специальность (объединение строк)</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-slate-400">—</span>
|
||||
<span>Выходной день врача</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 grid md:grid-cols-3 gap-6">
|
||||
<div class="bg-white rounded-xl shadow p-6 border border-slate-100 flex items-start gap-4">
|
||||
<div class="w-12 h-12 bg-amber-100 rounded-lg flex items-center justify-center flex-shrink-0">
|
||||
<i data-lucide="alert-circle" class="w-6 h-6 text-amber-600"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="font-semibold text-slate-800 mb-1">Важно</h4>
|
||||
<p class="text-sm text-slate-600">Расписание может меняться. Уточняйте актуальное время по телефону.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-xl shadow p-6 border border-slate-100 flex items-start gap-4">
|
||||
<div class="w-12 h-12 bg-sky-100 rounded-lg flex items-center justify-center flex-shrink-0">
|
||||
<i data-lucide="phone" class="w-6 h-6 text-sky-600"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="font-semibold text-slate-800 mb-1">Запись по телефону</h4>
|
||||
<p class="text-sm text-slate-600">+7 (495) 123-45-67 (круглосуточно)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-xl shadow p-6 border border-slate-100 flex items-start gap-4">
|
||||
<div class="w-12 h-12 bg-emerald-100 rounded-lg flex items-center justify-center flex-shrink-0">
|
||||
<i data-lucide="globe" class="w-6 h-6 text-emerald-600"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="font-semibold text-slate-800 mb-1">Онлайн-запись</h4>
|
||||
<p class="text-sm text-slate-600">Доступна через сайт и мобильное приложение</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="bg-slate-900 text-slate-300 mt-16">
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="flex flex-col md:flex-row items-center justify-between gap-4">
|
||||
<div class="flex items-center space-x-3">
|
||||
<i data-lucide="heart-pulse" class="w-6 h-6 text-sky-400"></i>
|
||||
<span class="font-semibold text-white">МедСэйв</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-slate-300 mb-2 md:mb-0">
|
||||
<i data-lucide="phone" class="w-4 h-4 text-sky-400"></i>
|
||||
<span class="font-medium text-white">+7 (123) 123-12-31</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center space-x-4">
|
||||
<span class="text-sm">Мы в социальных сетях:</span>
|
||||
<div class="flex space-x-3">
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-sky-500 hover:text-white transition" title="Telegram">
|
||||
<i data-lucide="send" class="w-5 h-5"></i>
|
||||
</a>
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-green-500 hover:text-white transition" title="WhatsApp">
|
||||
<i data-lucide="message-circle" class="w-5 h-5"></i>
|
||||
</a>
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-purple-600 hover:text-white transition" title="Viber">
|
||||
<i data-lucide="phone-call" class="w-5 h-5"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-sm text-slate-500">© 2024 МедСэйв. Все права защищены.</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
lucide.createIcons();
|
||||
function toggleMobileMenu() {
|
||||
document.getElementById('mobileMenu').classList.toggle('hidden');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
29
labWeb/lab4-6/style.css
Normal file
@@ -0,0 +1,29 @@
|
||||
body {
|
||||
padding: 2rem;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 16px;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
p {
|
||||
color: rgb(107, 114, 128);
|
||||
font-size: 15px;
|
||||
margin-bottom: 10px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.card {
|
||||
max-width: 620px;
|
||||
margin: 0 auto;
|
||||
padding: 16px;
|
||||
border: 1px solid lightgray;
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
.card p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
22
labWeb/lab7/index.js
Normal file
@@ -0,0 +1,22 @@
|
||||
let express = require(`express`);
|
||||
const app = express();
|
||||
const port = 3000;
|
||||
|
||||
app.listen(port, function () {
|
||||
console.log(`http://localhost:${port}`);
|
||||
});
|
||||
app.use(express.static(`public`));
|
||||
|
||||
const hbs = require(`hbs`);
|
||||
app.set(`views`, `views`);
|
||||
app.set(`view engine`, `hbs`);
|
||||
|
||||
console.log(4*32*1000*2*60*32/2**23);
|
||||
|
||||
app.get("/", function (req, res) {
|
||||
res.render("main");
|
||||
});
|
||||
|
||||
app.get("/hf", function (req, res) {
|
||||
res.render("head_and_footer");
|
||||
});
|
||||
1
labWeb/lab7/node_modules/.bin/handlebars
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../handlebars/bin/handlebars
|
||||
17
labWeb/lab7/node_modules/.bin/handlebars.cmd
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\handlebars\bin\handlebars" %*
|
||||
28
labWeb/lab7/node_modules/.bin/handlebars.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../handlebars/bin/handlebars" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../handlebars/bin/handlebars" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../handlebars/bin/handlebars" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../handlebars/bin/handlebars" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
12
labWeb/lab7/node_modules/.bin/mime
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../mime/cli.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../mime/cli.js" "$@"
|
||||
fi
|
||||
17
labWeb/lab7/node_modules/.bin/mime.cmd
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\mime\cli.js" %*
|
||||
28
labWeb/lab7/node_modules/.bin/mime.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../mime/cli.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../mime/cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../mime/cli.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../mime/cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
1
labWeb/lab7/node_modules/.bin/nodemon
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../nodemon/bin/nodemon.js
|
||||
17
labWeb/lab7/node_modules/.bin/nodemon.cmd
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\nodemon\bin\nodemon.js" %*
|
||||
28
labWeb/lab7/node_modules/.bin/nodemon.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../nodemon/bin/nodemon.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../nodemon/bin/nodemon.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../nodemon/bin/nodemon.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../nodemon/bin/nodemon.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
12
labWeb/lab7/node_modules/.bin/nodetouch
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../touch/bin/nodetouch.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../touch/bin/nodetouch.js" "$@"
|
||||
fi
|
||||
17
labWeb/lab7/node_modules/.bin/nodetouch.cmd
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\touch\bin\nodetouch.js" %*
|
||||
28
labWeb/lab7/node_modules/.bin/nodetouch.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../touch/bin/nodetouch.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../touch/bin/nodetouch.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../touch/bin/nodetouch.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../touch/bin/nodetouch.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
12
labWeb/lab7/node_modules/.bin/nopt
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../nopt/bin/nopt.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../nopt/bin/nopt.js" "$@"
|
||||
fi
|
||||
17
labWeb/lab7/node_modules/.bin/nopt.cmd
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\nopt\bin\nopt.js" %*
|
||||
28
labWeb/lab7/node_modules/.bin/nopt.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../nopt/bin/nopt.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../nopt/bin/nopt.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../nopt/bin/nopt.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../nopt/bin/nopt.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
1
labWeb/lab7/node_modules/.bin/npm
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../npm/bin/npm-cli.js
|
||||
17
labWeb/lab7/node_modules/.bin/npm.cmd
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\npm\bin\npm-cli.js" %*
|
||||
28
labWeb/lab7/node_modules/.bin/npm.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../npm/bin/npm-cli.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../npm/bin/npm-cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../npm/bin/npm-cli.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../npm/bin/npm-cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
1
labWeb/lab7/node_modules/.bin/npx
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../npm/bin/npx-cli.js
|
||||
17
labWeb/lab7/node_modules/.bin/npx.cmd
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\npm\bin\npx-cli.js" %*
|
||||
28
labWeb/lab7/node_modules/.bin/npx.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../npm/bin/npx-cli.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../npm/bin/npx-cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../npm/bin/npx-cli.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../npm/bin/npx-cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
12
labWeb/lab7/node_modules/.bin/semver
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../semver/bin/semver.js" "$@"
|
||||
fi
|
||||
17
labWeb/lab7/node_modules/.bin/semver.cmd
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\semver\bin\semver.js" %*
|
||||
28
labWeb/lab7/node_modules/.bin/semver.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../semver/bin/semver.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../semver/bin/semver.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
1
labWeb/lab7/node_modules/.bin/uglifyjs
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../uglify-js/bin/uglifyjs
|
||||
17
labWeb/lab7/node_modules/.bin/uglifyjs.cmd
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\uglify-js\bin\uglifyjs" %*
|
||||
28
labWeb/lab7/node_modules/.bin/uglifyjs.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../uglify-js/bin/uglifyjs" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../uglify-js/bin/uglifyjs" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../uglify-js/bin/uglifyjs" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../uglify-js/bin/uglifyjs" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
3609
labWeb/lab7/node_modules/.package-lock.json
generated
vendored
Normal file
46
labWeb/lab7/node_modules/abbrev/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
This software is dual-licensed under the ISC and MIT licenses.
|
||||
You may use this software under EITHER of the following licenses.
|
||||
|
||||
----------
|
||||
|
||||
The ISC License
|
||||
|
||||
Copyright (c) Isaac Z. Schlueter and Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
----------
|
||||
|
||||
Copyright Isaac Z. Schlueter and Contributors
|
||||
All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
23
labWeb/lab7/node_modules/abbrev/README.md
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
# abbrev-js
|
||||
|
||||
Just like [ruby's Abbrev](http://apidock.com/ruby/Abbrev).
|
||||
|
||||
Usage:
|
||||
|
||||
var abbrev = require("abbrev");
|
||||
abbrev("foo", "fool", "folding", "flop");
|
||||
|
||||
// returns:
|
||||
{ fl: 'flop'
|
||||
, flo: 'flop'
|
||||
, flop: 'flop'
|
||||
, fol: 'folding'
|
||||
, fold: 'folding'
|
||||
, foldi: 'folding'
|
||||
, foldin: 'folding'
|
||||
, folding: 'folding'
|
||||
, foo: 'foo'
|
||||
, fool: 'fool'
|
||||
}
|
||||
|
||||
This is handy for command-line scripts, or other cases where you want to be able to accept shorthands.
|
||||
61
labWeb/lab7/node_modules/abbrev/abbrev.js
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
module.exports = exports = abbrev.abbrev = abbrev
|
||||
|
||||
abbrev.monkeyPatch = monkeyPatch
|
||||
|
||||
function monkeyPatch () {
|
||||
Object.defineProperty(Array.prototype, 'abbrev', {
|
||||
value: function () { return abbrev(this) },
|
||||
enumerable: false, configurable: true, writable: true
|
||||
})
|
||||
|
||||
Object.defineProperty(Object.prototype, 'abbrev', {
|
||||
value: function () { return abbrev(Object.keys(this)) },
|
||||
enumerable: false, configurable: true, writable: true
|
||||
})
|
||||
}
|
||||
|
||||
function abbrev (list) {
|
||||
if (arguments.length !== 1 || !Array.isArray(list)) {
|
||||
list = Array.prototype.slice.call(arguments, 0)
|
||||
}
|
||||
for (var i = 0, l = list.length, args = [] ; i < l ; i ++) {
|
||||
args[i] = typeof list[i] === "string" ? list[i] : String(list[i])
|
||||
}
|
||||
|
||||
// sort them lexicographically, so that they're next to their nearest kin
|
||||
args = args.sort(lexSort)
|
||||
|
||||
// walk through each, seeing how much it has in common with the next and previous
|
||||
var abbrevs = {}
|
||||
, prev = ""
|
||||
for (var i = 0, l = args.length ; i < l ; i ++) {
|
||||
var current = args[i]
|
||||
, next = args[i + 1] || ""
|
||||
, nextMatches = true
|
||||
, prevMatches = true
|
||||
if (current === next) continue
|
||||
for (var j = 0, cl = current.length ; j < cl ; j ++) {
|
||||
var curChar = current.charAt(j)
|
||||
nextMatches = nextMatches && curChar === next.charAt(j)
|
||||
prevMatches = prevMatches && curChar === prev.charAt(j)
|
||||
if (!nextMatches && !prevMatches) {
|
||||
j ++
|
||||
break
|
||||
}
|
||||
}
|
||||
prev = current
|
||||
if (j === cl) {
|
||||
abbrevs[current] = current
|
||||
continue
|
||||
}
|
||||
for (var a = current.substr(0, j) ; j <= cl ; j ++) {
|
||||
abbrevs[a] = current
|
||||
a += current.charAt(j)
|
||||
}
|
||||
}
|
||||
return abbrevs
|
||||
}
|
||||
|
||||
function lexSort (a, b) {
|
||||
return a === b ? 0 : a > b ? 1 : -1
|
||||
}
|
||||
21
labWeb/lab7/node_modules/abbrev/package.json
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "abbrev",
|
||||
"version": "1.1.1",
|
||||
"description": "Like ruby's abbrev module, but in js",
|
||||
"author": "Isaac Z. Schlueter <i@izs.me>",
|
||||
"main": "abbrev.js",
|
||||
"scripts": {
|
||||
"test": "tap test.js --100",
|
||||
"preversion": "npm test",
|
||||
"postversion": "npm publish",
|
||||
"postpublish": "git push origin --all; git push origin --tags"
|
||||
},
|
||||
"repository": "http://github.com/isaacs/abbrev-js",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"tap": "^10.1"
|
||||
},
|
||||
"files": [
|
||||
"abbrev.js"
|
||||
]
|
||||
}
|
||||
243
labWeb/lab7/node_modules/accepts/HISTORY.md
generated
vendored
Normal file
@@ -0,0 +1,243 @@
|
||||
1.3.8 / 2022-02-02
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.34
|
||||
- deps: mime-db@~1.51.0
|
||||
* deps: negotiator@0.6.3
|
||||
|
||||
1.3.7 / 2019-04-29
|
||||
==================
|
||||
|
||||
* deps: negotiator@0.6.2
|
||||
- Fix sorting charset, encoding, and language with extra parameters
|
||||
|
||||
1.3.6 / 2019-04-28
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.24
|
||||
- deps: mime-db@~1.40.0
|
||||
|
||||
1.3.5 / 2018-02-28
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.18
|
||||
- deps: mime-db@~1.33.0
|
||||
|
||||
1.3.4 / 2017-08-22
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.16
|
||||
- deps: mime-db@~1.29.0
|
||||
|
||||
1.3.3 / 2016-05-02
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.11
|
||||
- deps: mime-db@~1.23.0
|
||||
* deps: negotiator@0.6.1
|
||||
- perf: improve `Accept` parsing speed
|
||||
- perf: improve `Accept-Charset` parsing speed
|
||||
- perf: improve `Accept-Encoding` parsing speed
|
||||
- perf: improve `Accept-Language` parsing speed
|
||||
|
||||
1.3.2 / 2016-03-08
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.10
|
||||
- Fix extension of `application/dash+xml`
|
||||
- Update primary extension for `audio/mp4`
|
||||
- deps: mime-db@~1.22.0
|
||||
|
||||
1.3.1 / 2016-01-19
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.9
|
||||
- deps: mime-db@~1.21.0
|
||||
|
||||
1.3.0 / 2015-09-29
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.7
|
||||
- deps: mime-db@~1.19.0
|
||||
* deps: negotiator@0.6.0
|
||||
- Fix including type extensions in parameters in `Accept` parsing
|
||||
- Fix parsing `Accept` parameters with quoted equals
|
||||
- Fix parsing `Accept` parameters with quoted semicolons
|
||||
- Lazy-load modules from main entry point
|
||||
- perf: delay type concatenation until needed
|
||||
- perf: enable strict mode
|
||||
- perf: hoist regular expressions
|
||||
- perf: remove closures getting spec properties
|
||||
- perf: remove a closure from media type parsing
|
||||
- perf: remove property delete from media type parsing
|
||||
|
||||
1.2.13 / 2015-09-06
|
||||
===================
|
||||
|
||||
* deps: mime-types@~2.1.6
|
||||
- deps: mime-db@~1.18.0
|
||||
|
||||
1.2.12 / 2015-07-30
|
||||
===================
|
||||
|
||||
* deps: mime-types@~2.1.4
|
||||
- deps: mime-db@~1.16.0
|
||||
|
||||
1.2.11 / 2015-07-16
|
||||
===================
|
||||
|
||||
* deps: mime-types@~2.1.3
|
||||
- deps: mime-db@~1.15.0
|
||||
|
||||
1.2.10 / 2015-07-01
|
||||
===================
|
||||
|
||||
* deps: mime-types@~2.1.2
|
||||
- deps: mime-db@~1.14.0
|
||||
|
||||
1.2.9 / 2015-06-08
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.1
|
||||
- perf: fix deopt during mapping
|
||||
|
||||
1.2.8 / 2015-06-07
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.0
|
||||
- deps: mime-db@~1.13.0
|
||||
* perf: avoid argument reassignment & argument slice
|
||||
* perf: avoid negotiator recursive construction
|
||||
* perf: enable strict mode
|
||||
* perf: remove unnecessary bitwise operator
|
||||
|
||||
1.2.7 / 2015-05-10
|
||||
==================
|
||||
|
||||
* deps: negotiator@0.5.3
|
||||
- Fix media type parameter matching to be case-insensitive
|
||||
|
||||
1.2.6 / 2015-05-07
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.11
|
||||
- deps: mime-db@~1.9.1
|
||||
* deps: negotiator@0.5.2
|
||||
- Fix comparing media types with quoted values
|
||||
- Fix splitting media types with quoted commas
|
||||
|
||||
1.2.5 / 2015-03-13
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.10
|
||||
- deps: mime-db@~1.8.0
|
||||
|
||||
1.2.4 / 2015-02-14
|
||||
==================
|
||||
|
||||
* Support Node.js 0.6
|
||||
* deps: mime-types@~2.0.9
|
||||
- deps: mime-db@~1.7.0
|
||||
* deps: negotiator@0.5.1
|
||||
- Fix preference sorting to be stable for long acceptable lists
|
||||
|
||||
1.2.3 / 2015-01-31
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.8
|
||||
- deps: mime-db@~1.6.0
|
||||
|
||||
1.2.2 / 2014-12-30
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.7
|
||||
- deps: mime-db@~1.5.0
|
||||
|
||||
1.2.1 / 2014-12-30
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.5
|
||||
- deps: mime-db@~1.3.1
|
||||
|
||||
1.2.0 / 2014-12-19
|
||||
==================
|
||||
|
||||
* deps: negotiator@0.5.0
|
||||
- Fix list return order when large accepted list
|
||||
- Fix missing identity encoding when q=0 exists
|
||||
- Remove dynamic building of Negotiator class
|
||||
|
||||
1.1.4 / 2014-12-10
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.4
|
||||
- deps: mime-db@~1.3.0
|
||||
|
||||
1.1.3 / 2014-11-09
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.3
|
||||
- deps: mime-db@~1.2.0
|
||||
|
||||
1.1.2 / 2014-10-14
|
||||
==================
|
||||
|
||||
* deps: negotiator@0.4.9
|
||||
- Fix error when media type has invalid parameter
|
||||
|
||||
1.1.1 / 2014-09-28
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.2
|
||||
- deps: mime-db@~1.1.0
|
||||
* deps: negotiator@0.4.8
|
||||
- Fix all negotiations to be case-insensitive
|
||||
- Stable sort preferences of same quality according to client order
|
||||
|
||||
1.1.0 / 2014-09-02
|
||||
==================
|
||||
|
||||
* update `mime-types`
|
||||
|
||||
1.0.7 / 2014-07-04
|
||||
==================
|
||||
|
||||
* Fix wrong type returned from `type` when match after unknown extension
|
||||
|
||||
1.0.6 / 2014-06-24
|
||||
==================
|
||||
|
||||
* deps: negotiator@0.4.7
|
||||
|
||||
1.0.5 / 2014-06-20
|
||||
==================
|
||||
|
||||
* fix crash when unknown extension given
|
||||
|
||||
1.0.4 / 2014-06-19
|
||||
==================
|
||||
|
||||
* use `mime-types`
|
||||
|
||||
1.0.3 / 2014-06-11
|
||||
==================
|
||||
|
||||
* deps: negotiator@0.4.6
|
||||
- Order by specificity when quality is the same
|
||||
|
||||
1.0.2 / 2014-05-29
|
||||
==================
|
||||
|
||||
* Fix interpretation when header not in request
|
||||
* deps: pin negotiator@0.4.5
|
||||
|
||||
1.0.1 / 2014-01-18
|
||||
==================
|
||||
|
||||
* Identity encoding isn't always acceptable
|
||||
* deps: negotiator@~0.4.0
|
||||
|
||||
1.0.0 / 2013-12-27
|
||||
==================
|
||||
|
||||
* Genesis
|
||||
23
labWeb/lab7/node_modules/accepts/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
|
||||
Copyright (c) 2015 Douglas Christopher Wilson <doug@somethingdoug.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
140
labWeb/lab7/node_modules/accepts/README.md
generated
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
# accepts
|
||||
|
||||
[![NPM Version][npm-version-image]][npm-url]
|
||||
[![NPM Downloads][npm-downloads-image]][npm-url]
|
||||
[![Node.js Version][node-version-image]][node-version-url]
|
||||
[![Build Status][github-actions-ci-image]][github-actions-ci-url]
|
||||
[![Test Coverage][coveralls-image]][coveralls-url]
|
||||
|
||||
Higher level content negotiation based on [negotiator](https://www.npmjs.com/package/negotiator).
|
||||
Extracted from [koa](https://www.npmjs.com/package/koa) for general use.
|
||||
|
||||
In addition to negotiator, it allows:
|
||||
|
||||
- Allows types as an array or arguments list, ie `(['text/html', 'application/json'])`
|
||||
as well as `('text/html', 'application/json')`.
|
||||
- Allows type shorthands such as `json`.
|
||||
- Returns `false` when no types match
|
||||
- Treats non-existent headers as `*`
|
||||
|
||||
## Installation
|
||||
|
||||
This is a [Node.js](https://nodejs.org/en/) module available through the
|
||||
[npm registry](https://www.npmjs.com/). Installation is done using the
|
||||
[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
|
||||
|
||||
```sh
|
||||
$ npm install accepts
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```js
|
||||
var accepts = require('accepts')
|
||||
```
|
||||
|
||||
### accepts(req)
|
||||
|
||||
Create a new `Accepts` object for the given `req`.
|
||||
|
||||
#### .charset(charsets)
|
||||
|
||||
Return the first accepted charset. If nothing in `charsets` is accepted,
|
||||
then `false` is returned.
|
||||
|
||||
#### .charsets()
|
||||
|
||||
Return the charsets that the request accepts, in the order of the client's
|
||||
preference (most preferred first).
|
||||
|
||||
#### .encoding(encodings)
|
||||
|
||||
Return the first accepted encoding. If nothing in `encodings` is accepted,
|
||||
then `false` is returned.
|
||||
|
||||
#### .encodings()
|
||||
|
||||
Return the encodings that the request accepts, in the order of the client's
|
||||
preference (most preferred first).
|
||||
|
||||
#### .language(languages)
|
||||
|
||||
Return the first accepted language. If nothing in `languages` is accepted,
|
||||
then `false` is returned.
|
||||
|
||||
#### .languages()
|
||||
|
||||
Return the languages that the request accepts, in the order of the client's
|
||||
preference (most preferred first).
|
||||
|
||||
#### .type(types)
|
||||
|
||||
Return the first accepted type (and it is returned as the same text as what
|
||||
appears in the `types` array). If nothing in `types` is accepted, then `false`
|
||||
is returned.
|
||||
|
||||
The `types` array can contain full MIME types or file extensions. Any value
|
||||
that is not a full MIME types is passed to `require('mime-types').lookup`.
|
||||
|
||||
#### .types()
|
||||
|
||||
Return the types that the request accepts, in the order of the client's
|
||||
preference (most preferred first).
|
||||
|
||||
## Examples
|
||||
|
||||
### Simple type negotiation
|
||||
|
||||
This simple example shows how to use `accepts` to return a different typed
|
||||
respond body based on what the client wants to accept. The server lists it's
|
||||
preferences in order and will get back the best match between the client and
|
||||
server.
|
||||
|
||||
```js
|
||||
var accepts = require('accepts')
|
||||
var http = require('http')
|
||||
|
||||
function app (req, res) {
|
||||
var accept = accepts(req)
|
||||
|
||||
// the order of this list is significant; should be server preferred order
|
||||
switch (accept.type(['json', 'html'])) {
|
||||
case 'json':
|
||||
res.setHeader('Content-Type', 'application/json')
|
||||
res.write('{"hello":"world!"}')
|
||||
break
|
||||
case 'html':
|
||||
res.setHeader('Content-Type', 'text/html')
|
||||
res.write('<b>hello, world!</b>')
|
||||
break
|
||||
default:
|
||||
// the fallback is text/plain, so no need to specify it above
|
||||
res.setHeader('Content-Type', 'text/plain')
|
||||
res.write('hello, world!')
|
||||
break
|
||||
}
|
||||
|
||||
res.end()
|
||||
}
|
||||
|
||||
http.createServer(app).listen(3000)
|
||||
```
|
||||
|
||||
You can test this out with the cURL program:
|
||||
```sh
|
||||
curl -I -H'Accept: text/html' http://localhost:3000/
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE)
|
||||
|
||||
[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/accepts/master
|
||||
[coveralls-url]: https://coveralls.io/r/jshttp/accepts?branch=master
|
||||
[github-actions-ci-image]: https://badgen.net/github/checks/jshttp/accepts/master?label=ci
|
||||
[github-actions-ci-url]: https://github.com/jshttp/accepts/actions/workflows/ci.yml
|
||||
[node-version-image]: https://badgen.net/npm/node/accepts
|
||||
[node-version-url]: https://nodejs.org/en/download
|
||||
[npm-downloads-image]: https://badgen.net/npm/dm/accepts
|
||||
[npm-url]: https://npmjs.org/package/accepts
|
||||
[npm-version-image]: https://badgen.net/npm/v/accepts
|
||||
238
labWeb/lab7/node_modules/accepts/index.js
generated
vendored
Normal file
@@ -0,0 +1,238 @@
|
||||
/*!
|
||||
* accepts
|
||||
* Copyright(c) 2014 Jonathan Ong
|
||||
* Copyright(c) 2015 Douglas Christopher Wilson
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
* @private
|
||||
*/
|
||||
|
||||
var Negotiator = require('negotiator')
|
||||
var mime = require('mime-types')
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
* @public
|
||||
*/
|
||||
|
||||
module.exports = Accepts
|
||||
|
||||
/**
|
||||
* Create a new Accepts object for the given req.
|
||||
*
|
||||
* @param {object} req
|
||||
* @public
|
||||
*/
|
||||
|
||||
function Accepts (req) {
|
||||
if (!(this instanceof Accepts)) {
|
||||
return new Accepts(req)
|
||||
}
|
||||
|
||||
this.headers = req.headers
|
||||
this.negotiator = new Negotiator(req)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given `type(s)` is acceptable, returning
|
||||
* the best match when true, otherwise `undefined`, in which
|
||||
* case you should respond with 406 "Not Acceptable".
|
||||
*
|
||||
* The `type` value may be a single mime type string
|
||||
* such as "application/json", the extension name
|
||||
* such as "json" or an array `["json", "html", "text/plain"]`. When a list
|
||||
* or array is given the _best_ match, if any is returned.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* // Accept: text/html
|
||||
* this.types('html');
|
||||
* // => "html"
|
||||
*
|
||||
* // Accept: text/*, application/json
|
||||
* this.types('html');
|
||||
* // => "html"
|
||||
* this.types('text/html');
|
||||
* // => "text/html"
|
||||
* this.types('json', 'text');
|
||||
* // => "json"
|
||||
* this.types('application/json');
|
||||
* // => "application/json"
|
||||
*
|
||||
* // Accept: text/*, application/json
|
||||
* this.types('image/png');
|
||||
* this.types('png');
|
||||
* // => undefined
|
||||
*
|
||||
* // Accept: text/*;q=.5, application/json
|
||||
* this.types(['html', 'json']);
|
||||
* this.types('html', 'json');
|
||||
* // => "json"
|
||||
*
|
||||
* @param {String|Array} types...
|
||||
* @return {String|Array|Boolean}
|
||||
* @public
|
||||
*/
|
||||
|
||||
Accepts.prototype.type =
|
||||
Accepts.prototype.types = function (types_) {
|
||||
var types = types_
|
||||
|
||||
// support flattened arguments
|
||||
if (types && !Array.isArray(types)) {
|
||||
types = new Array(arguments.length)
|
||||
for (var i = 0; i < types.length; i++) {
|
||||
types[i] = arguments[i]
|
||||
}
|
||||
}
|
||||
|
||||
// no types, return all requested types
|
||||
if (!types || types.length === 0) {
|
||||
return this.negotiator.mediaTypes()
|
||||
}
|
||||
|
||||
// no accept header, return first given type
|
||||
if (!this.headers.accept) {
|
||||
return types[0]
|
||||
}
|
||||
|
||||
var mimes = types.map(extToMime)
|
||||
var accepts = this.negotiator.mediaTypes(mimes.filter(validMime))
|
||||
var first = accepts[0]
|
||||
|
||||
return first
|
||||
? types[mimes.indexOf(first)]
|
||||
: false
|
||||
}
|
||||
|
||||
/**
|
||||
* Return accepted encodings or best fit based on `encodings`.
|
||||
*
|
||||
* Given `Accept-Encoding: gzip, deflate`
|
||||
* an array sorted by quality is returned:
|
||||
*
|
||||
* ['gzip', 'deflate']
|
||||
*
|
||||
* @param {String|Array} encodings...
|
||||
* @return {String|Array}
|
||||
* @public
|
||||
*/
|
||||
|
||||
Accepts.prototype.encoding =
|
||||
Accepts.prototype.encodings = function (encodings_) {
|
||||
var encodings = encodings_
|
||||
|
||||
// support flattened arguments
|
||||
if (encodings && !Array.isArray(encodings)) {
|
||||
encodings = new Array(arguments.length)
|
||||
for (var i = 0; i < encodings.length; i++) {
|
||||
encodings[i] = arguments[i]
|
||||
}
|
||||
}
|
||||
|
||||
// no encodings, return all requested encodings
|
||||
if (!encodings || encodings.length === 0) {
|
||||
return this.negotiator.encodings()
|
||||
}
|
||||
|
||||
return this.negotiator.encodings(encodings)[0] || false
|
||||
}
|
||||
|
||||
/**
|
||||
* Return accepted charsets or best fit based on `charsets`.
|
||||
*
|
||||
* Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5`
|
||||
* an array sorted by quality is returned:
|
||||
*
|
||||
* ['utf-8', 'utf-7', 'iso-8859-1']
|
||||
*
|
||||
* @param {String|Array} charsets...
|
||||
* @return {String|Array}
|
||||
* @public
|
||||
*/
|
||||
|
||||
Accepts.prototype.charset =
|
||||
Accepts.prototype.charsets = function (charsets_) {
|
||||
var charsets = charsets_
|
||||
|
||||
// support flattened arguments
|
||||
if (charsets && !Array.isArray(charsets)) {
|
||||
charsets = new Array(arguments.length)
|
||||
for (var i = 0; i < charsets.length; i++) {
|
||||
charsets[i] = arguments[i]
|
||||
}
|
||||
}
|
||||
|
||||
// no charsets, return all requested charsets
|
||||
if (!charsets || charsets.length === 0) {
|
||||
return this.negotiator.charsets()
|
||||
}
|
||||
|
||||
return this.negotiator.charsets(charsets)[0] || false
|
||||
}
|
||||
|
||||
/**
|
||||
* Return accepted languages or best fit based on `langs`.
|
||||
*
|
||||
* Given `Accept-Language: en;q=0.8, es, pt`
|
||||
* an array sorted by quality is returned:
|
||||
*
|
||||
* ['es', 'pt', 'en']
|
||||
*
|
||||
* @param {String|Array} langs...
|
||||
* @return {Array|String}
|
||||
* @public
|
||||
*/
|
||||
|
||||
Accepts.prototype.lang =
|
||||
Accepts.prototype.langs =
|
||||
Accepts.prototype.language =
|
||||
Accepts.prototype.languages = function (languages_) {
|
||||
var languages = languages_
|
||||
|
||||
// support flattened arguments
|
||||
if (languages && !Array.isArray(languages)) {
|
||||
languages = new Array(arguments.length)
|
||||
for (var i = 0; i < languages.length; i++) {
|
||||
languages[i] = arguments[i]
|
||||
}
|
||||
}
|
||||
|
||||
// no languages, return all requested languages
|
||||
if (!languages || languages.length === 0) {
|
||||
return this.negotiator.languages()
|
||||
}
|
||||
|
||||
return this.negotiator.languages(languages)[0] || false
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert extnames to mime.
|
||||
*
|
||||
* @param {String} type
|
||||
* @return {String}
|
||||
* @private
|
||||
*/
|
||||
|
||||
function extToMime (type) {
|
||||
return type.indexOf('/') === -1
|
||||
? mime.lookup(type)
|
||||
: type
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if mime is valid.
|
||||
*
|
||||
* @param {String} type
|
||||
* @return {String}
|
||||
* @private
|
||||
*/
|
||||
|
||||
function validMime (type) {
|
||||
return typeof type === 'string'
|
||||
}
|
||||
47
labWeb/lab7/node_modules/accepts/package.json
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"name": "accepts",
|
||||
"description": "Higher-level content negotiation",
|
||||
"version": "1.3.8",
|
||||
"contributors": [
|
||||
"Douglas Christopher Wilson <doug@somethingdoug.com>",
|
||||
"Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)"
|
||||
],
|
||||
"license": "MIT",
|
||||
"repository": "jshttp/accepts",
|
||||
"dependencies": {
|
||||
"mime-types": "~2.1.34",
|
||||
"negotiator": "0.6.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"deep-equal": "1.0.1",
|
||||
"eslint": "7.32.0",
|
||||
"eslint-config-standard": "14.1.1",
|
||||
"eslint-plugin-import": "2.25.4",
|
||||
"eslint-plugin-markdown": "2.2.1",
|
||||
"eslint-plugin-node": "11.1.0",
|
||||
"eslint-plugin-promise": "4.3.1",
|
||||
"eslint-plugin-standard": "4.1.0",
|
||||
"mocha": "9.2.0",
|
||||
"nyc": "15.1.0"
|
||||
},
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"HISTORY.md",
|
||||
"index.js"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"test": "mocha --reporter spec --check-leaks --bail test/",
|
||||
"test-ci": "nyc --reporter=lcov --reporter=text npm test",
|
||||
"test-cov": "nyc --reporter=html --reporter=text npm test"
|
||||
},
|
||||
"keywords": [
|
||||
"content",
|
||||
"negotiation",
|
||||
"accept",
|
||||
"accepts"
|
||||
]
|
||||
}
|
||||
15
labWeb/lab7/node_modules/anymatch/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
The ISC License
|
||||
|
||||
Copyright (c) 2019 Elan Shanker, Paul Miller (https://paulmillr.com)
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
87
labWeb/lab7/node_modules/anymatch/README.md
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
anymatch [](https://travis-ci.org/micromatch/anymatch) [](https://coveralls.io/r/micromatch/anymatch?branch=master)
|
||||
======
|
||||
Javascript module to match a string against a regular expression, glob, string,
|
||||
or function that takes the string as an argument and returns a truthy or falsy
|
||||
value. The matcher can also be an array of any or all of these. Useful for
|
||||
allowing a very flexible user-defined config to define things like file paths.
|
||||
|
||||
__Note: This module has Bash-parity, please be aware that Windows-style backslashes are not supported as separators. See https://github.com/micromatch/micromatch#backslashes for more information.__
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
```sh
|
||||
npm install anymatch
|
||||
```
|
||||
|
||||
#### anymatch(matchers, testString, [returnIndex], [options])
|
||||
* __matchers__: (_Array|String|RegExp|Function_)
|
||||
String to be directly matched, string with glob patterns, regular expression
|
||||
test, function that takes the testString as an argument and returns a truthy
|
||||
value if it should be matched, or an array of any number and mix of these types.
|
||||
* __testString__: (_String|Array_) The string to test against the matchers. If
|
||||
passed as an array, the first element of the array will be used as the
|
||||
`testString` for non-function matchers, while the entire array will be applied
|
||||
as the arguments for function matchers.
|
||||
* __options__: (_Object_ [optional]_) Any of the [picomatch](https://github.com/micromatch/picomatch#options) options.
|
||||
* __returnIndex__: (_Boolean [optional]_) If true, return the array index of
|
||||
the first matcher that that testString matched, or -1 if no match, instead of a
|
||||
boolean result.
|
||||
|
||||
```js
|
||||
const anymatch = require('anymatch');
|
||||
|
||||
const matchers = [ 'path/to/file.js', 'path/anyjs/**/*.js', /foo.js$/, string => string.includes('bar') && string.length > 10 ] ;
|
||||
|
||||
anymatch(matchers, 'path/to/file.js'); // true
|
||||
anymatch(matchers, 'path/anyjs/baz.js'); // true
|
||||
anymatch(matchers, 'path/to/foo.js'); // true
|
||||
anymatch(matchers, 'path/to/bar.js'); // true
|
||||
anymatch(matchers, 'bar.js'); // false
|
||||
|
||||
// returnIndex = true
|
||||
anymatch(matchers, 'foo.js', {returnIndex: true}); // 2
|
||||
anymatch(matchers, 'path/anyjs/foo.js', {returnIndex: true}); // 1
|
||||
|
||||
// any picomatc
|
||||
|
||||
// using globs to match directories and their children
|
||||
anymatch('node_modules', 'node_modules'); // true
|
||||
anymatch('node_modules', 'node_modules/somelib/index.js'); // false
|
||||
anymatch('node_modules/**', 'node_modules/somelib/index.js'); // true
|
||||
anymatch('node_modules/**', '/absolute/path/to/node_modules/somelib/index.js'); // false
|
||||
anymatch('**/node_modules/**', '/absolute/path/to/node_modules/somelib/index.js'); // true
|
||||
|
||||
const matcher = anymatch(matchers);
|
||||
['foo.js', 'bar.js'].filter(matcher); // [ 'foo.js' ]
|
||||
anymatch master* ❯
|
||||
|
||||
```
|
||||
|
||||
#### anymatch(matchers)
|
||||
You can also pass in only your matcher(s) to get a curried function that has
|
||||
already been bound to the provided matching criteria. This can be used as an
|
||||
`Array#filter` callback.
|
||||
|
||||
```js
|
||||
var matcher = anymatch(matchers);
|
||||
|
||||
matcher('path/to/file.js'); // true
|
||||
matcher('path/anyjs/baz.js', true); // 1
|
||||
|
||||
['foo.js', 'bar.js'].filter(matcher); // ['foo.js']
|
||||
```
|
||||
|
||||
Changelog
|
||||
----------
|
||||
[See release notes page on GitHub](https://github.com/micromatch/anymatch/releases)
|
||||
|
||||
- **v3.0:** Removed `startIndex` and `endIndex` arguments. Node 8.x-only.
|
||||
- **v2.0:** [micromatch](https://github.com/jonschlinkert/micromatch) moves away from minimatch-parity and inline with Bash. This includes handling backslashes differently (see https://github.com/micromatch/micromatch#backslashes for more information).
|
||||
- **v1.2:** anymatch uses [micromatch](https://github.com/jonschlinkert/micromatch)
|
||||
for glob pattern matching. Issues with glob pattern matching should be
|
||||
reported directly to the [micromatch issue tracker](https://github.com/jonschlinkert/micromatch/issues).
|
||||
|
||||
License
|
||||
-------
|
||||
[ISC](https://raw.github.com/micromatch/anymatch/master/LICENSE)
|
||||
20
labWeb/lab7/node_modules/anymatch/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
type AnymatchFn = (testString: string) => boolean;
|
||||
type AnymatchPattern = string|RegExp|AnymatchFn;
|
||||
type AnymatchMatcher = AnymatchPattern|AnymatchPattern[]
|
||||
type AnymatchTester = {
|
||||
(testString: string|any[], returnIndex: true): number;
|
||||
(testString: string|any[]): boolean;
|
||||
}
|
||||
|
||||
type PicomatchOptions = {dot: boolean};
|
||||
|
||||
declare const anymatch: {
|
||||
(matchers: AnymatchMatcher): AnymatchTester;
|
||||
(matchers: AnymatchMatcher, testString: null, returnIndex: true | PicomatchOptions): AnymatchTester;
|
||||
(matchers: AnymatchMatcher, testString: string|any[], returnIndex: true | PicomatchOptions): number;
|
||||
(matchers: AnymatchMatcher, testString: string|any[]): boolean;
|
||||
}
|
||||
|
||||
export {AnymatchMatcher as Matcher}
|
||||
export {AnymatchTester as Tester}
|
||||
export default anymatch
|
||||
104
labWeb/lab7/node_modules/anymatch/index.js
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
|
||||
const picomatch = require('picomatch');
|
||||
const normalizePath = require('normalize-path');
|
||||
|
||||
/**
|
||||
* @typedef {(testString: string) => boolean} AnymatchFn
|
||||
* @typedef {string|RegExp|AnymatchFn} AnymatchPattern
|
||||
* @typedef {AnymatchPattern|AnymatchPattern[]} AnymatchMatcher
|
||||
*/
|
||||
const BANG = '!';
|
||||
const DEFAULT_OPTIONS = {returnIndex: false};
|
||||
const arrify = (item) => Array.isArray(item) ? item : [item];
|
||||
|
||||
/**
|
||||
* @param {AnymatchPattern} matcher
|
||||
* @param {object} options
|
||||
* @returns {AnymatchFn}
|
||||
*/
|
||||
const createPattern = (matcher, options) => {
|
||||
if (typeof matcher === 'function') {
|
||||
return matcher;
|
||||
}
|
||||
if (typeof matcher === 'string') {
|
||||
const glob = picomatch(matcher, options);
|
||||
return (string) => matcher === string || glob(string);
|
||||
}
|
||||
if (matcher instanceof RegExp) {
|
||||
return (string) => matcher.test(string);
|
||||
}
|
||||
return (string) => false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Array<Function>} patterns
|
||||
* @param {Array<Function>} negPatterns
|
||||
* @param {String|Array} args
|
||||
* @param {Boolean} returnIndex
|
||||
* @returns {boolean|number}
|
||||
*/
|
||||
const matchPatterns = (patterns, negPatterns, args, returnIndex) => {
|
||||
const isList = Array.isArray(args);
|
||||
const _path = isList ? args[0] : args;
|
||||
if (!isList && typeof _path !== 'string') {
|
||||
throw new TypeError('anymatch: second argument must be a string: got ' +
|
||||
Object.prototype.toString.call(_path))
|
||||
}
|
||||
const path = normalizePath(_path, false);
|
||||
|
||||
for (let index = 0; index < negPatterns.length; index++) {
|
||||
const nglob = negPatterns[index];
|
||||
if (nglob(path)) {
|
||||
return returnIndex ? -1 : false;
|
||||
}
|
||||
}
|
||||
|
||||
const applied = isList && [path].concat(args.slice(1));
|
||||
for (let index = 0; index < patterns.length; index++) {
|
||||
const pattern = patterns[index];
|
||||
if (isList ? pattern(...applied) : pattern(path)) {
|
||||
return returnIndex ? index : true;
|
||||
}
|
||||
}
|
||||
|
||||
return returnIndex ? -1 : false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {AnymatchMatcher} matchers
|
||||
* @param {Array|string} testString
|
||||
* @param {object} options
|
||||
* @returns {boolean|number|Function}
|
||||
*/
|
||||
const anymatch = (matchers, testString, options = DEFAULT_OPTIONS) => {
|
||||
if (matchers == null) {
|
||||
throw new TypeError('anymatch: specify first argument');
|
||||
}
|
||||
const opts = typeof options === 'boolean' ? {returnIndex: options} : options;
|
||||
const returnIndex = opts.returnIndex || false;
|
||||
|
||||
// Early cache for matchers.
|
||||
const mtchers = arrify(matchers);
|
||||
const negatedGlobs = mtchers
|
||||
.filter(item => typeof item === 'string' && item.charAt(0) === BANG)
|
||||
.map(item => item.slice(1))
|
||||
.map(item => picomatch(item, opts));
|
||||
const patterns = mtchers
|
||||
.filter(item => typeof item !== 'string' || (typeof item === 'string' && item.charAt(0) !== BANG))
|
||||
.map(matcher => createPattern(matcher, opts));
|
||||
|
||||
if (testString == null) {
|
||||
return (testString, ri = false) => {
|
||||
const returnIndex = typeof ri === 'boolean' ? ri : false;
|
||||
return matchPatterns(patterns, negatedGlobs, testString, returnIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return matchPatterns(patterns, negatedGlobs, testString, returnIndex);
|
||||
};
|
||||
|
||||
anymatch.default = anymatch;
|
||||
module.exports = anymatch;
|
||||
48
labWeb/lab7/node_modules/anymatch/package.json
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "anymatch",
|
||||
"version": "3.1.3",
|
||||
"description": "Matches strings against configurable strings, globs, regular expressions, and/or functions",
|
||||
"files": [
|
||||
"index.js",
|
||||
"index.d.ts"
|
||||
],
|
||||
"dependencies": {
|
||||
"normalize-path": "^3.0.0",
|
||||
"picomatch": "^2.0.4"
|
||||
},
|
||||
"author": {
|
||||
"name": "Elan Shanker",
|
||||
"url": "https://github.com/es128"
|
||||
},
|
||||
"license": "ISC",
|
||||
"homepage": "https://github.com/micromatch/anymatch",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/micromatch/anymatch"
|
||||
},
|
||||
"keywords": [
|
||||
"match",
|
||||
"any",
|
||||
"string",
|
||||
"file",
|
||||
"fs",
|
||||
"list",
|
||||
"glob",
|
||||
"regex",
|
||||
"regexp",
|
||||
"regular",
|
||||
"expression",
|
||||
"function"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "nyc mocha",
|
||||
"mocha": "mocha"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "^6.1.3",
|
||||
"nyc": "^14.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
}
|
||||
21
labWeb/lab7/node_modules/array-flatten/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
43
labWeb/lab7/node_modules/array-flatten/README.md
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
# Array Flatten
|
||||
|
||||
[![NPM version][npm-image]][npm-url]
|
||||
[![NPM downloads][downloads-image]][downloads-url]
|
||||
[![Build status][travis-image]][travis-url]
|
||||
[![Test coverage][coveralls-image]][coveralls-url]
|
||||
|
||||
> Flatten an array of nested arrays into a single flat array. Accepts an optional depth.
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
npm install array-flatten --save
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
var flatten = require('array-flatten')
|
||||
|
||||
flatten([1, [2, [3, [4, [5], 6], 7], 8], 9])
|
||||
//=> [1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
|
||||
flatten([1, [2, [3, [4, [5], 6], 7], 8], 9], 2)
|
||||
//=> [1, 2, 3, [4, [5], 6], 7, 8, 9]
|
||||
|
||||
(function () {
|
||||
flatten(arguments) //=> [1, 2, 3]
|
||||
})(1, [2, 3])
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
[npm-image]: https://img.shields.io/npm/v/array-flatten.svg?style=flat
|
||||
[npm-url]: https://npmjs.org/package/array-flatten
|
||||
[downloads-image]: https://img.shields.io/npm/dm/array-flatten.svg?style=flat
|
||||
[downloads-url]: https://npmjs.org/package/array-flatten
|
||||
[travis-image]: https://img.shields.io/travis/blakeembrey/array-flatten.svg?style=flat
|
||||
[travis-url]: https://travis-ci.org/blakeembrey/array-flatten
|
||||
[coveralls-image]: https://img.shields.io/coveralls/blakeembrey/array-flatten.svg?style=flat
|
||||
[coveralls-url]: https://coveralls.io/r/blakeembrey/array-flatten?branch=master
|
||||
64
labWeb/lab7/node_modules/array-flatten/array-flatten.js
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Expose `arrayFlatten`.
|
||||
*/
|
||||
module.exports = arrayFlatten
|
||||
|
||||
/**
|
||||
* Recursive flatten function with depth.
|
||||
*
|
||||
* @param {Array} array
|
||||
* @param {Array} result
|
||||
* @param {Number} depth
|
||||
* @return {Array}
|
||||
*/
|
||||
function flattenWithDepth (array, result, depth) {
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
var value = array[i]
|
||||
|
||||
if (depth > 0 && Array.isArray(value)) {
|
||||
flattenWithDepth(value, result, depth - 1)
|
||||
} else {
|
||||
result.push(value)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive flatten function. Omitting depth is slightly faster.
|
||||
*
|
||||
* @param {Array} array
|
||||
* @param {Array} result
|
||||
* @return {Array}
|
||||
*/
|
||||
function flattenForever (array, result) {
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
var value = array[i]
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
flattenForever(value, result)
|
||||
} else {
|
||||
result.push(value)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten an array, with the ability to define a depth.
|
||||
*
|
||||
* @param {Array} array
|
||||
* @param {Number} depth
|
||||
* @return {Array}
|
||||
*/
|
||||
function arrayFlatten (array, depth) {
|
||||
if (depth == null) {
|
||||
return flattenForever(array, [])
|
||||
}
|
||||
|
||||
return flattenWithDepth(array, [], depth)
|
||||
}
|
||||
39
labWeb/lab7/node_modules/array-flatten/package.json
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "array-flatten",
|
||||
"version": "1.1.1",
|
||||
"description": "Flatten an array of nested arrays into a single flat array",
|
||||
"main": "array-flatten.js",
|
||||
"files": [
|
||||
"array-flatten.js",
|
||||
"LICENSE"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "istanbul cover _mocha -- -R spec"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/blakeembrey/array-flatten.git"
|
||||
},
|
||||
"keywords": [
|
||||
"array",
|
||||
"flatten",
|
||||
"arguments",
|
||||
"depth"
|
||||
],
|
||||
"author": {
|
||||
"name": "Blake Embrey",
|
||||
"email": "hello@blakeembrey.com",
|
||||
"url": "http://blakeembrey.me"
|
||||
},
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/blakeembrey/array-flatten/issues"
|
||||
},
|
||||
"homepage": "https://github.com/blakeembrey/array-flatten",
|
||||
"devDependencies": {
|
||||
"istanbul": "^0.3.13",
|
||||
"mocha": "^2.2.4",
|
||||
"pre-commit": "^1.0.7",
|
||||
"standard": "^3.7.3"
|
||||
}
|
||||
}
|
||||
23
labWeb/lab7/node_modules/balanced-match/LICENSE.md
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
(MIT)
|
||||
|
||||
Original code Copyright Julian Gruber <julian@juliangruber.com>
|
||||
|
||||
Port to TypeScript Copyright Isaac Z. Schlueter <i@izs.me>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
57
labWeb/lab7/node_modules/balanced-match/README.md
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
# balanced-match
|
||||
|
||||
Match balanced string pairs, like `{` and `}` or `<b>` and
|
||||
`</b>`. Supports regular expressions as well!
|
||||
|
||||
## Example
|
||||
|
||||
Get the first matching pair of braces:
|
||||
|
||||
```js
|
||||
import { balanced } from 'balanced-match'
|
||||
|
||||
console.log(balanced('{', '}', 'pre{in{nested}}post'))
|
||||
console.log(balanced('{', '}', 'pre{first}between{second}post'))
|
||||
console.log(
|
||||
balanced(/\s+\{\s+/, /\s+\}\s+/, 'pre { in{nest} } post'),
|
||||
)
|
||||
```
|
||||
|
||||
The matches are:
|
||||
|
||||
```bash
|
||||
$ node example.js
|
||||
{ start: 3, end: 14, pre: 'pre', body: 'in{nested}', post: 'post' }
|
||||
{ start: 3,
|
||||
end: 9,
|
||||
pre: 'pre',
|
||||
body: 'first',
|
||||
post: 'between{second}post' }
|
||||
{ start: 3, end: 17, pre: 'pre', body: 'in{nest}', post: 'post' }
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### const m = balanced(a, b, str)
|
||||
|
||||
For the first non-nested matching pair of `a` and `b` in `str`, return an
|
||||
object with those keys:
|
||||
|
||||
- **start** the index of the first match of `a`
|
||||
- **end** the index of the matching `b`
|
||||
- **pre** the preamble, `a` and `b` not included
|
||||
- **body** the match, `a` and `b` not included
|
||||
- **post** the postscript, `a` and `b` not included
|
||||
|
||||
If there's no match, `undefined` will be returned.
|
||||
|
||||
If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `['{', 'a', '']` and `{a}}` will match `['', 'a', '}']`.
|
||||
|
||||
### const r = balanced.range(a, b, str)
|
||||
|
||||
For the first non-nested matching pair of `a` and `b` in `str`, return an
|
||||
array with indexes: `[ <a index>, <b index> ]`.
|
||||
|
||||
If there's no match, `undefined` will be returned.
|
||||
|
||||
If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `[ 1, 3 ]` and `{a}}` will match `[0, 2]`.
|
||||
9
labWeb/lab7/node_modules/balanced-match/dist/commonjs/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
export declare const balanced: (a: string | RegExp, b: string | RegExp, str: string) => false | {
|
||||
start: number;
|
||||
end: number;
|
||||
pre: string;
|
||||
body: string;
|
||||
post: string;
|
||||
} | undefined;
|
||||
export declare const range: (a: string, b: string, str: string) => undefined | [number, number];
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
1
labWeb/lab7/node_modules/balanced-match/dist/commonjs/index.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ,GACnB,GAAG,MAAM,GAAG,MAAM,EAClB,GAAG,MAAM,GAAG,MAAM,EAClB,KAAK,MAAM;;;;;;aAgBZ,CAAA;AAOD,eAAO,MAAM,KAAK,GAChB,GAAG,MAAM,EACT,GAAG,MAAM,EACT,KAAK,MAAM,KACV,SAAS,GAAG,CAAC,MAAM,EAAE,MAAM,CA2C7B,CAAA"}
|
||||
59
labWeb/lab7/node_modules/balanced-match/dist/commonjs/index.js
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.range = exports.balanced = void 0;
|
||||
const balanced = (a, b, str) => {
|
||||
const ma = a instanceof RegExp ? maybeMatch(a, str) : a;
|
||||
const mb = b instanceof RegExp ? maybeMatch(b, str) : b;
|
||||
const r = ma !== null && mb != null && (0, exports.range)(ma, mb, str);
|
||||
return (r && {
|
||||
start: r[0],
|
||||
end: r[1],
|
||||
pre: str.slice(0, r[0]),
|
||||
body: str.slice(r[0] + ma.length, r[1]),
|
||||
post: str.slice(r[1] + mb.length),
|
||||
});
|
||||
};
|
||||
exports.balanced = balanced;
|
||||
const maybeMatch = (reg, str) => {
|
||||
const m = str.match(reg);
|
||||
return m ? m[0] : null;
|
||||
};
|
||||
const range = (a, b, str) => {
|
||||
let begs, beg, left, right = undefined, result;
|
||||
let ai = str.indexOf(a);
|
||||
let bi = str.indexOf(b, ai + 1);
|
||||
let i = ai;
|
||||
if (ai >= 0 && bi > 0) {
|
||||
if (a === b) {
|
||||
return [ai, bi];
|
||||
}
|
||||
begs = [];
|
||||
left = str.length;
|
||||
while (i >= 0 && !result) {
|
||||
if (i === ai) {
|
||||
begs.push(i);
|
||||
ai = str.indexOf(a, i + 1);
|
||||
}
|
||||
else if (begs.length === 1) {
|
||||
const r = begs.pop();
|
||||
if (r !== undefined)
|
||||
result = [r, bi];
|
||||
}
|
||||
else {
|
||||
beg = begs.pop();
|
||||
if (beg !== undefined && beg < left) {
|
||||
left = beg;
|
||||
right = bi;
|
||||
}
|
||||
bi = str.indexOf(b, i + 1);
|
||||
}
|
||||
i = ai < bi && ai >= 0 ? ai : bi;
|
||||
}
|
||||
if (begs.length && right !== undefined) {
|
||||
result = [left, right];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
exports.range = range;
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
labWeb/lab7/node_modules/balanced-match/dist/commonjs/index.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAO,MAAM,QAAQ,GAAG,CACtB,CAAkB,EAClB,CAAkB,EAClB,GAAW,EACX,EAAE;IACF,MAAM,EAAE,GAAG,CAAC,YAAY,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACvD,MAAM,EAAE,GAAG,CAAC,YAAY,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAEvD,MAAM,CAAC,GAAG,EAAE,KAAK,IAAI,IAAI,EAAE,IAAI,IAAI,IAAI,IAAA,aAAK,EAAC,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAA;IAEzD,OAAO,CACL,CAAC,IAAI;QACH,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;QACX,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;QACT,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACvB,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACvC,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC;KAClC,CACF,CAAA;AACH,CAAC,CAAA;AAnBY,QAAA,QAAQ,YAmBpB;AAED,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,GAAW,EAAE,EAAE;IAC9C,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACxB,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AACxB,CAAC,CAAA;AAEM,MAAM,KAAK,GAAG,CACnB,CAAS,EACT,CAAS,EACT,GAAW,EACmB,EAAE;IAChC,IAAI,IAAc,EAChB,GAAuB,EACvB,IAAY,EACZ,KAAK,GAAuB,SAAS,EACrC,MAAoC,CAAA;IACtC,IAAI,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IACvB,IAAI,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAA;IAC/B,IAAI,CAAC,GAAG,EAAE,CAAA;IAEV,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;QACtB,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACZ,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;QACjB,CAAC;QACD,IAAI,GAAG,EAAE,CAAA;QACT,IAAI,GAAG,GAAG,CAAC,MAAM,CAAA;QAEjB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACzB,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;gBACb,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;gBACZ,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;YAC5B,CAAC;iBAAM,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC7B,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;gBACpB,IAAI,CAAC,KAAK,SAAS;oBAAE,MAAM,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;YACvC,CAAC;iBAAM,CAAC;gBACN,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;gBAChB,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,GAAG,IAAI,EAAE,CAAC;oBACpC,IAAI,GAAG,GAAG,CAAA;oBACV,KAAK,GAAG,EAAE,CAAA;gBACZ,CAAC;gBAED,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;YAC5B,CAAC;YAED,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QAClC,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACvC,MAAM,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;QACxB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AA/CY,QAAA,KAAK,SA+CjB","sourcesContent":["export const balanced = (\n a: string | RegExp,\n b: string | RegExp,\n str: string,\n) => {\n const ma = a instanceof RegExp ? maybeMatch(a, str) : a\n const mb = b instanceof RegExp ? maybeMatch(b, str) : b\n\n const r = ma !== null && mb != null && range(ma, mb, str)\n\n return (\n r && {\n start: r[0],\n end: r[1],\n pre: str.slice(0, r[0]),\n body: str.slice(r[0] + ma.length, r[1]),\n post: str.slice(r[1] + mb.length),\n }\n )\n}\n\nconst maybeMatch = (reg: RegExp, str: string) => {\n const m = str.match(reg)\n return m ? m[0] : null\n}\n\nexport const range = (\n a: string,\n b: string,\n str: string,\n): undefined | [number, number] => {\n let begs: number[],\n beg: number | undefined,\n left: number,\n right: number | undefined = undefined,\n result: undefined | [number, number]\n let ai = str.indexOf(a)\n let bi = str.indexOf(b, ai + 1)\n let i = ai\n\n if (ai >= 0 && bi > 0) {\n if (a === b) {\n return [ai, bi]\n }\n begs = []\n left = str.length\n\n while (i >= 0 && !result) {\n if (i === ai) {\n begs.push(i)\n ai = str.indexOf(a, i + 1)\n } else if (begs.length === 1) {\n const r = begs.pop()\n if (r !== undefined) result = [r, bi]\n } else {\n beg = begs.pop()\n if (beg !== undefined && beg < left) {\n left = beg\n right = bi\n }\n\n bi = str.indexOf(b, i + 1)\n }\n\n i = ai < bi && ai >= 0 ? ai : bi\n }\n\n if (begs.length && right !== undefined) {\n result = [left, right]\n }\n }\n\n return result\n}\n"]}
|
||||
3
labWeb/lab7/node_modules/balanced-match/dist/commonjs/package.json
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "commonjs"
|
||||
}
|
||||
9
labWeb/lab7/node_modules/balanced-match/dist/esm/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
export declare const balanced: (a: string | RegExp, b: string | RegExp, str: string) => false | {
|
||||
start: number;
|
||||
end: number;
|
||||
pre: string;
|
||||
body: string;
|
||||
post: string;
|
||||
} | undefined;
|
||||
export declare const range: (a: string, b: string, str: string) => undefined | [number, number];
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
1
labWeb/lab7/node_modules/balanced-match/dist/esm/index.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ,GACnB,GAAG,MAAM,GAAG,MAAM,EAClB,GAAG,MAAM,GAAG,MAAM,EAClB,KAAK,MAAM;;;;;;aAgBZ,CAAA;AAOD,eAAO,MAAM,KAAK,GAChB,GAAG,MAAM,EACT,GAAG,MAAM,EACT,KAAK,MAAM,KACV,SAAS,GAAG,CAAC,MAAM,EAAE,MAAM,CA2C7B,CAAA"}
|
||||
54
labWeb/lab7/node_modules/balanced-match/dist/esm/index.js
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
export const balanced = (a, b, str) => {
|
||||
const ma = a instanceof RegExp ? maybeMatch(a, str) : a;
|
||||
const mb = b instanceof RegExp ? maybeMatch(b, str) : b;
|
||||
const r = ma !== null && mb != null && range(ma, mb, str);
|
||||
return (r && {
|
||||
start: r[0],
|
||||
end: r[1],
|
||||
pre: str.slice(0, r[0]),
|
||||
body: str.slice(r[0] + ma.length, r[1]),
|
||||
post: str.slice(r[1] + mb.length),
|
||||
});
|
||||
};
|
||||
const maybeMatch = (reg, str) => {
|
||||
const m = str.match(reg);
|
||||
return m ? m[0] : null;
|
||||
};
|
||||
export const range = (a, b, str) => {
|
||||
let begs, beg, left, right = undefined, result;
|
||||
let ai = str.indexOf(a);
|
||||
let bi = str.indexOf(b, ai + 1);
|
||||
let i = ai;
|
||||
if (ai >= 0 && bi > 0) {
|
||||
if (a === b) {
|
||||
return [ai, bi];
|
||||
}
|
||||
begs = [];
|
||||
left = str.length;
|
||||
while (i >= 0 && !result) {
|
||||
if (i === ai) {
|
||||
begs.push(i);
|
||||
ai = str.indexOf(a, i + 1);
|
||||
}
|
||||
else if (begs.length === 1) {
|
||||
const r = begs.pop();
|
||||
if (r !== undefined)
|
||||
result = [r, bi];
|
||||
}
|
||||
else {
|
||||
beg = begs.pop();
|
||||
if (beg !== undefined && beg < left) {
|
||||
left = beg;
|
||||
right = bi;
|
||||
}
|
||||
bi = str.indexOf(b, i + 1);
|
||||
}
|
||||
i = ai < bi && ai >= 0 ? ai : bi;
|
||||
}
|
||||
if (begs.length && right !== undefined) {
|
||||
result = [left, right];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
labWeb/lab7/node_modules/balanced-match/dist/esm/index.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG,CACtB,CAAkB,EAClB,CAAkB,EAClB,GAAW,EACX,EAAE;IACF,MAAM,EAAE,GAAG,CAAC,YAAY,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACvD,MAAM,EAAE,GAAG,CAAC,YAAY,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAEvD,MAAM,CAAC,GAAG,EAAE,KAAK,IAAI,IAAI,EAAE,IAAI,IAAI,IAAI,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAA;IAEzD,OAAO,CACL,CAAC,IAAI;QACH,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;QACX,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;QACT,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACvB,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACvC,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC;KAClC,CACF,CAAA;AACH,CAAC,CAAA;AAED,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,GAAW,EAAE,EAAE;IAC9C,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACxB,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AACxB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,KAAK,GAAG,CACnB,CAAS,EACT,CAAS,EACT,GAAW,EACmB,EAAE;IAChC,IAAI,IAAc,EAChB,GAAuB,EACvB,IAAY,EACZ,KAAK,GAAuB,SAAS,EACrC,MAAoC,CAAA;IACtC,IAAI,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IACvB,IAAI,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAA;IAC/B,IAAI,CAAC,GAAG,EAAE,CAAA;IAEV,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;QACtB,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACZ,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;QACjB,CAAC;QACD,IAAI,GAAG,EAAE,CAAA;QACT,IAAI,GAAG,GAAG,CAAC,MAAM,CAAA;QAEjB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACzB,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;gBACb,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;gBACZ,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;YAC5B,CAAC;iBAAM,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC7B,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;gBACpB,IAAI,CAAC,KAAK,SAAS;oBAAE,MAAM,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;YACvC,CAAC;iBAAM,CAAC;gBACN,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;gBAChB,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,GAAG,IAAI,EAAE,CAAC;oBACpC,IAAI,GAAG,GAAG,CAAA;oBACV,KAAK,GAAG,EAAE,CAAA;gBACZ,CAAC;gBAED,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;YAC5B,CAAC;YAED,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QAClC,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACvC,MAAM,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;QACxB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC,CAAA","sourcesContent":["export const balanced = (\n a: string | RegExp,\n b: string | RegExp,\n str: string,\n) => {\n const ma = a instanceof RegExp ? maybeMatch(a, str) : a\n const mb = b instanceof RegExp ? maybeMatch(b, str) : b\n\n const r = ma !== null && mb != null && range(ma, mb, str)\n\n return (\n r && {\n start: r[0],\n end: r[1],\n pre: str.slice(0, r[0]),\n body: str.slice(r[0] + ma.length, r[1]),\n post: str.slice(r[1] + mb.length),\n }\n )\n}\n\nconst maybeMatch = (reg: RegExp, str: string) => {\n const m = str.match(reg)\n return m ? m[0] : null\n}\n\nexport const range = (\n a: string,\n b: string,\n str: string,\n): undefined | [number, number] => {\n let begs: number[],\n beg: number | undefined,\n left: number,\n right: number | undefined = undefined,\n result: undefined | [number, number]\n let ai = str.indexOf(a)\n let bi = str.indexOf(b, ai + 1)\n let i = ai\n\n if (ai >= 0 && bi > 0) {\n if (a === b) {\n return [ai, bi]\n }\n begs = []\n left = str.length\n\n while (i >= 0 && !result) {\n if (i === ai) {\n begs.push(i)\n ai = str.indexOf(a, i + 1)\n } else if (begs.length === 1) {\n const r = begs.pop()\n if (r !== undefined) result = [r, bi]\n } else {\n beg = begs.pop()\n if (beg !== undefined && beg < left) {\n left = beg\n right = bi\n }\n\n bi = str.indexOf(b, i + 1)\n }\n\n i = ai < bi && ai >= 0 ? ai : bi\n }\n\n if (begs.length && right !== undefined) {\n result = [left, right]\n }\n }\n\n return result\n}\n"]}
|
||||
3
labWeb/lab7/node_modules/balanced-match/dist/esm/package.json
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
||||