webscout 7.0__py3-none-any.whl → 7.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of webscout might be problematic. Click here for more details.
- webscout/LLM.py +1 -1
- webscout/Provider/Blackboxai.py +136 -137
- webscout/Provider/Cloudflare.py +92 -78
- webscout/Provider/Deepinfra.py +59 -35
- webscout/Provider/Glider.py +74 -59
- webscout/Provider/Groq.py +26 -18
- webscout/Provider/Jadve.py +108 -77
- webscout/Provider/Llama3.py +117 -94
- webscout/Provider/Marcus.py +65 -10
- webscout/Provider/Netwrck.py +61 -49
- webscout/Provider/PI.py +77 -122
- webscout/Provider/PizzaGPT.py +129 -82
- webscout/Provider/TextPollinationsAI.py +75 -47
- webscout/Provider/__init__.py +1 -3
- webscout/Provider/dgaf.py +68 -39
- webscout/Provider/gaurish.py +106 -66
- webscout/Provider/llamatutor.py +72 -62
- webscout/Provider/llmchat.py +61 -35
- webscout/Provider/meta.py +6 -6
- webscout/Provider/multichat.py +205 -104
- webscout/Provider/typegpt.py +26 -23
- webscout/Provider/yep.py +3 -3
- webscout/version.py +1 -1
- webscout/webscout_search.py +1141 -1140
- webscout/webscout_search_async.py +635 -635
- {webscout-7.0.dist-info → webscout-7.1.dist-info}/METADATA +18 -26
- {webscout-7.0.dist-info → webscout-7.1.dist-info}/RECORD +31 -32
- webscout/Provider/RUBIKSAI.py +0 -272
- {webscout-7.0.dist-info → webscout-7.1.dist-info}/LICENSE.md +0 -0
- {webscout-7.0.dist-info → webscout-7.1.dist-info}/WHEEL +0 -0
- {webscout-7.0.dist-info → webscout-7.1.dist-info}/entry_points.txt +0 -0
- {webscout-7.0.dist-info → webscout-7.1.dist-info}/top_level.txt +0 -0
webscout/Provider/Marcus.py
CHANGED
|
@@ -7,18 +7,19 @@ from webscout.AIutel import Conversation
|
|
|
7
7
|
from webscout.AIutel import AwesomePrompts
|
|
8
8
|
from webscout.AIbase import Provider
|
|
9
9
|
from webscout import exceptions
|
|
10
|
+
from webscout.Litlogger import LitLogger, LogFormat, ColorScheme
|
|
10
11
|
from webscout import LitAgent as Lit
|
|
11
12
|
|
|
12
13
|
class Marcus(Provider):
|
|
13
14
|
"""
|
|
14
15
|
This class provides methods for interacting with the AskMarcus API.
|
|
15
|
-
Improved to match webscout provider standards.
|
|
16
|
+
Improved to match webscout provider standards with comprehensive logging.
|
|
16
17
|
"""
|
|
17
18
|
|
|
18
19
|
def __init__(
|
|
19
20
|
self,
|
|
20
21
|
is_conversation: bool = True,
|
|
21
|
-
max_tokens: int = 2048,
|
|
22
|
+
max_tokens: int = 2048,
|
|
22
23
|
timeout: int = 30,
|
|
23
24
|
intro: str = None,
|
|
24
25
|
filepath: str = None,
|
|
@@ -26,14 +27,25 @@ class Marcus(Provider):
|
|
|
26
27
|
proxies: dict = {},
|
|
27
28
|
history_offset: int = 10250,
|
|
28
29
|
act: str = None,
|
|
30
|
+
logging: bool = False
|
|
29
31
|
):
|
|
30
|
-
"""Initializes the Marcus API."""
|
|
32
|
+
"""Initializes the Marcus API with logging capabilities."""
|
|
33
|
+
self.logger = LitLogger(
|
|
34
|
+
name="Marcus",
|
|
35
|
+
format=LogFormat.MODERN_EMOJI,
|
|
36
|
+
color_scheme=ColorScheme.CYBERPUNK
|
|
37
|
+
) if logging else None
|
|
38
|
+
|
|
39
|
+
if self.logger:
|
|
40
|
+
self.logger.info("Initializing Marcus API")
|
|
41
|
+
|
|
31
42
|
self.session = requests.Session()
|
|
32
43
|
self.is_conversation = is_conversation
|
|
33
44
|
self.max_tokens_to_sample = max_tokens
|
|
34
45
|
self.api_endpoint = "https://www.askmarcus.app/api/response"
|
|
35
46
|
self.timeout = timeout
|
|
36
47
|
self.last_response = {}
|
|
48
|
+
|
|
37
49
|
self.headers = {
|
|
38
50
|
'content-type': 'application/json',
|
|
39
51
|
'accept': '*/*',
|
|
@@ -41,11 +53,13 @@ class Marcus(Provider):
|
|
|
41
53
|
'referer': 'https://www.askmarcus.app/chat',
|
|
42
54
|
'user-agent': Lit().random(),
|
|
43
55
|
}
|
|
56
|
+
|
|
44
57
|
self.__available_optimizers = (
|
|
45
58
|
method
|
|
46
59
|
for method in dir(Optimizers)
|
|
47
60
|
if callable(getattr(Optimizers, method)) and not method.startswith("__")
|
|
48
61
|
)
|
|
62
|
+
|
|
49
63
|
Conversation.intro = (
|
|
50
64
|
AwesomePrompts().get_act(
|
|
51
65
|
act, raise_not_found=True, default=None, case_insensitive=True
|
|
@@ -53,12 +67,16 @@ class Marcus(Provider):
|
|
|
53
67
|
if act
|
|
54
68
|
else intro or Conversation.intro
|
|
55
69
|
)
|
|
70
|
+
|
|
56
71
|
self.conversation = Conversation(
|
|
57
72
|
is_conversation, self.max_tokens_to_sample, filepath, update_file
|
|
58
73
|
)
|
|
59
74
|
self.conversation.history_offset = history_offset
|
|
60
75
|
self.session.proxies = proxies
|
|
61
76
|
|
|
77
|
+
if self.logger:
|
|
78
|
+
self.logger.info("Marcus API initialized successfully")
|
|
79
|
+
|
|
62
80
|
def ask(
|
|
63
81
|
self,
|
|
64
82
|
prompt: str,
|
|
@@ -67,14 +85,22 @@ class Marcus(Provider):
|
|
|
67
85
|
optimizer: str = None,
|
|
68
86
|
conversationally: bool = False,
|
|
69
87
|
) -> Dict[str, Any] | Generator[str, None, None]:
|
|
70
|
-
"""Sends a prompt to the AskMarcus API and returns the response."""
|
|
88
|
+
"""Sends a prompt to the AskMarcus API and returns the response with logging."""
|
|
89
|
+
if self.logger:
|
|
90
|
+
self.logger.debug(f"Processing request - Prompt: {prompt[:50]}...")
|
|
91
|
+
self.logger.debug(f"Stream: {stream}, Optimizer: {optimizer}")
|
|
92
|
+
|
|
71
93
|
conversation_prompt = self.conversation.gen_complete_prompt(prompt)
|
|
72
94
|
if optimizer:
|
|
73
95
|
if optimizer in self.__available_optimizers:
|
|
74
96
|
conversation_prompt = getattr(Optimizers, optimizer)(
|
|
75
97
|
conversation_prompt if conversationally else prompt
|
|
76
98
|
)
|
|
99
|
+
if self.logger:
|
|
100
|
+
self.logger.debug(f"Applied optimizer: {optimizer}")
|
|
77
101
|
else:
|
|
102
|
+
if self.logger:
|
|
103
|
+
self.logger.error(f"Invalid optimizer requested: {optimizer}")
|
|
78
104
|
raise exceptions.FailedToGenerateResponseError(
|
|
79
105
|
f"Optimizer is not one of {self.__available_optimizers}"
|
|
80
106
|
)
|
|
@@ -83,21 +109,46 @@ class Marcus(Provider):
|
|
|
83
109
|
|
|
84
110
|
def for_stream():
|
|
85
111
|
try:
|
|
86
|
-
|
|
112
|
+
if self.logger:
|
|
113
|
+
self.logger.debug("Initiating streaming request to API")
|
|
114
|
+
|
|
115
|
+
with requests.post(
|
|
116
|
+
self.api_endpoint,
|
|
117
|
+
headers=self.headers,
|
|
118
|
+
json=data,
|
|
119
|
+
stream=True,
|
|
120
|
+
timeout=self.timeout
|
|
121
|
+
) as response:
|
|
87
122
|
response.raise_for_status()
|
|
123
|
+
|
|
124
|
+
if self.logger:
|
|
125
|
+
self.logger.info(f"API connection established successfully. Status: {response.status_code}")
|
|
126
|
+
|
|
88
127
|
for line in response.iter_lines():
|
|
89
128
|
if line:
|
|
90
129
|
yield line.decode('utf-8')
|
|
91
|
-
|
|
130
|
+
|
|
131
|
+
self.conversation.update_chat_history(
|
|
132
|
+
prompt, self.get_message(self.last_response)
|
|
133
|
+
)
|
|
92
134
|
|
|
93
135
|
except requests.exceptions.RequestException as e:
|
|
136
|
+
if self.logger:
|
|
137
|
+
self.logger.error(f"API request failed: {str(e)}")
|
|
94
138
|
raise exceptions.ProviderConnectionError(f"Error connecting to Marcus: {str(e)}")
|
|
95
139
|
|
|
96
140
|
def for_non_stream():
|
|
141
|
+
if self.logger:
|
|
142
|
+
self.logger.debug("Processing non-streaming request")
|
|
143
|
+
|
|
97
144
|
full_response = ""
|
|
98
145
|
for line in for_stream():
|
|
99
146
|
full_response += line
|
|
100
147
|
self.last_response = {"text": full_response}
|
|
148
|
+
|
|
149
|
+
if self.logger:
|
|
150
|
+
self.logger.debug("Response processing completed")
|
|
151
|
+
|
|
101
152
|
return self.last_response
|
|
102
153
|
|
|
103
154
|
return for_stream() if stream else for_non_stream()
|
|
@@ -109,7 +160,9 @@ class Marcus(Provider):
|
|
|
109
160
|
optimizer: str = None,
|
|
110
161
|
conversationally: bool = False,
|
|
111
162
|
) -> str | Generator[str, None, None]:
|
|
112
|
-
"""Generates a response from the AskMarcus API."""
|
|
163
|
+
"""Generates a response from the AskMarcus API with logging."""
|
|
164
|
+
if self.logger:
|
|
165
|
+
self.logger.debug(f"Chat request initiated - Prompt: {prompt[:50]}...")
|
|
113
166
|
|
|
114
167
|
def for_stream():
|
|
115
168
|
for response_chunk in self.ask(
|
|
@@ -130,8 +183,10 @@ class Marcus(Provider):
|
|
|
130
183
|
assert isinstance(response, dict), "Response should be of dict data-type only"
|
|
131
184
|
return response.get("text", "")
|
|
132
185
|
|
|
133
|
-
if __name__ ==
|
|
134
|
-
|
|
135
|
-
|
|
186
|
+
if __name__ == "__main__":
|
|
187
|
+
from rich import print
|
|
188
|
+
# Enable logging for testing
|
|
189
|
+
ai = Marcus(logging=True)
|
|
190
|
+
response = ai.chat(input(">>> "), stream=True)
|
|
136
191
|
for chunk in response:
|
|
137
192
|
print(chunk, end="", flush=True)
|
webscout/Provider/Netwrck.py
CHANGED
|
@@ -2,41 +2,39 @@ import time
|
|
|
2
2
|
import uuid
|
|
3
3
|
import requests
|
|
4
4
|
import json
|
|
5
|
-
|
|
6
5
|
from typing import Any, Dict, Optional, Generator, Union
|
|
7
6
|
from dataclasses import dataclass, asdict
|
|
8
7
|
from datetime import date
|
|
9
|
-
|
|
10
8
|
from webscout.AIutel import Optimizers, Conversation, AwesomePrompts
|
|
11
9
|
from webscout.AIbase import Provider
|
|
12
10
|
from webscout import exceptions
|
|
13
11
|
from webscout.Litlogger import LitLogger, LogFormat, ColorScheme
|
|
14
12
|
from webscout.litagent import LitAgent
|
|
15
13
|
|
|
16
|
-
|
|
17
14
|
class Netwrck(Provider):
|
|
18
15
|
"""
|
|
19
16
|
A class to interact with the Netwrck.com API. Supports streaming.
|
|
20
17
|
"""
|
|
21
|
-
greeting = """
|
|
18
|
+
greeting = """Hello! I'm a helpful assistant. How can I help you today?"""
|
|
22
19
|
|
|
23
20
|
AVAILABLE_MODELS = {
|
|
24
|
-
"lumimaid": "neversleep/llama-3
|
|
21
|
+
"lumimaid": "neversleep/llama-3-lumimaid-8b:extended",
|
|
25
22
|
"grok": "x-ai/grok-2",
|
|
26
23
|
"claude": "anthropic/claude-3.5-sonnet:beta",
|
|
27
24
|
"euryale": "sao10k/l3-euryale-70b",
|
|
28
25
|
"gpt4mini": "openai/gpt-4o-mini",
|
|
29
26
|
"mythomax": "gryphe/mythomax-l2-13b",
|
|
30
27
|
"gemini": "google/gemini-pro-1.5",
|
|
31
|
-
"lumimaid70b": "neversleep/llama-3.1-lumimaid-70b",
|
|
32
28
|
"nemotron": "nvidia/llama-3.1-nemotron-70b-instruct",
|
|
29
|
+
"deepseek-r1": "deepseek/deepseek-r1",
|
|
30
|
+
"deepseek": "deepseek/deepseek-chat",
|
|
33
31
|
}
|
|
34
32
|
|
|
35
33
|
def __init__(
|
|
36
34
|
self,
|
|
37
35
|
model: str = "claude",
|
|
38
36
|
is_conversation: bool = True,
|
|
39
|
-
max_tokens: int =
|
|
37
|
+
max_tokens: int = 4096,
|
|
40
38
|
timeout: int = 30,
|
|
41
39
|
intro: Optional[str] = None,
|
|
42
40
|
filepath: Optional[str] = None,
|
|
@@ -50,8 +48,18 @@ class Netwrck(Provider):
|
|
|
50
48
|
logging: bool = False
|
|
51
49
|
):
|
|
52
50
|
"""Initializes the Netwrck API client."""
|
|
51
|
+
# Initialize logger first for initialization logging
|
|
52
|
+
self.logger = LitLogger(
|
|
53
|
+
name="Netwrck",
|
|
54
|
+
format=LogFormat.MODERN_EMOJI,
|
|
55
|
+
color_scheme=ColorScheme.CYBERPUNK
|
|
56
|
+
) if logging else None
|
|
57
|
+
|
|
53
58
|
if model not in self.AVAILABLE_MODELS:
|
|
54
|
-
|
|
59
|
+
error_msg = f"Invalid model: {model}. Choose from: {list(self.AVAILABLE_MODELS.keys())}"
|
|
60
|
+
if self.logger:
|
|
61
|
+
self.logger.error(error_msg)
|
|
62
|
+
raise ValueError(error_msg)
|
|
55
63
|
|
|
56
64
|
self.model = model
|
|
57
65
|
self.model_name = self.AVAILABLE_MODELS[model]
|
|
@@ -64,9 +72,7 @@ class Netwrck(Provider):
|
|
|
64
72
|
self.temperature = temperature
|
|
65
73
|
self.top_p = top_p
|
|
66
74
|
|
|
67
|
-
# Initialize LitAgent for user agent generation
|
|
68
75
|
self.agent = LitAgent()
|
|
69
|
-
|
|
70
76
|
self.headers = {
|
|
71
77
|
'authority': 'netwrck.com',
|
|
72
78
|
'accept': '*/*',
|
|
@@ -76,6 +82,7 @@ class Netwrck(Provider):
|
|
|
76
82
|
'referer': 'https://netwrck.com/',
|
|
77
83
|
'user-agent': self.agent.random()
|
|
78
84
|
}
|
|
85
|
+
|
|
79
86
|
self.session.headers.update(self.headers)
|
|
80
87
|
self.proxies = proxies or {}
|
|
81
88
|
|
|
@@ -84,16 +91,16 @@ class Netwrck(Provider):
|
|
|
84
91
|
if act
|
|
85
92
|
else intro or Conversation.intro
|
|
86
93
|
)
|
|
94
|
+
|
|
87
95
|
self.conversation = Conversation(is_conversation, max_tokens, filepath, update_file)
|
|
88
96
|
self.conversation.history_offset = history_offset
|
|
89
97
|
self.__available_optimizers = (
|
|
90
|
-
method
|
|
91
|
-
for method in dir(Optimizers)
|
|
98
|
+
method for method in dir(Optimizers)
|
|
92
99
|
if callable(getattr(Optimizers, method)) and not method.startswith("__")
|
|
93
100
|
)
|
|
94
101
|
|
|
95
|
-
|
|
96
|
-
|
|
102
|
+
if self.logger:
|
|
103
|
+
self.logger.info(f"Initialized Netwrck with model: {self.model_name}")
|
|
97
104
|
|
|
98
105
|
def ask(
|
|
99
106
|
self,
|
|
@@ -104,22 +111,20 @@ class Netwrck(Provider):
|
|
|
104
111
|
conversationally: bool = False,
|
|
105
112
|
) -> Union[Dict[str, Any], Generator]:
|
|
106
113
|
"""Sends a prompt to the Netwrck API and returns the response."""
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
114
|
+
if optimizer and optimizer not in self.__available_optimizers:
|
|
115
|
+
error_msg = f"Optimizer is not one of {self.__available_optimizers}"
|
|
116
|
+
if self.logger:
|
|
117
|
+
self.logger.error(f"Invalid optimizer requested: {optimizer}")
|
|
118
|
+
raise exceptions.FailedToGenerateResponseError(error_msg)
|
|
110
119
|
|
|
111
120
|
conversation_prompt = self.conversation.gen_complete_prompt(prompt)
|
|
112
121
|
if optimizer:
|
|
113
|
-
|
|
114
|
-
conversation_prompt
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
self.logger.error(f"Invalid optimizer: {optimizer}")
|
|
120
|
-
raise exceptions.FailedToGenerateResponseError(
|
|
121
|
-
f"Optimizer is not one of {self.__available_optimizers}"
|
|
122
|
-
)
|
|
122
|
+
conversation_prompt = getattr(Optimizers, optimizer)(
|
|
123
|
+
conversation_prompt if conversationally else prompt
|
|
124
|
+
)
|
|
125
|
+
if self.logger:
|
|
126
|
+
self.logger.debug(f"Applied optimizer: {optimizer}")
|
|
127
|
+
|
|
123
128
|
payload = {
|
|
124
129
|
"query": prompt,
|
|
125
130
|
"context": self.system_prompt,
|
|
@@ -128,6 +133,9 @@ class Netwrck(Provider):
|
|
|
128
133
|
"greeting": self.greeting
|
|
129
134
|
}
|
|
130
135
|
|
|
136
|
+
if self.logger:
|
|
137
|
+
self.logger.debug(f"Sending request to Netwrck API [stream={stream}]")
|
|
138
|
+
|
|
131
139
|
def for_stream():
|
|
132
140
|
try:
|
|
133
141
|
response = self.session.post(
|
|
@@ -140,26 +148,23 @@ class Netwrck(Provider):
|
|
|
140
148
|
)
|
|
141
149
|
response.raise_for_status()
|
|
142
150
|
|
|
143
|
-
# Initialize an empty string to accumulate the streaming text
|
|
144
151
|
streaming_text = ""
|
|
145
152
|
for line in response.iter_lines():
|
|
146
153
|
if line:
|
|
147
154
|
decoded_line = line.decode('utf-8').strip('"')
|
|
148
|
-
streaming_text += decoded_line
|
|
149
|
-
yield {"text": decoded_line}
|
|
155
|
+
streaming_text += decoded_line
|
|
156
|
+
yield {"text": decoded_line}
|
|
150
157
|
|
|
151
|
-
# Optionally, you can update the conversation history with the full streaming text
|
|
152
158
|
self.conversation.update_chat_history(payload["query"], streaming_text)
|
|
153
159
|
|
|
154
|
-
except
|
|
160
|
+
except requests.exceptions.RequestException as e:
|
|
155
161
|
if self.logger:
|
|
156
|
-
self.logger.error(f"
|
|
157
|
-
raise exceptions.ProviderConnectionError(f"
|
|
158
|
-
|
|
162
|
+
self.logger.error(f"Network error: {str(e)}")
|
|
163
|
+
raise exceptions.ProviderConnectionError(f"Network error: {str(e)}") from e
|
|
159
164
|
except Exception as e:
|
|
160
165
|
if self.logger:
|
|
161
|
-
self.logger.error(f"
|
|
162
|
-
raise exceptions.ProviderConnectionError(f"
|
|
166
|
+
self.logger.error(f"Unexpected error: {str(e)}")
|
|
167
|
+
raise exceptions.ProviderConnectionError(f"Unexpected error: {str(e)}") from e
|
|
163
168
|
|
|
164
169
|
def for_non_stream():
|
|
165
170
|
try:
|
|
@@ -171,16 +176,24 @@ class Netwrck(Provider):
|
|
|
171
176
|
timeout=self.timeout,
|
|
172
177
|
)
|
|
173
178
|
response.raise_for_status()
|
|
174
|
-
|
|
179
|
+
|
|
180
|
+
if self.logger:
|
|
181
|
+
self.logger.debug(f"Response status: {response.status_code}")
|
|
182
|
+
|
|
175
183
|
text = response.text.strip('"')
|
|
176
184
|
self.last_response = {"text": text}
|
|
177
185
|
self.conversation.update_chat_history(prompt, text)
|
|
178
186
|
|
|
179
187
|
return self.last_response
|
|
188
|
+
|
|
189
|
+
except requests.exceptions.RequestException as e:
|
|
190
|
+
if self.logger:
|
|
191
|
+
self.logger.error(f"Network error: {str(e)}")
|
|
192
|
+
raise exceptions.FailedToGenerateResponseError(f"Network error: {str(e)}") from e
|
|
180
193
|
except Exception as e:
|
|
181
194
|
if self.logger:
|
|
182
|
-
self.logger.error(f"
|
|
183
|
-
raise exceptions.
|
|
195
|
+
self.logger.error(f"Unexpected error: {str(e)}")
|
|
196
|
+
raise exceptions.FailedToGenerateResponseError(f"Unexpected error: {str(e)}") from e
|
|
184
197
|
|
|
185
198
|
return for_stream() if stream else for_non_stream()
|
|
186
199
|
|
|
@@ -193,7 +206,7 @@ class Netwrck(Provider):
|
|
|
193
206
|
) -> str:
|
|
194
207
|
"""Generates a response from the Netwrck API."""
|
|
195
208
|
if self.logger:
|
|
196
|
-
|
|
209
|
+
self.logger.debug(f"Processing chat request [stream={stream}]")
|
|
197
210
|
|
|
198
211
|
def for_stream():
|
|
199
212
|
for response in self.ask(
|
|
@@ -219,21 +232,20 @@ class Netwrck(Provider):
|
|
|
219
232
|
def get_message(self, response: Dict[str, Any]) -> str:
|
|
220
233
|
"""Retrieves message only from response"""
|
|
221
234
|
assert isinstance(response, dict), "Response should be of dict data-type only"
|
|
222
|
-
return response["text"]
|
|
235
|
+
return response["text"].replace('\\n', '\n').replace('\\n\\n', '\n\n')
|
|
223
236
|
|
|
224
|
-
# Example Usage:
|
|
225
237
|
if __name__ == "__main__":
|
|
226
238
|
from rich import print
|
|
227
239
|
|
|
228
|
-
#
|
|
240
|
+
# Example with logging enabled
|
|
241
|
+
netwrck = Netwrck(model="claude", logging=False)
|
|
242
|
+
|
|
229
243
|
print("Non-Streaming Response:")
|
|
230
|
-
|
|
231
|
-
response = netwrck.chat("tell me about Russia")
|
|
244
|
+
response = netwrck.chat("Tell me about Russia")
|
|
232
245
|
print(response)
|
|
233
246
|
|
|
234
|
-
# Streaming example
|
|
235
247
|
print("\nStreaming Response:")
|
|
236
|
-
response = netwrck.chat("
|
|
248
|
+
response = netwrck.chat("Tell me about India", stream=True)
|
|
237
249
|
for chunk in response:
|
|
238
250
|
print(chunk, end="", flush=True)
|
|
239
|
-
print()
|
|
251
|
+
print()
|