From 5e5c2062bf436be34b5bb8dc5603c6ead9af45cc Mon Sep 17 00:00:00 2001 From: Jamie Wong Date: Sun, 24 May 2026 10:58:29 +0800 Subject: [PATCH 01/38] fix(openai): emit response.failed for /v1/responses after stream started When /v1/responses streaming hits the user/account concurrency wait, the wait loop sends SSE ping comments to keep the connection alive, which flushes HTTP 200 + headers. If the wait then times out (or any other post-flush error fires), handleStreamingAwareError previously emitted a generic `event: error` frame. Codex CLI requires the stream to end with a Responses terminal event (response.completed/failed/incomplete/cancelled), so it reports "stream closed before response.completed" and the user-facing rate-limit intent is lost. This change detects inbound = /v1/responses in both handleStreamingAwareError implementations and emits a protocol-compliant response.failed event whose field set mirrors apicompat.makeResponsesCompletedEvent (id/object/model/status/output/error). The synthetic id reuses ctxkey.RequestID so client errors can be grepped against server logs. sequence_number is intentionally omitted to preserve monotonicity on streams that already emitted real events. Other inbound endpoints (/v1/chat/completions, /v1/messages) keep their legacy formats untouched. Co-Authored-By: Claude Opus 4.7 --- backend/internal/handler/gateway_handler.go | 8 + .../handler/openai_gateway_handler.go | 9 + .../internal/handler/stream_error_event.go | 111 ++++++++++ .../handler/stream_error_event_test.go | 202 ++++++++++++++++++ 4 files changed, 330 insertions(+) create mode 100644 backend/internal/handler/stream_error_event.go create mode 100644 backend/internal/handler/stream_error_event_test.go diff --git a/backend/internal/handler/gateway_handler.go b/backend/internal/handler/gateway_handler.go index 4420a87c..970d7472 100644 --- a/backend/internal/handler/gateway_handler.go +++ b/backend/internal/handler/gateway_handler.go @@ -1420,6 +1420,14 @@ func (h *GatewayHandler) mapUpstreamError(statusCode int) (int, string, string) // handleStreamingAwareError handles errors that may occur after streaming has started func (h *GatewayHandler) handleStreamingAwareError(c *gin.Context, status int, errType, message string, streamStarted bool) { if streamStarted { + // /v1/responses 的严格 SDK(Codex CLI)要求终止事件必须属于 + // response.completed/failed/incomplete/cancelled 集合。 + // Anthropic-backed Responses 路径同样会因为通用 error 帧被拒。 + if GetInboundEndpoint(c) == EndpointResponses { + if writeResponsesFailedSSE(c, errType, message) { + return + } + } // Stream already started, send error as SSE event then close flusher, ok := c.Writer.(http.Flusher) if ok { diff --git a/backend/internal/handler/openai_gateway_handler.go b/backend/internal/handler/openai_gateway_handler.go index 9c5560f5..dd00a244 100644 --- a/backend/internal/handler/openai_gateway_handler.go +++ b/backend/internal/handler/openai_gateway_handler.go @@ -1691,6 +1691,15 @@ func (h *OpenAIGatewayHandler) mapUpstreamError(statusCode int) (int, string, st // handleStreamingAwareError handles errors that may occur after streaming has started func (h *OpenAIGatewayHandler) handleStreamingAwareError(c *gin.Context, status int, errType, message string, streamStarted bool) { if streamStarted { + // /v1/responses 的严格 SDK(Codex CLI)要求终止事件必须属于 + // response.completed/failed/incomplete/cancelled 集合。 + // 通用 `event: error` 帧不被识别为终止事件,会导致 + // "stream closed before response.completed"。 + if GetInboundEndpoint(c) == EndpointResponses { + if writeResponsesFailedSSE(c, errType, message) { + return + } + } // Stream already started, send error as SSE event then close flusher, ok := c.Writer.(http.Flusher) if ok { diff --git a/backend/internal/handler/stream_error_event.go b/backend/internal/handler/stream_error_event.go new file mode 100644 index 00000000..9c6378c2 --- /dev/null +++ b/backend/internal/handler/stream_error_event.go @@ -0,0 +1,111 @@ +package handler + +import ( + "fmt" + "net/http" + "strconv" + "strings" + + "github.com/Wei-Shaw/sub2api/internal/pkg/ctxkey" + "github.com/gin-gonic/gin" + "github.com/google/uuid" +) + +// writeResponsesFailedSSE emits a `response.failed` SSE event in the OpenAI +// Responses API protocol after the stream has already started. +// +// 必要性:一旦 SSE 头和任意数据(例如等待槽位时的 ping comment)已经 flush, +// HTTP 200 状态码就被固化。此后若网关需要回报错误,只能继续通过 SSE 事件传达。 +// 通用的 `event: error` 帧不是 Responses 协议规定的终止事件, +// Codex CLI 等严格 SDK 会因为没收到 `response.completed/failed/incomplete/cancelled` +// 而抛出 "stream closed before response.completed"。 +// +// 字段集对齐 apicompat.makeResponsesCompletedEvent:id/object/model/status/output/error。 +// 故意不写 sequence_number:本函数被调用时无法可靠拿到当前流的 last sequence, +// 而 OpenAI spec 将 sequence_number 设为可选;省略避免破坏单调性约束。 +// +// 返回 true 表示已尝试 SSE 写出(不论 Write 是否成功,caller 都应直接 return)。 +// 返回 false 表示 writer 不支持 Flusher,无法以 SSE 形式回报错误; +// 此时 caller 也无法回退到 JSON(HTTP 200 已固化),通常意味着连接已经损坏, +// 应当让请求处理函数 return,由上层关闭连接。 +func writeResponsesFailedSSE(c *gin.Context, errType, message string) bool { + flusher, ok := c.Writer.(http.Flusher) + if !ok { + return false + } + rid := synthesizeResponseID(c) + model := requestModel(c) + code := mapResponsesErrorCode(errType) + + var b strings.Builder + b.Grow(256 + len(message) + len(model)) + b.WriteString(`{"type":"response.failed","response":{`) + b.WriteString(`"id":`) + b.WriteString(strconv.Quote(rid)) + b.WriteString(`,"object":"response"`) + if model != "" { + b.WriteString(`,"model":`) + b.WriteString(strconv.Quote(model)) + } + b.WriteString(`,"status":"failed","output":[],"error":{"code":`) + b.WriteString(strconv.Quote(code)) + b.WriteString(`,"message":`) + b.WriteString(strconv.Quote(message)) + b.WriteString(`}}}`) + + if _, err := fmt.Fprintf(c.Writer, "event: response.failed\ndata: %s\n\n", b.String()); err != nil { + _ = c.Error(err) + return true + } + flusher.Flush() + return true +} + +// synthesizeResponseID 为合成的 response.failed 事件生成一个稳定的 id。 +// 优先复用 server 端生成的 request_id(存在 request.Context 里,由 request_logger 写入), +// 以便客户端报错能与 server 日志关联;缺失时回退 uuid。 +func synthesizeResponseID(c *gin.Context) string { + if c != nil && c.Request != nil { + if rid, ok := c.Request.Context().Value(ctxkey.RequestID).(string); ok { + if rid = strings.TrimSpace(rid); rid != "" { + return "resp_" + strings.ReplaceAll(rid, "-", "") + } + } + } + return "resp_" + strings.ReplaceAll(uuid.NewString(), "-", "") +} + +// requestModel 取当前请求的 inbound model(由 setOpsRequestContext 写入)。 +// 缺失时返回 "";caller 据此决定是否忽略该字段。 +func requestModel(c *gin.Context) string { + if c == nil { + return "" + } + if v, ok := c.Get(opsModelKey); ok { + if s, ok := v.(string); ok { + return strings.TrimSpace(s) + } + } + return "" +} + +// mapResponsesErrorCode 把内部 errType 映射为 Responses 协议常见的 error.code。 +// 无明确映射时原样返回,保证至少可读。 +func mapResponsesErrorCode(errType string) string { + switch errType { + case "rate_limit_error": + return "rate_limit_exceeded" + case "invalid_request_error": + return "invalid_request" + case "permission_error": + return "permission_denied" + case "authentication_error": + return "authentication_failed" + case "upstream_error": + return "upstream_error" + case "server_error", "api_error", "": + return "server_error" + default: + return errType + } +} diff --git a/backend/internal/handler/stream_error_event_test.go b/backend/internal/handler/stream_error_event_test.go new file mode 100644 index 00000000..e1abbc1d --- /dev/null +++ b/backend/internal/handler/stream_error_event_test.go @@ -0,0 +1,202 @@ +package handler + +import ( + "context" + "encoding/json" + "net/http" + "net/http/httptest" + "strings" + "testing" + + "github.com/Wei-Shaw/sub2api/internal/pkg/ctxkey" + "github.com/gin-gonic/gin" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// Regression for the production incident on 2026-05-24 around 9:13 CST: +// user 16 sent /v1/responses with stream:true via Codex CLI; the user-concurrency +// slot wait sent SSE ping comments (flushing HTTP 200 + headers), then the 30s +// timeout fired and the handler emitted `event: error\ndata: {...}`. Codex CLI +// does not recognize that as a Responses terminal event and reports +// "stream closed before response.completed". The fix is to emit a synthetic +// response.failed event when the inbound endpoint is /v1/responses. + +func newGinContextForEndpoint(t *testing.T, endpoint string) (*gin.Context, *httptest.ResponseRecorder) { + t.Helper() + gin.SetMode(gin.TestMode) + w := httptest.NewRecorder() + c, _ := gin.CreateTestContext(w) + c.Request = httptest.NewRequest(http.MethodPost, endpoint, nil) + return c, w +} + +// parseResponsesFailedSSE 抽出 SSE 中 data 行的 JSON,返回 (response 对象, error 对象)。 +func parseResponsesFailedSSE(t *testing.T, body string) (map[string]any, map[string]any) { + t.Helper() + require.True(t, strings.HasPrefix(body, "event: response.failed\n"), + "expect event: response.failed prefix, got: %q", body) + require.True(t, strings.HasSuffix(body, "\n\n")) + + lines := strings.SplitN(strings.TrimSuffix(body, "\n\n"), "\n", 2) + require.Len(t, lines, 2) + require.True(t, strings.HasPrefix(lines[1], "data: ")) + jsonStr := strings.TrimPrefix(lines[1], "data: ") + + var parsed map[string]any + require.NoError(t, json.Unmarshal([]byte(jsonStr), &parsed), "data must be valid JSON: %s", jsonStr) + + assert.Equal(t, "response.failed", parsed["type"]) + // 故意不发 sequence_number,避免与后续真实事件的序号冲突。 + _, hasSeq := parsed["sequence_number"] + assert.False(t, hasSeq, "synthetic event must not emit sequence_number") + + resp, ok := parsed["response"].(map[string]any) + require.True(t, ok, "response object missing") + assert.Equal(t, "response", resp["object"]) + assert.Equal(t, "failed", resp["status"]) + + errObj, ok := resp["error"].(map[string]any) + require.True(t, ok, "error object missing") + + return resp, errObj +} + +// OpenAI handler: /v1/responses streaming, after stream started, must emit response.failed. +func TestOpenAIHandleStreamingAwareError_ResponsesStreamingEmitsResponseFailed(t *testing.T) { + c, w := newGinContextForEndpoint(t, EndpointResponses) + h := &OpenAIGatewayHandler{} + h.handleStreamingAwareError(c, http.StatusTooManyRequests, "rate_limit_error", + "Concurrency limit exceeded for user, please retry later", true) + + resp, errObj := parseResponsesFailedSSE(t, w.Body.String()) + + id, _ := resp["id"].(string) + assert.True(t, strings.HasPrefix(id, "resp_"), "id should start with resp_, got %q", id) + assert.Equal(t, "rate_limit_exceeded", errObj["code"]) + assert.Equal(t, "Concurrency limit exceeded for user, please retry later", errObj["message"]) +} + +// 当 setOpsRequestContext 写过 model,合成事件应回填该字段(与 codebase 已有 makeResponsesCompletedEvent 对齐)。 +func TestOpenAIHandleStreamingAwareError_ResponsesStreamingIncludesModel(t *testing.T) { + c, w := newGinContextForEndpoint(t, EndpointResponses) + setOpsRequestContext(c, "gpt-5.5", true) + + h := &OpenAIGatewayHandler{} + h.handleStreamingAwareError(c, http.StatusBadGateway, "upstream_error", "boom", true) + + resp, _ := parseResponsesFailedSSE(t, w.Body.String()) + assert.Equal(t, "gpt-5.5", resp["model"]) +} + +// 没有 model 时 model 字段不应出现(避免发空字符串污染下游解析)。 +func TestOpenAIHandleStreamingAwareError_ResponsesStreamingOmitsEmptyModel(t *testing.T) { + c, w := newGinContextForEndpoint(t, EndpointResponses) + h := &OpenAIGatewayHandler{} + h.handleStreamingAwareError(c, http.StatusBadGateway, "upstream_error", "boom", true) + + resp, _ := parseResponsesFailedSSE(t, w.Body.String()) + _, hasModel := resp["model"] + assert.False(t, hasModel, "model field must be omitted when unknown") +} + +// 当 request.Context 携带 ctxkey.RequestID 时,合成 id 应与之关联,便于和 server log 串起来。 +func TestOpenAIHandleStreamingAwareError_ResponsesStreamingReusesRequestID(t *testing.T) { + c, w := newGinContextForEndpoint(t, EndpointResponses) + c.Request = c.Request.WithContext( + context.WithValue(c.Request.Context(), ctxkey.RequestID, "fd277bc5-ff7e-45d1-8aa9-f54e1df318f1"), + ) + + h := &OpenAIGatewayHandler{} + h.handleStreamingAwareError(c, http.StatusTooManyRequests, "rate_limit_error", "x", true) + + resp, _ := parseResponsesFailedSSE(t, w.Body.String()) + assert.Equal(t, "resp_fd277bc5ff7e45d18aa9f54e1df318f1", resp["id"]) +} + +// 与旧分支的 TestOpenAIHandleStreamingAwareError_JSONEscaping 对齐: +// 新的 response.failed payload 也必须正确转义 message 里的特殊字符, +// 否则下游 SDK 解析 JSON 时会失败。 +func TestOpenAIHandleStreamingAwareError_ResponsesStreamingJSONEscaping(t *testing.T) { + cases := []struct { + name string + errType string + message string + }{ + {"双引号", "server_error", `upstream returned "invalid" response`}, + {"反斜杠", "server_error", `path C:\Users\test\file.txt not found`}, + {"双引号+反斜杠", "upstream_error", `error parsing "key\value": unexpected token`}, + {"换行与制表", "server_error", "line1\nline2\ttab"}, + {"普通", "upstream_error", "Upstream service temporarily unavailable"}, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + c, w := newGinContextForEndpoint(t, EndpointResponses) + h := &OpenAIGatewayHandler{} + h.handleStreamingAwareError(c, http.StatusBadGateway, tc.errType, tc.message, true) + + _, errObj := parseResponsesFailedSSE(t, w.Body.String()) + assert.Equal(t, tc.message, errObj["message"], "message 必须被原样还原") + }) + } +} + +// OpenAI handler: /v1/chat/completions streaming keeps the legacy event: error format +// (out of scope for this fix; covered to prevent regression of unrelated paths). +func TestOpenAIHandleStreamingAwareError_ChatCompletionsStreamingKeepsLegacy(t *testing.T) { + c, w := newGinContextForEndpoint(t, EndpointChatCompletions) + h := &OpenAIGatewayHandler{} + h.handleStreamingAwareError(c, http.StatusBadGateway, "upstream_error", "boom", true) + + body := w.Body.String() + assert.True(t, strings.HasPrefix(body, "event: error\n"), "got: %q", body) +} + +// Gateway (Anthropic-backed) handler: /v1/responses path also must emit response.failed. +func TestGatewayHandleStreamingAwareError_ResponsesStreamingEmitsResponseFailed(t *testing.T) { + c, w := newGinContextForEndpoint(t, EndpointResponses) + h := &GatewayHandler{} + h.handleStreamingAwareError(c, http.StatusBadGateway, "upstream_error", "upstream gone", true) + + _, errObj := parseResponsesFailedSSE(t, w.Body.String()) + assert.Equal(t, "upstream_error", errObj["code"]) + assert.Equal(t, "upstream gone", errObj["message"]) +} + +// Gateway handler: /v1/messages preserves the legacy data:{type:error,...} format +// (Anthropic spec accepts a type:"error" stream event). +func TestGatewayHandleStreamingAwareError_MessagesStreamingKeepsLegacy(t *testing.T) { + c, w := newGinContextForEndpoint(t, EndpointMessages) + h := &GatewayHandler{} + h.handleStreamingAwareError(c, http.StatusBadGateway, "upstream_error", "boom", true) + + body := w.Body.String() + assert.True(t, strings.HasPrefix(body, `data: {"type":"error"`), "got: %q", body) +} + +// Synthesized response.failed id falls back to uuid when no request_id is present. +func TestSynthesizeResponseID_FallbackUUID(t *testing.T) { + c, _ := newGinContextForEndpoint(t, EndpointResponses) + id := synthesizeResponseID(c) + assert.True(t, strings.HasPrefix(id, "resp_")) + // uuid 去掉短横线后 32 hex 字符;前缀 "resp_" 共 37。 + assert.Len(t, id, 37) +} + +func TestMapResponsesErrorCode(t *testing.T) { + cases := []struct{ in, out string }{ + {"rate_limit_error", "rate_limit_exceeded"}, + {"invalid_request_error", "invalid_request"}, + {"permission_error", "permission_denied"}, + {"authentication_error", "authentication_failed"}, + {"upstream_error", "upstream_error"}, + {"server_error", "server_error"}, + {"api_error", "server_error"}, + {"", "server_error"}, + {"custom_thing", "custom_thing"}, + } + for _, tc := range cases { + assert.Equal(t, tc.out, mapResponsesErrorCode(tc.in), "in=%q", tc.in) + } +} From cff2f291be21f9d8d3367cec949a1ecf97182ede Mon Sep 17 00:00:00 2001 From: Jamie Wong Date: Sun, 24 May 2026 19:32:08 +0800 Subject: [PATCH 02/38] fix(openai): also match bare /responses route in handleStreamingAwareError MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first revision compared GetInboundEndpoint(c) against EndpointResponses ("/v1/responses"). NormalizeInboundEndpoint only recognizes paths that contain the literal "/v1/responses" substring, but the project actually registers six /responses routes — three of which (top-level r.POST("/responses", ...) and codexDirect's "/backend-api/codex/responses") have FullPath values without the "/v1" prefix and therefore fall through to the default branch. Codex CLI users targeting the bare /responses route at the production deployment (observed 2026-05-24 ~11:05 UTC, user 16) never reached the new writeResponsesFailedSSE path: the endpoint check was false, the legacy `event: error` frame fired, and the strict SDK kept reporting "stream closed before response.completed". Replace the strict equality check with inboundIsResponses(c), which uses suffix detection on FullPath (falling back to URL.Path when FullPath is empty in test fixtures) and covers all six route variants: /v1/responses[/...] /responses[/...] /backend-api/codex/responses[/...] Add test table covering all routes plus negative cases. Co-Authored-By: Claude Opus 4.7 --- backend/internal/handler/gateway_handler.go | 2 +- .../handler/openai_gateway_handler.go | 2 +- .../internal/handler/stream_error_event.go | 30 +++++++++++ .../handler/stream_error_event_test.go | 51 +++++++++++++++++++ 4 files changed, 83 insertions(+), 2 deletions(-) diff --git a/backend/internal/handler/gateway_handler.go b/backend/internal/handler/gateway_handler.go index 970d7472..be55e69b 100644 --- a/backend/internal/handler/gateway_handler.go +++ b/backend/internal/handler/gateway_handler.go @@ -1423,7 +1423,7 @@ func (h *GatewayHandler) handleStreamingAwareError(c *gin.Context, status int, e // /v1/responses 的严格 SDK(Codex CLI)要求终止事件必须属于 // response.completed/failed/incomplete/cancelled 集合。 // Anthropic-backed Responses 路径同样会因为通用 error 帧被拒。 - if GetInboundEndpoint(c) == EndpointResponses { + if inboundIsResponses(c) { if writeResponsesFailedSSE(c, errType, message) { return } diff --git a/backend/internal/handler/openai_gateway_handler.go b/backend/internal/handler/openai_gateway_handler.go index dd00a244..ea95b812 100644 --- a/backend/internal/handler/openai_gateway_handler.go +++ b/backend/internal/handler/openai_gateway_handler.go @@ -1695,7 +1695,7 @@ func (h *OpenAIGatewayHandler) handleStreamingAwareError(c *gin.Context, status // response.completed/failed/incomplete/cancelled 集合。 // 通用 `event: error` 帧不被识别为终止事件,会导致 // "stream closed before response.completed"。 - if GetInboundEndpoint(c) == EndpointResponses { + if inboundIsResponses(c) { if writeResponsesFailedSSE(c, errType, message) { return } diff --git a/backend/internal/handler/stream_error_event.go b/backend/internal/handler/stream_error_event.go index 9c6378c2..fc5bf61d 100644 --- a/backend/internal/handler/stream_error_event.go +++ b/backend/internal/handler/stream_error_event.go @@ -61,6 +61,36 @@ func writeResponsesFailedSSE(c *gin.Context, errType, message string) bool { return true } +// inboundIsResponses 判断当前请求是否落在任何 /responses 路由上。 +// +// 不能直接用 GetInboundEndpoint(c) == EndpointResponses 比较,因为 +// NormalizeInboundEndpoint 只识别包含 "/v1/responses" 子串的路径; +// 项目里实际注册了多组路由(gateway_v1、top-level bare、codex direct), +// 其中 r.POST("/responses", ...) 和 codexDirect.POST("/responses", ...) +// 的 c.FullPath() 不含 "/v1/" 前缀,会被归一化为原始路径, +// 导致协议合规终止事件没法发出去。 +// +// 这里用 FullPath 的后缀判断,覆盖所有变体: +// - /v1/responses +// - /v1/responses/compact +// - /responses +// - /responses/compact +// - /backend-api/codex/responses +// - /backend-api/codex/responses/compact +func inboundIsResponses(c *gin.Context) bool { + if c == nil { + return false + } + p := strings.TrimRight(c.FullPath(), "/") + if p == "" && c.Request != nil && c.Request.URL != nil { + p = strings.TrimRight(c.Request.URL.Path, "/") + } + if p == "" { + return false + } + return strings.HasSuffix(p, "/responses") || strings.Contains(p, "/responses/") +} + // synthesizeResponseID 为合成的 response.failed 事件生成一个稳定的 id。 // 优先复用 server 端生成的 request_id(存在 request.Context 里,由 request_logger 写入), // 以便客户端报错能与 server 日志关联;缺失时回退 uuid。 diff --git a/backend/internal/handler/stream_error_event_test.go b/backend/internal/handler/stream_error_event_test.go index e1abbc1d..721b5856 100644 --- a/backend/internal/handler/stream_error_event_test.go +++ b/backend/internal/handler/stream_error_event_test.go @@ -175,6 +175,57 @@ func TestGatewayHandleStreamingAwareError_MessagesStreamingKeepsLegacy(t *testin assert.True(t, strings.HasPrefix(body, `data: {"type":"error"`), "got: %q", body) } +// 项目里 /responses 注册在多组路由:/v1/responses(gateway)、裸 /responses(top-level)、 +// /backend-api/codex/responses(codex direct)。我们 fix 必须覆盖全部, +// 否则一些客户端走的路径就不会发 response.failed,照样报 stream closed。 +// 这是生产 2026-05-24 ~11:05 UTC user 16 实际命中的 bug。 +func TestInboundIsResponses_CoversAllRoutes(t *testing.T) { + cases := []struct { + route string + want bool + }{ + {"/v1/responses", true}, + {"/v1/responses/compact", true}, + {"/responses", true}, // <-- 用户 16 实际走这条 + {"/responses/compact", true}, + {"/backend-api/codex/responses", true}, + {"/backend-api/codex/responses/compact", true}, + {"/v1/chat/completions", false}, + {"/v1/messages", false}, + {"/", false}, + {"/responses-fake", false}, + } + for _, tc := range cases { + t.Run(tc.route, func(t *testing.T) { + c, _ := newGinContextForEndpoint(t, tc.route) + assert.Equal(t, tc.want, inboundIsResponses(c), "route=%q", tc.route) + }) + } +} + +// 用 c.Request.URL.Path 作为 fallback(当 c.FullPath() 为空时,例如某些测试 fixture)。 +func TestInboundIsResponses_FallsBackToURLPath(t *testing.T) { + gin.SetMode(gin.TestMode) + w := httptest.NewRecorder() + c, _ := gin.CreateTestContext(w) + c.Request = httptest.NewRequest(http.MethodPost, "/responses", nil) + // 这种情况下 c.FullPath() 是 "",必须 fallback 到 URL.Path + assert.True(t, inboundIsResponses(c), "URL.Path fallback must work when FullPath is empty") +} + +// 回归生产事故:用户 16 走 /responses 路径,必须发 response.failed。 +func TestOpenAIHandleStreamingAwareError_BareResponsesRouteEmitsResponseFailed(t *testing.T) { + c, w := newGinContextForEndpoint(t, "/responses") + h := &OpenAIGatewayHandler{} + h.handleStreamingAwareError(c, http.StatusTooManyRequests, "rate_limit_error", + "Concurrency limit exceeded for user, please retry later", true) + + resp, errObj := parseResponsesFailedSSE(t, w.Body.String()) + id, _ := resp["id"].(string) + assert.True(t, strings.HasPrefix(id, "resp_")) + assert.Equal(t, "rate_limit_exceeded", errObj["code"]) +} + // Synthesized response.failed id falls back to uuid when no request_id is present. func TestSynthesizeResponseID_FallbackUUID(t *testing.T) { c, _ := newGinContextForEndpoint(t, EndpointResponses) From b34cc71bee0f531f657ae1ff5c5eeed5c8d00c1d Mon Sep 17 00:00:00 2001 From: Jamie Wong Date: Sun, 24 May 2026 22:00:56 +0800 Subject: [PATCH 03/38] fix(openai): also emit response.failed in ensureForwardErrorResponse after Writer.Written MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Case B: when a slot wait flushes SSE ping comments first (Writer.Written becomes true), the previous ensureForwardErrorResponse short-circuited on `c.Writer.Written()` and returned false without notifying the client. Subsequent upstream errors (http2 timeout, stream INTERNAL_ERROR, etc.) produced silent EOF; Codex CLI reported "stream closed before response.completed" just like the user-slot timeout case. Remove the Written() early return; coerce streamStarted to true when Writer has already been written to, and let handleStreamingAwareError walk the existing logic — which now (thanks to the previous commits) emits a protocol-compliant response.failed for /responses paths and the legacy `event: error` for others. Update tests that previously asserted "do not override written response": the new contract is to *append* an SSE terminal frame so the client sees a clean close instead of EOF. recoverResponsesPanic inherits this fix. Co-Authored-By: Claude Opus 4.7 --- backend/internal/handler/gateway_handler.go | 8 +++- .../gateway_handler_error_fallback_test.go | 28 ++++++++++-- .../handler/openai_gateway_handler.go | 10 ++++- .../handler/openai_gateway_handler_test.go | 43 ++++++++++++++++--- 4 files changed, 79 insertions(+), 10 deletions(-) diff --git a/backend/internal/handler/gateway_handler.go b/backend/internal/handler/gateway_handler.go index be55e69b..51c2d94e 100644 --- a/backend/internal/handler/gateway_handler.go +++ b/backend/internal/handler/gateway_handler.go @@ -1446,10 +1446,16 @@ func (h *GatewayHandler) handleStreamingAwareError(c *gin.Context, status int, e } // ensureForwardErrorResponse 在 Forward 返回错误但尚未写响应时补写统一错误响应。 +// Writer 已被写过时(ping 已 flush)走 streamStarted 分支, +// 让 handleStreamingAwareError 通过 SSE 发协议合规的终止事件, +// 否则下游收到的就是 silent EOF。 func (h *GatewayHandler) ensureForwardErrorResponse(c *gin.Context, streamStarted bool) bool { - if c == nil || c.Writer == nil || c.Writer.Written() { + if c == nil || c.Writer == nil { return false } + if c.Writer.Written() { + streamStarted = true + } h.handleStreamingAwareError(c, http.StatusBadGateway, "upstream_error", "Upstream request failed", streamStarted) return true } diff --git a/backend/internal/handler/gateway_handler_error_fallback_test.go b/backend/internal/handler/gateway_handler_error_fallback_test.go index 4fce5ec1..fe9e2ebf 100644 --- a/backend/internal/handler/gateway_handler_error_fallback_test.go +++ b/backend/internal/handler/gateway_handler_error_fallback_test.go @@ -33,7 +33,9 @@ func TestGatewayEnsureForwardErrorResponse_WritesFallbackWhenNotWritten(t *testi assert.Equal(t, "Upstream request failed", errorObj["message"]) } -func TestGatewayEnsureForwardErrorResponse_DoesNotOverrideWrittenResponse(t *testing.T) { +// Writer 已写后 ensureForwardErrorResponse 必须把错误以 SSE 形式追加, +// 而不是 silent EOF。非 /responses 路径走 legacy data:{"type":"error"} 分支。 +func TestGatewayEnsureForwardErrorResponse_AppendsSSEAfterWritten(t *testing.T) { gin.SetMode(gin.TestMode) w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) @@ -43,7 +45,27 @@ func TestGatewayEnsureForwardErrorResponse_DoesNotOverrideWrittenResponse(t *tes h := &GatewayHandler{} wrote := h.ensureForwardErrorResponse(c, false) - require.False(t, wrote) + require.True(t, wrote) require.Equal(t, http.StatusTeapot, w.Code) - assert.Equal(t, "already written", w.Body.String()) + assert.Contains(t, w.Body.String(), "already written") + assert.Contains(t, w.Body.String(), `data: {"type":"error"`) +} + +// case B 回归:Anthropic-backed /responses,Writer 已被写过时 +// ensureForwardErrorResponse 仍要发 response.failed。 +func TestGatewayEnsureForwardErrorResponse_ResponsesRouteAfterWrittenEmitsResponseFailed(t *testing.T) { + gin.SetMode(gin.TestMode) + w := httptest.NewRecorder() + c, _ := gin.CreateTestContext(w) + c.Request = httptest.NewRequest(http.MethodPost, EndpointResponses, nil) + _, _ = c.Writer.WriteString(":\n\n") + + h := &GatewayHandler{} + wrote := h.ensureForwardErrorResponse(c, false) + + require.True(t, wrote) + body := w.Body.String() + assert.Contains(t, body, ":\n\n") + assert.Contains(t, body, "event: response.failed\n") + assert.Contains(t, body, `"type":"response.failed"`) } diff --git a/backend/internal/handler/openai_gateway_handler.go b/backend/internal/handler/openai_gateway_handler.go index ea95b812..5464d654 100644 --- a/backend/internal/handler/openai_gateway_handler.go +++ b/backend/internal/handler/openai_gateway_handler.go @@ -1719,9 +1719,17 @@ func (h *OpenAIGatewayHandler) handleStreamingAwareError(c *gin.Context, status // ensureForwardErrorResponse 在 Forward 返回错误但尚未写响应时补写统一错误响应。 func (h *OpenAIGatewayHandler) ensureForwardErrorResponse(c *gin.Context, streamStarted bool) bool { - if c == nil || c.Writer == nil || c.Writer.Written() { + if c == nil || c.Writer == nil { return false } + // 旧实现在 Writer.Written 时直接 return false,导致 ping 已 flush 之后的 + // 上游错误(http2 timeout、连接中断等)完全无法把错误传给客户端—— + // HTTP 200 已锁死,TCP 直接 EOF,Codex CLI 报 "stream closed before response.completed"。 + // 这里改成:Writer 已写过时强制走 streamStarted 分支,让 + // handleStreamingAwareError 通过 SSE 发协议合规的 response.failed。 + if c.Writer.Written() { + streamStarted = true + } h.handleStreamingAwareError(c, http.StatusBadGateway, "upstream_error", "Upstream request failed", streamStarted) return true } diff --git a/backend/internal/handler/openai_gateway_handler_test.go b/backend/internal/handler/openai_gateway_handler_test.go index 6bddbce9..49b7b9ec 100644 --- a/backend/internal/handler/openai_gateway_handler_test.go +++ b/backend/internal/handler/openai_gateway_handler_test.go @@ -174,7 +174,11 @@ func TestOpenAIEnsureForwardErrorResponse_WritesFallbackWhenNotWritten(t *testin assert.Equal(t, "Upstream request failed", errorObj["message"]) } -func TestOpenAIEnsureForwardErrorResponse_DoesNotOverrideWrittenResponse(t *testing.T) { +// Writer 已写后 ensureForwardErrorResponse 必须仍然把错误信息以 SSE +// 形式追加给客户端(streamStarted 强制 true)。 +// 这是 case B 修复:旧实现遇到 Writer.Written 直接 return false, +// 客户端只能拿到 silent EOF;Codex CLI 报 "stream closed before response.completed"。 +func TestOpenAIEnsureForwardErrorResponse_AppendsSSEAfterWritten(t *testing.T) { gin.SetMode(gin.TestMode) w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) @@ -184,9 +188,34 @@ func TestOpenAIEnsureForwardErrorResponse_DoesNotOverrideWrittenResponse(t *test h := &OpenAIGatewayHandler{} wrote := h.ensureForwardErrorResponse(c, false) - require.False(t, wrote) + require.True(t, wrote, "must attempt to communicate the failure to the client via SSE") + // 状态码改不了(headers 已 flush),但 body 应该追加 SSE 错误事件。 require.Equal(t, http.StatusTeapot, w.Code) - assert.Equal(t, "already written", w.Body.String()) + assert.Contains(t, w.Body.String(), "already written") + // 非 /responses 路径走 legacy event: error 分支。 + assert.Contains(t, w.Body.String(), "event: error\n") +} + +// case B 回归测试:/responses 路径,Writer 已被写过(模拟 ping flushed), +// ensureForwardErrorResponse 必须发 response.failed,让 Codex 收到合规终止事件。 +func TestOpenAIEnsureForwardErrorResponse_ResponsesRouteAfterWrittenEmitsResponseFailed(t *testing.T) { + gin.SetMode(gin.TestMode) + w := httptest.NewRecorder() + c, _ := gin.CreateTestContext(w) + c.Request = httptest.NewRequest(http.MethodPost, EndpointResponses, nil) + // 模拟 ping 已 flush 的状态:Writer 已写过 1 个字节 + _, _ = c.Writer.WriteString(":\n\n") + + h := &OpenAIGatewayHandler{} + wrote := h.ensureForwardErrorResponse(c, false) + + require.True(t, wrote) + body := w.Body.String() + assert.Contains(t, body, ":\n\n", "earlier ping bytes preserved") + assert.Contains(t, body, "event: response.failed\n", "appended a Responses terminal event") + assert.Contains(t, body, `"type":"response.failed"`) + assert.Contains(t, body, `"code":"upstream_error"`) + assert.Contains(t, body, "Upstream request failed") } func TestShouldLogOpenAIForwardFailureAsWarn(t *testing.T) { @@ -266,7 +295,9 @@ func TestOpenAIRecoverResponsesPanic_NoPanicNoWrite(t *testing.T) { assert.Equal(t, "", w.Body.String()) } -func TestOpenAIRecoverResponsesPanic_DoesNotOverrideWrittenResponse(t *testing.T) { +// Panic 在已 flush 的 /v1/responses 流中:状态码无法改(已 written), +// 但 body 应追加 response.failed 让客户端识别为合规截断而不是 silent EOF。 +func TestOpenAIRecoverResponsesPanic_AppendsResponseFailedAfterWritten(t *testing.T) { gin.SetMode(gin.TestMode) w := httptest.NewRecorder() @@ -284,7 +315,9 @@ func TestOpenAIRecoverResponsesPanic_DoesNotOverrideWrittenResponse(t *testing.T }) require.Equal(t, http.StatusTeapot, w.Code) - assert.Equal(t, "already written", w.Body.String()) + body := w.Body.String() + assert.Contains(t, body, "already written") + assert.Contains(t, body, "event: response.failed\n") } func TestOpenAIMissingResponsesDependencies(t *testing.T) { From fc66cd704a996928bc3f1c3d879bbc4feb12f23d Mon Sep 17 00:00:00 2001 From: siyuan <740665504@qq.com> Date: Mon, 25 May 2026 10:46:58 +0800 Subject: [PATCH 04/38] fix: recognize codex tool outputs in ws continuation --- .../service/openai_tool_continuation.go | 66 ++++++--- .../service/openai_tool_continuation_test.go | 47 ++++-- .../internal/service/openai_ws_forwarder.go | 30 +++- ...penai_ws_forwarder_ingress_session_test.go | 135 ++++++++++++++++++ .../openai_ws_forwarder_ingress_test.go | 30 ++++ 5 files changed, 272 insertions(+), 36 deletions(-) diff --git a/backend/internal/service/openai_tool_continuation.go b/backend/internal/service/openai_tool_continuation.go index c0f98de4..7d503f5a 100644 --- a/backend/internal/service/openai_tool_continuation.go +++ b/backend/internal/service/openai_tool_continuation.go @@ -20,6 +20,32 @@ type FunctionCallOutputValidation struct { HasItemReferenceForAllCallIDs bool } +func isCodexToolCallContextItemType(typ string) bool { + switch strings.TrimSpace(typ) { + case "tool_call", + "function_call", + "local_shell_call", + "tool_search_call", + "custom_tool_call", + "mcp_tool_call": + return true + default: + return false + } +} + +func isCodexToolCallOutputItemType(typ string) bool { + switch strings.TrimSpace(typ) { + case "function_call_output", + "tool_search_output", + "custom_tool_call_output", + "mcp_tool_call_output": + return true + default: + return false + } +} + // NeedsToolContinuation 判定请求是否需要工具调用续链处理。 // 满足以下任一信号即视为续链:previous_response_id、input 内包含工具输出/item_reference、 // 或显式声明 tools/tool_choice。 @@ -53,7 +79,9 @@ func NeedsToolContinuation(reqBody map[string]any) bool { return false } -// AnalyzeToolContinuationSignals 单次遍历 input,提取 function_call_output/tool_call/item_reference 相关信号。 +// AnalyzeToolContinuationSignals 单次遍历 input,提取工具输出/工具调用上下文/item_reference 相关信号。 +// 字段名保留 FunctionCallOutput 是为了兼容既有调用点;语义覆盖 Codex 的所有工具输出 +// (function_call_output/tool_search_output/custom_tool_call_output/mcp_tool_call_output)。 func AnalyzeToolContinuationSignals(reqBody map[string]any) ToolContinuationSignals { signals := ToolContinuationSignals{} if reqBody == nil { @@ -73,13 +101,13 @@ func AnalyzeToolContinuationSignals(reqBody map[string]any) ToolContinuationSign continue } itemType, _ := itemMap["type"].(string) - switch itemType { - case "tool_call", "function_call": + switch { + case isCodexToolCallContextItemType(itemType): callID, _ := itemMap["call_id"].(string) if strings.TrimSpace(callID) != "" { signals.HasToolCallContext = true } - case "function_call_output": + case isCodexToolCallOutputItemType(itemType): signals.HasFunctionCallOutput = true callID, _ := itemMap["call_id"].(string) callID = strings.TrimSpace(callID) @@ -91,7 +119,7 @@ func AnalyzeToolContinuationSignals(reqBody map[string]any) ToolContinuationSign callIDs = make(map[string]struct{}) } callIDs[callID] = struct{}{} - case "item_reference": + case itemType == "item_reference": signals.HasItemReference = true idValue, _ := itemMap["id"].(string) idValue = strings.TrimSpace(idValue) @@ -123,9 +151,10 @@ func AnalyzeToolContinuationSignals(reqBody map[string]any) ToolContinuationSign } // ValidateFunctionCallOutputContext 为 handler 提供低开销校验结果: -// 1) 无 function_call_output 直接返回 -// 2) 若已存在 tool_call/function_call 上下文则提前返回 +// 1) 无工具输出直接返回 +// 2) 若已存在工具调用上下文则提前返回 // 3) 仅在无工具上下文时才构建 call_id / item_reference 集合 +// 字段名保留 FunctionCallOutput 是为了兼容既有调用点;语义覆盖所有 Codex 工具输出。 func ValidateFunctionCallOutputContext(reqBody map[string]any) FunctionCallOutputValidation { result := FunctionCallOutputValidation{} if reqBody == nil { @@ -142,10 +171,10 @@ func ValidateFunctionCallOutputContext(reqBody map[string]any) FunctionCallOutpu continue } itemType, _ := itemMap["type"].(string) - switch itemType { - case "function_call_output": + switch { + case isCodexToolCallOutputItemType(itemType): result.HasFunctionCallOutput = true - case "tool_call", "function_call": + case isCodexToolCallContextItemType(itemType): callID, _ := itemMap["call_id"].(string) if strings.TrimSpace(callID) != "" { result.HasToolCallContext = true @@ -168,8 +197,8 @@ func ValidateFunctionCallOutputContext(reqBody map[string]any) FunctionCallOutpu continue } itemType, _ := itemMap["type"].(string) - switch itemType { - case "function_call_output": + switch { + case isCodexToolCallOutputItemType(itemType): callID, _ := itemMap["call_id"].(string) callID = strings.TrimSpace(callID) if callID == "" { @@ -177,7 +206,7 @@ func ValidateFunctionCallOutputContext(reqBody map[string]any) FunctionCallOutpu continue } callIDs[callID] = struct{}{} - case "item_reference": + case itemType == "item_reference": idValue, _ := itemMap["id"].(string) idValue = strings.TrimSpace(idValue) if idValue == "" { @@ -201,24 +230,25 @@ func ValidateFunctionCallOutputContext(reqBody map[string]any) FunctionCallOutpu return result } -// HasFunctionCallOutput 判断 input 是否包含 function_call_output,用于触发续链校验。 +// HasFunctionCallOutput 判断 input 是否包含任意 Codex 工具输出,用于触发续链校验。 +// 名称保留 function_call_output 是为了兼容既有调用点。 func HasFunctionCallOutput(reqBody map[string]any) bool { return AnalyzeToolContinuationSignals(reqBody).HasFunctionCallOutput } -// HasToolCallContext 判断 input 是否包含带 call_id 的 tool_call/function_call, -// 用于判断 function_call_output 是否具备可关联的上下文。 +// HasToolCallContext 判断 input 是否包含带 call_id 的工具调用上下文, +// 用于判断工具输出是否具备可关联的上下文。 func HasToolCallContext(reqBody map[string]any) bool { return AnalyzeToolContinuationSignals(reqBody).HasToolCallContext } -// FunctionCallOutputCallIDs 提取 input 中 function_call_output 的 call_id 集合。 +// FunctionCallOutputCallIDs 提取 input 中工具输出的 call_id 集合。 // 仅返回非空 call_id,用于与 item_reference.id 做匹配校验。 func FunctionCallOutputCallIDs(reqBody map[string]any) []string { return AnalyzeToolContinuationSignals(reqBody).FunctionCallOutputCallIDs } -// HasFunctionCallOutputMissingCallID 判断是否存在缺少 call_id 的 function_call_output。 +// HasFunctionCallOutputMissingCallID 判断是否存在缺少 call_id 的工具输出。 func HasFunctionCallOutputMissingCallID(reqBody map[string]any) bool { return AnalyzeToolContinuationSignals(reqBody).HasFunctionCallOutputMissingCallID } diff --git a/backend/internal/service/openai_tool_continuation_test.go b/backend/internal/service/openai_tool_continuation_test.go index 3f415d9d..0e0552f6 100644 --- a/backend/internal/service/openai_tool_continuation_test.go +++ b/backend/internal/service/openai_tool_continuation_test.go @@ -38,41 +38,57 @@ func TestNeedsToolContinuationSignals(t *testing.T) { } func TestHasFunctionCallOutput(t *testing.T) { - // 仅当 input 中存在 function_call_output 才视为续链输出。 + // 所有 Codex 工具输出都应视为续链输出,避免 WS 续链时丢失 previous_response_id。 require.False(t, HasFunctionCallOutput(nil)) - require.True(t, HasFunctionCallOutput(map[string]any{ - "input": []any{map[string]any{"type": "function_call_output"}}, - })) + for _, typ := range []string{ + "function_call_output", + "tool_search_output", + "custom_tool_call_output", + "mcp_tool_call_output", + } { + require.True(t, HasFunctionCallOutput(map[string]any{ + "input": []any{map[string]any{"type": typ}}, + }), typ) + } require.False(t, HasFunctionCallOutput(map[string]any{ "input": "text", })) } func TestHasToolCallContext(t *testing.T) { - // tool_call/function_call 必须包含 call_id,才能作为可关联上下文。 + // 工具调用上下文必须包含 call_id,才能作为可关联上下文。 require.False(t, HasToolCallContext(nil)) - require.True(t, HasToolCallContext(map[string]any{ - "input": []any{map[string]any{"type": "tool_call", "call_id": "call_1"}}, - })) - require.True(t, HasToolCallContext(map[string]any{ - "input": []any{map[string]any{"type": "function_call", "call_id": "call_2"}}, - })) + for _, typ := range []string{ + "tool_call", + "function_call", + "local_shell_call", + "tool_search_call", + "custom_tool_call", + "mcp_tool_call", + } { + require.True(t, HasToolCallContext(map[string]any{ + "input": []any{map[string]any{"type": typ, "call_id": "call_1"}}, + }), typ) + } require.False(t, HasToolCallContext(map[string]any{ "input": []any{map[string]any{"type": "tool_call"}}, })) } func TestFunctionCallOutputCallIDs(t *testing.T) { - // 仅提取非空 call_id,去重后返回。 + // 仅提取工具输出的非空 call_id,去重后返回。 require.Empty(t, FunctionCallOutputCallIDs(nil)) callIDs := FunctionCallOutputCallIDs(map[string]any{ "input": []any{ map[string]any{"type": "function_call_output", "call_id": "call_1"}, + map[string]any{"type": "tool_search_output", "call_id": "call_search"}, + map[string]any{"type": "custom_tool_call_output", "call_id": "call_custom"}, + map[string]any{"type": "mcp_tool_call_output", "call_id": "call_mcp"}, map[string]any{"type": "function_call_output", "call_id": ""}, map[string]any{"type": "function_call_output", "call_id": "call_1"}, }, }) - require.ElementsMatch(t, []string{"call_1"}, callIDs) + require.ElementsMatch(t, []string{"call_1", "call_search", "call_custom", "call_mcp"}, callIDs) } func TestHasFunctionCallOutputMissingCallID(t *testing.T) { @@ -80,8 +96,11 @@ func TestHasFunctionCallOutputMissingCallID(t *testing.T) { require.True(t, HasFunctionCallOutputMissingCallID(map[string]any{ "input": []any{map[string]any{"type": "function_call_output"}}, })) + require.True(t, HasFunctionCallOutputMissingCallID(map[string]any{ + "input": []any{map[string]any{"type": "tool_search_output"}}, + })) require.False(t, HasFunctionCallOutputMissingCallID(map[string]any{ - "input": []any{map[string]any{"type": "function_call_output", "call_id": "call_1"}}, + "input": []any{map[string]any{"type": "tool_search_output", "call_id": "call_1"}}, })) } diff --git a/backend/internal/service/openai_ws_forwarder.go b/backend/internal/service/openai_ws_forwarder.go index 700dbedf..5edf4db9 100644 --- a/backend/internal/service/openai_ws_forwarder.go +++ b/backend/internal/service/openai_ws_forwarder.go @@ -1548,13 +1548,35 @@ func openAIWSRawItemsHasPrefix(items []json.RawMessage, prefix []json.RawMessage func openAIWSRawItemsHasFunctionCallOutput(items []json.RawMessage) bool { for _, item := range items { - if gjson.GetBytes(item, "type").String() == "function_call_output" { + if isCodexToolCallOutputItemType(gjson.GetBytes(item, "type").String()) { return true } } return false } +func openAIWSRawPayloadHasToolCallOutput(payload []byte) bool { + if len(payload) == 0 { + return false + } + input := gjson.GetBytes(payload, "input") + if !input.Exists() { + return false + } + if input.IsArray() { + for _, item := range input.Array() { + if isCodexToolCallOutputItemType(item.Get("type").String()) { + return true + } + } + return false + } + if input.Type == gjson.JSON { + return isCodexToolCallOutputItemType(input.Get("type").String()) + } + return false +} + func buildOpenAIWSReplayInputSequence( previousFullInput []json.RawMessage, previousFullInputExists bool, @@ -2855,7 +2877,7 @@ func (s *OpenAIGatewayService) ProxyResponsesWebSocketFromClient( turnPreviousResponseIDKind := ClassifyOpenAIPreviousResponseIDKind(turnPreviousResponseID) turnPromptCacheKey := openAIWSPayloadStringFromRaw(payload, "prompt_cache_key") turnStoreDisabled := s.isOpenAIWSStoreDisabledInRequestRaw(payload, account) - turnHasFunctionCallOutput := gjson.GetBytes(payload, `input.#(type=="function_call_output")`).Exists() + turnHasFunctionCallOutput := openAIWSRawPayloadHasToolCallOutput(payload) eventCount := 0 tokenEventCount := 0 terminalEventCount := 0 @@ -3131,7 +3153,7 @@ func (s *OpenAIGatewayService) ProxyResponsesWebSocketFromClient( currentTurnReplayInputExists := false skipBeforeTurn := false hasCurrentOrReplayFunctionCallOutput := func(payload []byte) bool { - if gjson.GetBytes(payload, `input.#(type=="function_call_output")`).Exists() { + if openAIWSRawPayloadHasToolCallOutput(payload) { return true } return currentTurnReplayInputExists && openAIWSRawItemsHasFunctionCallOutput(currentTurnReplayInput) @@ -3256,7 +3278,7 @@ func (s *OpenAIGatewayService) ProxyResponsesWebSocketFromClient( currentPreviousResponseID := openAIWSPayloadStringFromRaw(currentPayload, "previous_response_id") expectedPrev := strings.TrimSpace(lastTurnResponseID) toolSignals := ToolContinuationSignals{ - HasFunctionCallOutput: gjson.GetBytes(currentPayload, `input.#(type=="function_call_output")`).Exists(), + HasFunctionCallOutput: openAIWSRawPayloadHasToolCallOutput(currentPayload), } if toolSignals.HasFunctionCallOutput { var currentReqBody map[string]any diff --git a/backend/internal/service/openai_ws_forwarder_ingress_session_test.go b/backend/internal/service/openai_ws_forwarder_ingress_session_test.go index a4b39ddf..edb6fbcd 100644 --- a/backend/internal/service/openai_ws_forwarder_ingress_session_test.go +++ b/backend/internal/service/openai_ws_forwarder_ingress_session_test.go @@ -1223,6 +1223,141 @@ func TestOpenAIGatewayService_ProxyResponsesWebSocketFromClient_StoreDisabledFun require.Equal(t, "resp_auto_prev_1", gjson.Get(requestToJSONString(captureConn.writes[1]), "previous_response_id").String(), "function_call_output 缺失 previous_response_id 时应回填上一轮响应 ID") } +func TestOpenAIGatewayService_ProxyResponsesWebSocketFromClient_StoreDisabledToolSearchOutputAutoAttachesPreviousResponseID(t *testing.T) { + gin.SetMode(gin.TestMode) + + cfg := &config.Config{} + cfg.Security.URLAllowlist.Enabled = false + cfg.Security.URLAllowlist.AllowInsecureHTTP = true + cfg.Gateway.OpenAIWS.Enabled = true + cfg.Gateway.OpenAIWS.OAuthEnabled = true + cfg.Gateway.OpenAIWS.APIKeyEnabled = true + cfg.Gateway.OpenAIWS.ResponsesWebsocketsV2 = true + cfg.Gateway.OpenAIWS.MaxConnsPerAccount = 1 + cfg.Gateway.OpenAIWS.MinIdlePerAccount = 0 + cfg.Gateway.OpenAIWS.MaxIdlePerAccount = 1 + cfg.Gateway.OpenAIWS.QueueLimitPerConn = 8 + cfg.Gateway.OpenAIWS.DialTimeoutSeconds = 3 + cfg.Gateway.OpenAIWS.ReadTimeoutSeconds = 3 + cfg.Gateway.OpenAIWS.WriteTimeoutSeconds = 3 + + captureConn := &openAIWSCaptureConn{ + events: [][]byte{ + []byte(`{"type":"response.completed","response":{"id":"resp_tool_search_prev_1","model":"gpt-5.1","usage":{"input_tokens":1,"output_tokens":1}}}`), + []byte(`{"type":"response.completed","response":{"id":"resp_tool_search_prev_2","model":"gpt-5.1","usage":{"input_tokens":1,"output_tokens":1}}}`), + }, + } + captureDialer := &openAIWSCaptureDialer{conn: captureConn} + pool := newOpenAIWSConnPool(cfg) + pool.setClientDialerForTest(captureDialer) + + svc := &OpenAIGatewayService{ + cfg: cfg, + httpUpstream: &httpUpstreamRecorder{}, + cache: &stubGatewayCache{}, + openaiWSResolver: NewOpenAIWSProtocolResolver(cfg), + toolCorrector: NewCodexToolCorrector(), + openaiWSPool: pool, + } + + account := &Account{ + ID: 145, + Name: "openai-ingress-tool-search-output-auto-prev", + Platform: PlatformOpenAI, + Type: AccountTypeAPIKey, + Status: StatusActive, + Schedulable: true, + Concurrency: 1, + Credentials: map[string]any{ + "api_key": "sk-test", + }, + Extra: map[string]any{ + "responses_websockets_v2_enabled": true, + }, + } + + serverErrCh := make(chan error, 1) + wsServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + conn, err := coderws.Accept(w, r, &coderws.AcceptOptions{ + CompressionMode: coderws.CompressionContextTakeover, + }) + if err != nil { + serverErrCh <- err + return + } + defer func() { + _ = conn.CloseNow() + }() + + rec := httptest.NewRecorder() + ginCtx, _ := gin.CreateTestContext(rec) + req := r.Clone(r.Context()) + req.Header = req.Header.Clone() + req.Header.Set("User-Agent", "unit-test-agent/1.0") + ginCtx.Request = req + + readCtx, cancel := context.WithTimeout(r.Context(), 3*time.Second) + msgType, firstMessage, readErr := conn.Read(readCtx) + cancel() + if readErr != nil { + serverErrCh <- readErr + return + } + if msgType != coderws.MessageText && msgType != coderws.MessageBinary { + serverErrCh <- errors.New("unsupported websocket client message type") + return + } + + serverErrCh <- svc.ProxyResponsesWebSocketFromClient(r.Context(), ginCtx, conn, account, "sk-test", firstMessage, nil) + })) + defer wsServer.Close() + + dialCtx, cancelDial := context.WithTimeout(context.Background(), 3*time.Second) + clientConn, _, err := coderws.Dial(dialCtx, "ws"+strings.TrimPrefix(wsServer.URL, "http"), nil) + cancelDial() + require.NoError(t, err) + defer func() { + _ = clientConn.CloseNow() + }() + + writeMessage := func(payload string) { + writeCtx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + require.NoError(t, clientConn.Write(writeCtx, coderws.MessageText, []byte(payload))) + } + readMessage := func() []byte { + readCtx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + msgType, message, readErr := clientConn.Read(readCtx) + require.NoError(t, readErr) + require.Equal(t, coderws.MessageText, msgType) + return message + } + + writeMessage(`{"type":"response.create","model":"gpt-5.1","stream":false,"store":false,"input":[{"type":"input_text","text":"hello"}]}`) + firstTurn := readMessage() + require.Equal(t, "resp_tool_search_prev_1", gjson.GetBytes(firstTurn, "response.id").String()) + + writeMessage(`{"type":"response.create","model":"gpt-5.1","stream":false,"store":false,"input":[{"type":"tool_search_output","call_id":"call_search_1","output":"ok"}]}`) + secondTurn := readMessage() + require.Equal(t, "resp_tool_search_prev_2", gjson.GetBytes(secondTurn, "response.id").String()) + + require.NoError(t, clientConn.Close(coderws.StatusNormalClosure, "done")) + select { + case serverErr := <-serverErrCh: + require.NoError(t, serverErr) + case <-time.After(5 * time.Second): + t.Fatal("等待 ingress websocket 结束超时") + } + + require.Equal(t, 1, captureDialer.DialCount()) + require.Len(t, captureConn.writes, 2) + secondWrite := requestToJSONString(captureConn.writes[1]) + require.Equal(t, "resp_tool_search_prev_1", gjson.Get(secondWrite, "previous_response_id").String(), "tool_search_output 缺失 previous_response_id 时应回填上一轮响应 ID") + require.Equal(t, "tool_search_output", gjson.Get(secondWrite, "input.0.type").String()) + require.Equal(t, "call_search_1", gjson.Get(secondWrite, "input.0.call_id").String()) +} + func TestOpenAIGatewayService_ProxyResponsesWebSocketFromClient_StoreDisabledFunctionCallOutputSkipsAutoAttachWhenLastResponseIDMissing(t *testing.T) { gin.SetMode(gin.TestMode) diff --git a/backend/internal/service/openai_ws_forwarder_ingress_test.go b/backend/internal/service/openai_ws_forwarder_ingress_test.go index c735f50a..31c9a142 100644 --- a/backend/internal/service/openai_ws_forwarder_ingress_test.go +++ b/backend/internal/service/openai_ws_forwarder_ingress_test.go @@ -696,6 +696,36 @@ func TestBuildOpenAIWSReplayInputSequence(t *testing.T) { }) } +func TestOpenAIWSRawPayloadHasToolCallOutput(t *testing.T) { + t.Parallel() + + for _, typ := range []string{ + "function_call_output", + "tool_search_output", + "custom_tool_call_output", + "mcp_tool_call_output", + } { + typ := typ + t.Run(typ, func(t *testing.T) { + t.Parallel() + payload := []byte(`{"input":[{"type":"` + typ + `","call_id":"call_1","output":"ok"}]}`) + require.True(t, openAIWSRawPayloadHasToolCallOutput(payload)) + }) + } + + t.Run("object_input", func(t *testing.T) { + t.Parallel() + payload := []byte(`{"input":{"type":"tool_search_output","call_id":"call_1","output":"ok"}}`) + require.True(t, openAIWSRawPayloadHasToolCallOutput(payload)) + }) + + t.Run("non_tool_output", func(t *testing.T) { + t.Parallel() + payload := []byte(`{"input":[{"type":"input_text","text":"hello"}]}`) + require.False(t, openAIWSRawPayloadHasToolCallOutput(payload)) + }) +} + func TestSetOpenAIWSPayloadInputSequence(t *testing.T) { t.Parallel() From a9c7a3a095758c0be6dd244bdbbb4511ed8745fb Mon Sep 17 00:00:00 2001 From: wucm667 Date: Mon, 25 May 2026 14:15:39 +0800 Subject: [PATCH 05/38] fix(bedrock): strip context_management when beta is removed --- backend/internal/service/bedrock_request.go | 22 +++++++ .../internal/service/bedrock_request_test.go | 61 +++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/backend/internal/service/bedrock_request.go b/backend/internal/service/bedrock_request.go index 8a1fb317..f4416ce3 100644 --- a/backend/internal/service/bedrock_request.go +++ b/backend/internal/service/bedrock_request.go @@ -185,6 +185,7 @@ func BuildBedrockURL(region, modelID string, stream bool) string { // 5. 清理 cache_control 中 Bedrock 不支持的字段(scope, ttl) // 6. 修复 thinking 字段兼容性(Opus 4.7 仅支持 adaptive,enabled 需要 budget_tokens) // 7. 清理 tool_use.id / tool_use_id 中 Bedrock 不接受的字符 +// 8. 根据最终 Bedrock beta tokens 剥离不再支持的 beta 字段 func PrepareBedrockRequestBody(body []byte, modelID string, betaHeader string) ([]byte, error) { betaTokens := ResolveBedrockBetaTokens(betaHeader, body, modelID) return PrepareBedrockRequestBodyWithTokens(body, modelID, betaTokens, false) @@ -195,6 +196,9 @@ func PrepareBedrockRequestBody(body []byte, modelID string, betaHeader string) ( func PrepareBedrockRequestBodyWithTokens(body []byte, modelID string, betaTokens []string, ccCompat bool) ([]byte, error) { var err error + betaTokens = filterBedrockBetaTokens(betaTokens) + body = sanitizeBedrockFieldsForBetaTokens(body, betaTokens) + // 注入 anthropic_version(Bedrock 要求) body, err = sjson.SetBytes(body, "anthropic_version", "bedrock-2023-05-31") if err != nil { @@ -471,6 +475,8 @@ var bedrockSupportedBetaTokens = map[string]bool{ "tool-examples-2025-10-29": true, } +const bedrockContextManagementBetaToken = "context-management-2025-06-27" + // bedrockBetaTokenTransforms 定义 Bedrock Invoke 特有的 beta 头转换规则 // Anthropic 直接 API 使用通用头,Bedrock Invoke 需要特定的替代头 var bedrockBetaTokenTransforms = map[string]string{ @@ -617,6 +623,22 @@ func filterBedrockBetaTokens(tokens []string) []string { return result } +func sanitizeBedrockFieldsForBetaTokens(body []byte, betaTokens []string) []byte { + if !containsBedrockBetaToken(betaTokens, bedrockContextManagementBetaToken) && gjson.GetBytes(body, "context_management").Exists() { + body, _ = sjson.DeleteBytes(body, "context_management") + } + return body +} + +func containsBedrockBetaToken(tokens []string, target string) bool { + for _, token := range tokens { + if token == target { + return true + } + } + return false +} + // bedrockToolUseIDRe 匹配 Bedrock 允许的 tool_use ID 字符(字母、数字、下划线、连字符) var bedrockToolUseIDRe = regexp.MustCompile(`[^a-zA-Z0-9_-]`) diff --git a/backend/internal/service/bedrock_request_test.go b/backend/internal/service/bedrock_request_test.go index 98942ba4..94f1a118 100644 --- a/backend/internal/service/bedrock_request_test.go +++ b/backend/internal/service/bedrock_request_test.go @@ -378,6 +378,67 @@ func TestPrepareBedrockRequestBody_BetaFiltering(t *testing.T) { }) } +func TestPrepareBedrockRequestBodyWithTokens_ContextManagementRequiresSupportedBeta(t *testing.T) { + modelID := "us.anthropic.claude-opus-4-6-v1" + + t.Run("strips context_management when final tokens omit context-management beta", func(t *testing.T) { + input := `{ + "messages":[{"role":"user","content":"hi"}], + "max_tokens":100, + "context_management":{"edits":[{"type":"clear_thinking_20251015","keep":"all"}]} + }` + betaTokens := []string{"context-1m-2025-08-07"} + originalTokens := append([]string(nil), betaTokens...) + + result, err := PrepareBedrockRequestBodyWithTokens([]byte(input), modelID, betaTokens, false) + require.NoError(t, err) + + assert.False(t, gjson.GetBytes(result, "context_management").Exists()) + assert.Equal(t, originalTokens, betaTokens) + assert.Equal(t, originalTokens, bedrockAnthropicBetaNames(result)) + }) + + t.Run("leaves body without context_management otherwise intact", func(t *testing.T) { + input := `{"messages":[{"role":"user","content":"hi"}],"max_tokens":100}` + + result, err := PrepareBedrockRequestBodyWithTokens([]byte(input), modelID, nil, false) + require.NoError(t, err) + + assert.False(t, gjson.GetBytes(result, "context_management").Exists()) + assert.False(t, gjson.GetBytes(result, "anthropic_beta").Exists()) + assert.Equal(t, "hi", gjson.GetBytes(result, "messages.0.content").String()) + assert.Equal(t, int64(100), gjson.GetBytes(result, "max_tokens").Int()) + }) + + t.Run("filters explicit unsupported context-management beta and strips field", func(t *testing.T) { + input := `{ + "messages":[{"role":"user","content":"hi"}], + "max_tokens":100, + "context_management":{"edits":[{"type":"clear_thinking_20251015","keep":"all"}]} + }` + + result, err := PrepareBedrockRequestBodyWithTokens( + []byte(input), + modelID, + []string{bedrockContextManagementBetaToken, "context-1m-2025-08-07"}, + false, + ) + require.NoError(t, err) + + assert.False(t, gjson.GetBytes(result, "context_management").Exists()) + assert.Equal(t, []string{"context-1m-2025-08-07"}, bedrockAnthropicBetaNames(result)) + }) +} + +func bedrockAnthropicBetaNames(body []byte) []string { + arr := gjson.GetBytes(body, "anthropic_beta").Array() + names := make([]string, len(arr)) + for i, token := range arr { + names[i] = token.String() + } + return names +} + func TestBedrockCrossRegionPrefix(t *testing.T) { tests := []struct { region string From 53acde1efd236e54b629f2122b7dec6469945508 Mon Sep 17 00:00:00 2001 From: shaw Date: Mon, 25 May 2026 18:16:46 +0800 Subject: [PATCH 06/38] style: fix lint errors in response.failed SSE writer Errcheck flagged three unchecked strings.Builder.WriteString calls and gofmt rejected over-aligned trailing comment in the route table. Rewrite writeResponsesFailedSSE with json.Marshal on typed structs instead of Builder+strconv.Quote. Same wire format, but: - no unchecked Write returns to silence - strict JSON escaping (strconv.Quote emits \a and \v which are not valid JSON; Marshal handles all runes correctly) - omitempty model field via struct tag instead of conditional Builder - consistent with the json.Marshal style used elsewhere in handler/ Collapse trailing comment whitespace in stream_error_event_test.go to satisfy gofmt. All 30+ subtests in the package still pass. --- .../internal/handler/stream_error_event.go | 62 +++++++++++++------ .../handler/stream_error_event_test.go | 2 +- 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/backend/internal/handler/stream_error_event.go b/backend/internal/handler/stream_error_event.go index fc5bf61d..f3a33a8c 100644 --- a/backend/internal/handler/stream_error_event.go +++ b/backend/internal/handler/stream_error_event.go @@ -1,9 +1,9 @@ package handler import ( + "encoding/json" "fmt" "net/http" - "strconv" "strings" "github.com/Wei-Shaw/sub2api/internal/pkg/ctxkey" @@ -11,6 +11,30 @@ import ( "github.com/google/uuid" ) +// responsesFailedError 对齐 OpenAI Responses 协议 error 子对象。 +type responsesFailedError struct { + Code string `json:"code"` + Message string `json:"message"` +} + +// responsesFailedBody 对齐 apicompat.makeResponsesCompletedEvent 输出的 response 子对象字段集。 +// Output 用空 slice(不是 nil)确保 marshal 为 `[]` 而非 `null`。 +type responsesFailedBody struct { + ID string `json:"id"` + Object string `json:"object"` + Model string `json:"model,omitempty"` + Status string `json:"status"` + Output []any `json:"output"` + Error responsesFailedError `json:"error"` +} + +// responsesFailedEvent 是写入 SSE data 行的顶层结构。 +// 故意不带 sequence_number:spec 标记可选,且本函数被调用时无法可靠拿到 last seq。 +type responsesFailedEvent struct { + Type string `json:"type"` + Response responsesFailedBody `json:"response"` +} + // writeResponsesFailedSSE emits a `response.failed` SSE event in the OpenAI // Responses API protocol after the stream has already started. // @@ -33,27 +57,27 @@ func writeResponsesFailedSSE(c *gin.Context, errType, message string) bool { if !ok { return false } - rid := synthesizeResponseID(c) - model := requestModel(c) - code := mapResponsesErrorCode(errType) - var b strings.Builder - b.Grow(256 + len(message) + len(model)) - b.WriteString(`{"type":"response.failed","response":{`) - b.WriteString(`"id":`) - b.WriteString(strconv.Quote(rid)) - b.WriteString(`,"object":"response"`) - if model != "" { - b.WriteString(`,"model":`) - b.WriteString(strconv.Quote(model)) + payload, err := json.Marshal(responsesFailedEvent{ + Type: "response.failed", + Response: responsesFailedBody{ + ID: synthesizeResponseID(c), + Object: "response", + Model: requestModel(c), + Status: "failed", + Output: []any{}, + Error: responsesFailedError{ + Code: mapResponsesErrorCode(errType), + Message: message, + }, + }, + }) + if err != nil { + _ = c.Error(err) + return true } - b.WriteString(`,"status":"failed","output":[],"error":{"code":`) - b.WriteString(strconv.Quote(code)) - b.WriteString(`,"message":`) - b.WriteString(strconv.Quote(message)) - b.WriteString(`}}}`) - if _, err := fmt.Fprintf(c.Writer, "event: response.failed\ndata: %s\n\n", b.String()); err != nil { + if _, err := fmt.Fprintf(c.Writer, "event: response.failed\ndata: %s\n\n", payload); err != nil { _ = c.Error(err) return true } diff --git a/backend/internal/handler/stream_error_event_test.go b/backend/internal/handler/stream_error_event_test.go index 721b5856..f24cf97f 100644 --- a/backend/internal/handler/stream_error_event_test.go +++ b/backend/internal/handler/stream_error_event_test.go @@ -186,7 +186,7 @@ func TestInboundIsResponses_CoversAllRoutes(t *testing.T) { }{ {"/v1/responses", true}, {"/v1/responses/compact", true}, - {"/responses", true}, // <-- 用户 16 实际走这条 + {"/responses", true}, // <-- 用户 16 实际走这条 {"/responses/compact", true}, {"/backend-api/codex/responses", true}, {"/backend-api/codex/responses/compact", true}, From 2f70d965bf5b046ad6e9474a77a493bf4fb60801 Mon Sep 17 00:00:00 2001 From: shaw Date: Mon, 25 May 2026 19:02:58 +0800 Subject: [PATCH 07/38] chore: update sponsors --- README.md | 16 +++++++++++++--- README_CN.md | 12 ++++++++++++ README_JA.md | 12 ++++++++++++ assets/partners/logos/unity2.png | Bin 0 -> 761902 bytes assets/partners/logos/veilx.png | Bin 0 -> 384971 bytes 5 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 assets/partners/logos/unity2.png create mode 100644 assets/partners/logos/veilx.png diff --git a/README.md b/README.md index 5415ea61..cb9d36ed 100644 --- a/README.md +++ b/README.md @@ -103,9 +103,7 @@ Sub2API is an AI API gateway platform designed to distribute and manage API quot pateway -Thanks to PatewayAI for sponsoring this project! PatewayAI is a premium model API relay service provider built for heavy AI developers, focused on direct official connections. Offering the full Claude series and Codex series models, 100% sourced directly from official providers — no dilution, no substitution, open to verification. Billing is fully transparent with token-level invoices that can be audited line by line. -Enterprise-grade high concurrency is also supported, with a dedicated management platform for enterprise clients. Enterprise customers can sign formal contracts and receive invoices. Visit the official website for more details and contact information. -Register now via this link to receive $3 in trial credits. User top-ups start as low as 60% off, and referring friends earns both parties rewards — referral bonuses up to $150. +Thanks to PatewayAI for sponsoring this project! PatewayAI is a premium API relay built for heavy AI developers, offering the full Claude and Codex series sourced 100% from official providers, with transparent token-level billing. Enterprise plans include high concurrency, dedicated management, contracts, and invoicing. Register now to get $3 in trial credits, top-ups from 60% off, and referral bonuses up to $150. @@ -120,6 +118,18 @@ Register now via this link to recei + +unity2 +Thanks to Unity2 for sponsoring this project! Unity2 is a high-performance AI model API relay for individuals, teams, and enterprises, handling 30B+ tokens/day with 5000 RPM concurrency. One API Key works across Claude Code, Codex, OpenAI models, IDE plugins, and Agent workflows, with balance billing, bundled subscriptions, enterprise invoicing, and 1-on-1 support. Register to claim $2 in balance, plus $10 more by joining the official group — up to $12 in free credit. + + + + +veilx +Thanks to Veilx for sponsoring this project! Veilx CDN is purpose-built for large-scale AI API traffic, deeply optimized for relay services and call chains across OpenAI, Claude, Gemini, and scenarios like chat, image generation, embeddings, and streaming — delivering lower latency and higher stability under heavy concurrency. It also offers China three-network optimized return lines, making it ideal for global AI relay platforms, overseas AI SaaS, and cross-border high-concurrency deployments. + + + ## Ecosystem diff --git a/README_CN.md b/README_CN.md index ca7b3218..6c9ff372 100644 --- a/README_CN.md +++ b/README_CN.md @@ -119,6 +119,18 @@ Sub2API 是一个 AI API 网关平台,用于分发和管理 AI 产品订阅的 + +unity2 +感谢 Unity2 赞助本项目! Unity2 是面向个人开发者、团队、企业的高性能 AI 模型 API 中转平台,长期服务国内头部企业,日均承载超 300 亿 token 调用,支持 5000 RPM 级高并发。一个 API Key 即可适配 Claude Code、Codex、OpenAI 模型、IDE 插件和 Agent 工作流等场景。具备企业级稳定供应能力,在高并发、持续调用和团队集中采购场景下依然保持低延迟、高可用。同时支持余额计费、组合订阅、首充优惠、企业开票、专属 1v1 对接,适合个人高频使用和企业长期接入。现在注册 Unity2.ai 可领取 $2 余额,加入官方群再送 $10 余额,合计最高可领 $12 免费额度,适合先体验后长期使用。注册链接 + + + + +veilx +感谢 Veilx 赞助本项目! Veilx CDN 专为超大规模 API 请求场景打造,针对 AI 中转站业务与 AI API 调用链路进行了深度优化,轻松应对高并发、高频请求与大流量传输,为开发者与企业提供更快、更稳、更低延迟的加速体验。无论是 OpenAI、Claude、Gemini 等 AI 接口中转,还是聊天、绘图、Embedding、流式输出等复杂场景,Veilx 都能显著提升响应速度与连接稳定性,有效降低网络波动带来的超时与失败问题。同时,Veilx 提供中国三网优化回国极速线路,大幅提升中国大陆地区访问海外 AI 服务的速度与稳定性,特别适合全球 AI 中转平台、海外 AI SaaS、跨境业务与高并发 API 系统部署。专为 AI API 而生,让你的 AI 中转服务更快、更稳、更省心。购买地址 + + + ## 生态项目 diff --git a/README_JA.md b/README_JA.md index 45adfd65..e3453d5e 100644 --- a/README_JA.md +++ b/README_JA.md @@ -119,6 +119,18 @@ Sub2API は、AI 製品のサブスクリプションから API クォータを + +unity2 +Unity2 のご支援に感謝します!Unity2 は個人開発者、チーム、企業向けの高性能 AI モデル API 中継プラットフォームです。中国の大手企業に長期にわたりサービスを提供しており、1日あたり 300 億以上のトークン呼び出しを処理し、5000 RPM 級の高並列性をサポートします。1つの API キーで Claude Code、Codex、OpenAI モデル、IDE プラグイン、Agent ワークフローなど様々なシナリオに対応できます。エンタープライズグレードの安定供給能力を備え、高並列・継続的な呼び出し・チームの集中購入シーンでも低レイテンシと高可用性を維持します。残高課金、組み合わせサブスクリプション、初回チャージ特典、企業向け請求書発行、専属 1v1 サポートにも対応しており、個人の頻繁な利用にも企業の長期導入にも適しています。今 Unity2.ai に登録すると $2 の残高、公式グループに参加するとさらに $10 の残高がもらえ、合計最大 $12 の無料クレジットを獲得できます — 試用後に長期利用したい方に最適です。登録リンク + + + + +veilx +Veilx のご支援に感謝します!Veilx CDN は超大規模 API リクエストシナリオ向けに設計されており、AI 中継サービスと AI API 呼び出しチェーンに対して深く最適化されています。高並列・高頻度リクエスト・大容量トラフィックに容易に対応し、開発者と企業により高速で安定した、低レイテンシの加速体験を提供します。OpenAI、Claude、Gemini などの AI インターフェース中継はもちろん、チャット、画像生成、Embedding、ストリーミング出力などの複雑なシナリオでも、Veilx は応答速度と接続安定性を大幅に向上させ、ネットワーク変動によるタイムアウトや失敗を効果的に削減します。さらに、Veilx は中国三大ネットワーク最適化の高速回線を提供しており、中国本土から海外 AI サービスへのアクセス速度と安定性を大幅に向上させます。グローバル AI 中継プラットフォーム、海外 AI SaaS、越境ビジネス、高並列 API システム展開に特に適しています。AI API のために生まれ、あなたの AI 中継サービスをより速く、より安定して、より安心に。購入リンク + + + ## エコシステム diff --git a/assets/partners/logos/unity2.png b/assets/partners/logos/unity2.png new file mode 100644 index 0000000000000000000000000000000000000000..f1da2ed1b7b42c84f1c3940f39b18c8d37b4caca GIT binary patch literal 761902 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�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℞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≻B}Ct9E-W6 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

WrJeD;I`nns9y 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 qcH&Pqd0YPXM!lU+(tbCBKsTGjPnFsQ5Q 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

BaIe#LeK~Ardr)tdOx(Ibw?hs3Ud`Eg8xXb$0 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�WzePMkP# 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%0Do$3-sn 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

jr+T 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�|GOpl=z2|<5fxN7GBi{3?#8l3m-nFRD(`C~P^JPVdy^ zRg>0(l7UBn@|Twk1(~r3PHFLd=A@*qC#(SO0EUQ6;`Bn3XT@77@LlutB=pg`KJG3Z zA2*6Ue)#RQaX4R=du;K2Oov7vxIPR%5E@IL%DK(u)wWnuVgJj-IyIH^{$9)_p_hoo z$kNh&l6)WQj6Rs|2?@A}Hy+z-$rSA5#glzDFv9X9akxd0;ICq=2o2 zJ^prlxC$X`do$H;kH&;O?%VT0+$CF!J)Q`AJo&C)ZC4q@)S}+1!!d5ALtzi2kA>@l zgqMUpCSzzPxNBLI-%ee|!<#4bHrk`i| z6u-<1lg>0>f=wcDssiB1OiXYi`k{c2xT}uOSJenbY4zBdx+bpm!!ALOFN??Hw~xPk zxRO`QKoA6|d_?aiw`9qH^$xDHNuKqYu=Dpl`4bYt~1$Jth? z*PevW83ROTFIZ`B$U%>1Em2pJ?W(QwuWs10Y$7IvDXCNE5_zto`jW)kfR9yhkS_)w ze-d^v=>_O0ve2@IR=c;{jH&yUv?IK|v+hm);Ch|VpGED}HdH`oq0kZ;J;>_b`ZY#F z_)H>rU+!iZ2#%~C)InVp1;H#Oh@DC`_INd<^F$38mVKeYhrmMtD$yIOw@N`P;K@i zN%u&n$E=SmjE=6q^S;r!gt-JA2fj%DGczo|@S~F8-E5wg=@qOHQ zuCR+aAFbcRo)24#J~HzW%Q-KnLLaQ*e1{7XPLTU2-zVS4&fudmu`B<4a9U>dtD!3$ zz1>RHt*>JZC#hI$wuL?ZQj6G@pwK@2FaR<3*ludMpDrAug{3h*F4*Hf=wt5rcv9jn z#vV^^jb+-BOPa+0u}j$Fwy+1BkLvoki6vQ=?Dy!)=2MiB5Uy0sRe4VB`EbWC-_^qv zFEGJgD9?^e4F;nU*cv#A88`Sh2PKDZrpU!O{v(@8f3YvqO#or7hsm+3<^A!vw&ORM zoS60vYZKP>m5X9jFTS{j8sJ05>Hd*TP7l&9AxL?sKrMp9%y(|6F(}VSj%p@Nft}si zF6FfJuim`<<-=#f9hYTk-Ao^>q@mtvFoG3lNCGMufc*0I&HG&m!0dKl4-slSzqOF8 z2YhJBqbyj=i>}Wl_Zs5ok+z}U1h|V;u>WLRPW90mB1dO2UQee;*89jlYXhU=3?}RX z_)uf1z4pKd<^A%)YCNq3X(*6l!f4e9D0Te**m~2iyfebV71vV5*eD>YbCMBygeXk| z51~-!9GwmpFox1f(X{E+M8Mg|}MN?$+T`*x~~gLL(xeMrG5p^q1> z=VOuZVyUt3K_9{Uuy9#``So$24}lGTWVgr5^ikLKFPzJoBQMu>+GUm|(NvHOU#4)z z+A^DPowYORRwemCt*YmudKPk1#d(^w#T0Wf_`vZ2_Ap4&$(?_fG}Tuke1yqqv`L!k zr$u-ELf6MK>hk#Mod9b@hhiM8EA{|>%=2w+x4ur;BNl@pa@C5rBV4`SWQ4;5>>(;D z8(9%FYq5AVE>|P`w8$ohFDm3sE<>pWuuFC}z5nf9wzu#8$lhn#t^yf07WE30%C)AIYy(F=2NaQx~){+an|!2%U=czdbsB|8~)XvBe+W{Pt#dynFQJG)4QO z!%9{z@iER4#hY0E0EYHay5ft&AWkB3?WrhTCYbBxjI{8|=u-69Y4~OAk+A`1BrIr| zwF+k40tD|q8m?sD#G5a{2f=z>fkv_m<|C%gO|WeA*nkg#Y5fr*A0T#~Zv*o+hFnyT@mx8>Mfa6mjh>fcNSgsv58kbyo7 zKIXJj!Y&UI`nd7!ai3X;5|q?r9=y}(@W%7X`haqZ!g_Uloc?}#n$d@oPdC)3l-B9P zR4i8PQs77CZN7Y|=Vq28FE746I8+4QQp@F`8>*AcRry6*Nb$rVmKNyYSEN6yXNe(( zltkg0CK34abI`{Z!a&%|RtY}ouiwgk56O8Md#}stJmowWwTws~bJho$wzB6Bw+cvX zG@+^(Xp|Q&*yG{deDjF8%#p_}VUKRBR9Ip5{AId?!Y!_XVGYRW`@O%lY4aqv7`4~Q zW2k)&@S$--!|M-aQa?L>Bj5iY+poKgJn@6#)^)tcSLfaNagA$`BzGS&qRbE_0EfNdrjKyHDABBQH4LwGLLqUzb#1)_(--Ck)!Y~jBk1CQJ;>$gL+kf52ac;7E{;l zF<9A%D@QNz0(vmA08@=38L=@ljV!1v@DT!`mORzu2>5VM3-g`=(?9mvI3*|3Dh&x` z_K1?f5otreXa-c6U!KLqR+sh84QaU<{V?JSU^IdZ#EUZ%M1_4~wNeRCrKT6knO!KO z44wH@lcYIuG=q`swJVJRhKsyVdal{K)9ztK-~B!~H@?Ez=IR_dp-8K0qJU zPERxXcu~+tS(IZuSEcpj`#3343$5nD9_E4I`^cYZ>CWim>a>+a9BhdEAYUU|kg$3^ zFqBlWswvKq$W*`wDljojir?dlzmz=RDx;ph7WHUe<`1O|C%klfil`ENNj-Qp-8dx) znQYr-RsD#$ytpSagmZev((?=ZF=LNJ)G2J8bocOkfIaYgLx0ANHy33AL5=5kOJ*?m`xgWw!^=gI8mhucVXy?9%05-n~iu z)3j<%MnePCQGp^G<>l>hF!HEXatE*=)xYE}(Vsk5smA?oI(vQPQ@z36B(2Z|4y-Ig zl>rjqgE|X7x}b?HczA*ayZ@c@u^aF|p)y)*=7K9Bdx4K+Q;I77_VeYR+s^U_{rt1i z&&$OHmYdgUL1;WS#Y4>u0m&}VN87#h6DFYU;jX})g!_KElzZ*xoaiUd^vadDyJ`36 zkzGQadUt13MiOb&n`^*FSD44s_ru=0(`7OFIIEs;!fBGs|v>IO>(WNX!E++qawjU z5oX@42t{$2@<2fVz(OF91If=A!^}gzc%Wp_#?*Q=Wm!#woEUcn@X)qgy7dEvH1sJXP`+)emY%S{1*?-%{z_ zFR<`^%xE7uGL%iarZ4aGTNedh&$JpJ^*55o1H<$26LA-?$MYLU8(|MgjUp+rO)-}n zx>pXni12X%_UQV}0i}a9mXz0LAwo@FNLoUS*WiYA$gUx%OmoRXe6Q3_0|PLq()^$8 z?D+kM&y<&OrF__8(NyZjrMJgvaY{DT8FodUbkyA^c3k=4I%!{lF(5o|Dk?;D!SNW+ zimlwIYw{e7#~&|=FVSR@%#%veua{oGnvT%6wK!vxT2)yz*X)3-0Qd;kQI8czeuf^e z-hBL!kVir|(M~Ly7*At+uY`=6nmPlj&y&OE*X;iIGLuhN zQ6rK3=G>z%0v|NY#o)uMIP01y?&?V1)JMM85J+X(X7rIdc)29OKz)D&)oD`Or+%K% zhu$qRP9^R`>0X&P1->{++xT&n&~r_rF2Ivlvko=>Jh0A=U;Ub}Z1ic)YRto*+|^lWN8SKtFE=;-LUuIucu3a<$9FDM-0K->56K zqn84_W06Ne+I1W=`ncQ1UGh%at`E@1zaISS$>Xb2S+mEOz@;~vJJ05Ln|L2f&j*eV zd>;jW{4VsN?1l6N{3yJSQ@>Vm7gl$mhgcV-(98GFuT9(NZoa#gl9lwd!H3WWViM&^ zth3s{ScN9l1GekqZ=~-r#~%4}9(cK*!AF5tr+22qDyr^);wIZPfj#hip!EUx5ZCnK z;TX(ZkByZq`8|X^z#lV-)5x+-T+>@uyJ;QFugd=(OllkKpF9|F>uStW$`$aTbYFKs z8_TK9yIu8lJWp+wTV6sEhDs|rwp<=RE7S7j*J)A)e2_k)xu4C0ioSy9%>=LYLg1#G z9Sdj82N(&{L|kSS*dr~F)3ix=sep~oFf5;Ovb2)F6ZWtQo*WlZ?mNhAA&TTEaq#Lm zCwa^j8!Nns^^~$(e)}~+1g&NmffT-d5_!ZTyEH9==@Nc<_r4^*>_neISl^x5ZVXod zYin@!2{q!H3;%I$h=j?Udag z_6etdURbW^SrqUgXkqZd!bezsCGa6XRYD(^GJ-~FWnqD`lYM?Ecl0zY0ycqS7+NHT z2p4)E2>57 z(ixv-`{DN%d#qi-DF2?Z$FsTLL#_|d2jJsz;+l4SPJt6v(#n+jp0LNA8|6l2@xA(u=8Gp&^**#%E8I;1nH#a z3g^p|93PqBDXUACPM0(O<<)eyOI=KCod6%Cen|CI%JwxHt@>JSY=YyOrqaFj}Ng`1gSM7@l&X(b1(8^VyZR8B-OaNKU~+(xOEl2$HlZr*NCR6KU71aSV-A#;B!v zkjYrfphn@Z4W#2g&|0BIf;KBc6ha%+(u-@=Rf zYH9d!3w0CC{ZQ8$S8du*6WnIP3hx`)d9u+9epUPu_z2yXIeTOsB0}XZ;&!ztrw(d} zUBL%QdAcSd+z8#LFWpgF%*3AhwFpe#-oAT#9&`bH*zu9=$a+URfuRPbWO_f^V6Lm`E-hsb%U0$*mv553$3FJ3qhr_b8lIxDw@tu8lpgx#vSA^~3KG8BkOwa9$*t407{Z z)D?e6sRW>*79#__O@;(HqA?5GA?OS*q?2ns`1FyP#>4LT<7ZdoEND_gWe#F|emVQ2 zCvoe`0&S#8>1Mx&2Ov>NYZ;Y5sN%zn;;|&syXv^IbhP#2LSw%+74Wgkj*qI~#d@U^ zHu%VlkF(5bDLrwOUCRsb;TU*BG_RnlGVrQ)L|H74r}u9&^jJ7OF3w`vGoEE(S(+eJ zfgc|}zTefN)AMR;+6ViW2ad3ZEFES|_pMupuyQzhI*dbNoe>fZeWmoXnQgAPR+c6B7#o^QJmn{cC>|t8M+!(8d=-ilDeXp6pp7Fc@q>(T%UV!Z z$;D5aX)9JlR!@}gWcp2xFL^%X&27Pl@{HRKt{qU|qPd){C((>KOt|pKcj}uul=&WR z$m;hl6CRocvx~-$GYgYM={cj7Vg(0?>Hh~vTS-G5Vxit1A3gYqy0(B1;g9@@of>@z z4Mc?>C(n%ce)vJFcwtbGzp4cv=#lKdq@4?Y6UPW7ohR*3HHwLm}*u_#U5qmiVT{^uX38+@`ZlKAk&v9zFVQc678Vx~p?hZKP^Z zv`lURI`kpS&Y}tW$k?NwuM5;iF-Jv+QVQSKQTvami!xqFcM0s#FIKK%6oQ@E1ri}l zgH*~U2#KImN|7T4AJp3r{Q!>(9Lvl{75JcrbnVIE{_HkGWqsgkXIW)O_+hJ6+b(F4 zgFWN`A2N-dX(sxtxh79et_4Yr`>1x-`;rU|7F_`!R})yWk{62>R?hfEa(t9PQ9>WZ zr4iW+>;enUtyP;msVZ!4@SzD^?)zotdSvLKwUT%9H*CLOgT;hjCKj<8ExZYSynZ_* z_>n_X7UyCf^x}euES1KoEZ0q>*7J%nE|w{Tx|)IyU6u{-AkgiRoL1OK4_T>bUq3_MLu=i7E@nh4@Q=h6Ifk5B9*`#-h6WTP(ce{6}iu#5AmB` zK938W&7E|ylg})UuVPp}hf&Q~NWs>C_n=WXU(L%NEc{KI*H`TK*zbd^PbcvAW>_9C z>+Gqk_NXi&2T=>6f4IuzB!LU?;pgLQXL16BCx=STBW&PKXYheu2THaSlQaa4ZI&md z?B{LcgIMV}jpVtNIRGDlUWj2Ux<}cG-VsNiFOP~W3QU~{Y|KdIMkcMPA`1V*;KLb0 z2A>BQxqpb$O)P*FWs46S^%;#~zy~FH!f^xNbX@9+i)lkoZOUON_?9?-%6UQQV~1{f zH#{Gy#K@0Nze=iJfDg$Oc6neXy^n{_Ae;();Q5%sj~0E{lcwQ%l+eecJLh)-eVm~$ zR%AuN9s(a3e*EUAM22yyrj0HV0r`z#;0)}DC`Zgf3#14XZPr`L82@twd;`BS*50x9h#4gBNM4)TiiKw%;; zkhY1FI-!sE+vT7@k&4>l6Q{bSc4E;q=CvBcRT8h5xjDD?XF-o-lQfq7bkYl=E!gh= znGI6dojLgOJW)T^xzU~Q2f-1kcjU|`;G^7vWDzX0*FarJ=rw9HFO_-yK;T38N_%i$ zZmi9Rp8!6x$tCV$xh%!|z(-&Gz!#U)zZiUw`O{@XKE{(SRYtl4&u3+YKiv$kuN-F9 zDeF6i7eojk`96l^+tC<-C*@urMcrQ3)~)rT>b~}!L!&7in@}#A3vwem#ZbrVU<{1`32Hy zR*JuXEo!X8||_zgg2uuK$KtreEb(- z7cZ%Rj~Oe-67Zo3*FMW3fzQJ!`iIH%;_%Arlo^x#c`z@O#18Wl!ZZush=f6Q ztHFnLDXh?K-Q2jv=_4vHR#NDa;p?|?=t&2Yk#}4LmLsQ4MT87Q2)j!fj4l0s@L^(+ zmSIgiL2D`XjzZA1vbNAq>%u&@nkn7c;p{XYBu=yS(9zt%EL0jaI&od>!_8*Eg=7Hq z3;mdApo(-`;fQ|8&&!C#x82TXN4>rfj_tulvg!yeH_1?B>idB4F-0F~JAQm5_Pzwd z>&h9=N#a(Q|9w+!ca(LqW(fJM0GOdoj3I)ld#rp0)6Z*)+kAyzpdyIG&pV>0{ zxOG1X!1wZ?U*Ph{Z&lvzD1T-L4%XritX~)G@z;|8AL(<7Jb)kRvc&hey%@4eVHF%v zPXl}W^@kt6ZyX<>k1)GFp8iqTqt4c#n2bFt@@U`(Q5Uese7(|GTUZq;z-kx$9w%HS zH&_=3@X-*T=8b$864y49nBb~fV{oq7xF*0Z3G|SzcAHW=(+v z%~~k3sYLoR7|dfjE1jXbTF9K`Rt85>5GZIDH+gihv$_dBQ<+Dr99PgXQIA(PogDzz+CW z66+5a8oOQ?o6;1_rrvD$alA^nD80YVNnHaheR)iWy^``=N;EOGJ_()KoU~8YSX*;p z4tLVQOx+SrPT*rsrfc{I8dba8qOGhJq=veZ#u4h7Al@UZkr@>(A!R1mJXKqu@7>*D z_||L}%h$OSn99p^DgzU-5#GM%TJpP4Jkm-l1-BS{z(h-iK(H>+=UZI52&lv8%tppO zURM3Pn*eqh;KQI5d@&ObRsDtkZ`5HmvZBo@`@c?WRI64MS0~2kVj~r5j6T2~P(EZ2 zlRbX=-OcqHq6Ver=0`>!6UK+Yhs~tSJLkWie?ABV*!$rq>EihQuXlt#&S0EM+DnG- zBT-I&`2Mrs+`k#3URZ#R{85dEIv962)+~iM};_kGy*P zayqP3s1_?ww6q%&f*PV``ppmPhY!E8QZSH*ya0S~QB&|iMGgH(-~&Iecy6e3kz?3` zkN+ms7WH_S9aiRTsBuuB64UF4V(W}P4nI-2Bvp;-&x?L9H(?(kpSU?H})BuO#7EKBF5i2FE z#)r_nh-X-a)zs{m*~*(4(n?D7J>1(dU%{Be*hepn3T~nL3O~}|17X(2^Wjat{$6!A z0U!Alnp40u0v`&SbuI{`uh#S7*o2yAqSqX$$+Y`yng`Rz6xV2T=%+kJZDUZhn%tjJ zK8@KXu>U6VrMkZgdQZ>{It*?cAE$O1>-D8Z9FD(G$U{Y&S>|x8UkDvaS>%jHV z{gDUi`;zBUz+r^Y=n7JP*4DkMRdv&AWgG=K>6pEgKIYa?|(~Oxug6-TzjM_E@ACNG1 z!N*~MkHx||Vy;=oLA~TUE+a4!Gw=RX+mC{ex%9n7IE7~+nk)NvY^L3EWV5Cg{BSAr zKB&U8uj=rj#5NLo-I(`LaX*J=pt`xa9p!|yA`$T-DL4*P#$IahWs12R>Mdvye# z9Ha5vI*>v~Z41MS4Q941j3LOEW|da(VYx?J-6W|=Ud4jfpI#u32C>0kLuH6 z^2%R;kFLeJBwJYn65kGKu6?UREiNsF=!fM?O)P5DwfAY6QY>1is}++qXC>QiYMb>~ zYgk}7`l7f#b}G9Nb;;l(*-zixoUK=-A;P5Bl8RnzkM2If^8xe__5gfj?D6Q=NAi6b zEi@d_#R;7W+Mx+b^gkx7Xx~ zsp#W}d*|N_o1;F(IRw4cwnaQ+JKR=1mlJ(hU5qr_QQ+m-9~XUwNXGKhMgph*rY@?N z2CgZhon47#PzHXwprZ9r)`5%ysH-K$DK6;Hz{2doLC28t{thvFboQRV+dG#yfN_b{?oi4BNLKF4H*FAZZdb{Dr{S1-6rG zTRk`X@rp>0DfaT=Z6co1548-Bq5-f$W|4G=tcv5pu~f*B4p~AS!JH4k2WPn#d{BLe zlWCO{Z0#P{qBHxzhcACW;Z&ERBtd8|6t-bI=rM%yR=K#0K1%-(_`vkuKrE$Eeb_8c zyQMZSv5E0!TIS`MXS7baq$4uE+@w*v6jk-%&0#`BfDgKL^H5yh%=akpe;BM47uZ4C zqZo65CKMziV%U!0lgyMhdmo%PEmY#L3*gdw8bAcMpoSFyA0P?9G8rX4SbG3f3~C~@ zjpxJpGTFEx(~8dqAIQur@t5$FfKnA1;&p%zSIQEN1n~eas|S3vj@~AO0xqVE&d7Wi z{y^{HHJ+V_$5XG|=9@X=o)Tt5vVCUo5&ouxKBRFv(N=e&ZH68Re569}PjBZ`tA6JF zJ#5jV2S*RJs7|9UU=M?jj6VLE&eh*GEDKpWS-)`7rin zv|*Oh;{-v{*Kz(hJw7TAupRnGj=AI-`q|9&;O(t&n!Z$Bzi7bU`)08zIkwyd*U-<{ zBa>bdnAsIKePZO{2T#6RtR$&!zEt4&j6J?H_L!g#Q$8Zk<;&~CVrgoTbLkHZKI~;I z*qROmxRvycH!;GQpa_pwG$Y4dT9qkHJ>%cX=>_hvRMms#rrp8do^>qD%Mq% z-hjir4K)zigqH=&$9m=K4p;FEwk@UCk69q*l#ra^w zf(rIXcq<{6~_VFT0#REP>7Tq4-|5niBiJ`}&yo<0$LLbTQ{Ca+4 zi^hhxLivafj_=<&JJ~NR3ge^lJ~H}va$^8YOuZe)$ATW%jt`^(AX!sA*K;XJw#guy z`gbgWkD|zW@Ai6mWB`MV?5gOR-uWTplfs&{=L2~$>`76F{jRS?^!r-fvScp_dn8;K z=;IrBA1&vjV2{qM0{U7WA{r%V{;I0l)G8N~JT4OUqnnjg9&O|{+QEweA4)*$%SdsD zl-3SfA4LdZn#oc5oga#yELzuR=@=+M&O&fQ2(P+Zd$Y5eYoQdf9>{725aRF~fe%Ee zcT;S|%PTG#SKXRr6CYB@&j3VfvS_|5xt|KKfuSdeVybd@?Kd=$=0bW#2d}2)#Hp?7OEc&s}{Gpi@C^g3qHVFdkLot+cbGXo@}}F z$KWFi-tOmo=$bDE9|f=%h8qM&X^M(NIQ2}oEE6jm9uKF#ly*K$c6ryh(!vgTzfC6? zRptWN`TZpuGi^pafzkT971VYrmp^oiT=nkC$friTPf&H{dn^j`XW12XR4?VVwya|B|M2A&Ld~y`7mT=xh5;8oNyqS){CbT#uu#(pCc?(^49DO z&cK&Ml%~8?2X}kq40dnq@Q;Ly3O7TBxKg-~Ofnve+!4sZ(Nw~s1$}@$WYeh2W1)|u zMX6U|$N*V%xOxBEl0|BpdOpngkUcv8?RKNNc4FK0!yKsqeM}=R_&&bZccBmL)Df5C z)BI6^$N0f609h@Q-{VHY9`zj>zG(z|8WZ-ocjs=#9y)+DNn_GE%Gg6KaFRa@_K?~0 zfeCx8${~u?l*`mTRtbCjJ>MIk2iT)hPD`FkU=M(1?f4PFq~JiL$udn<&~0<)icG8; zjdfn7gRX2ns$5Xr=xb)6zb`#xv^_DdNL5 zvo6dPq|MN0$hvLHH*_G!?V$*Hse*TLGDg@Zmy+XSnbc780;#RH<5-jG-m_k@XhH?J zaLX*e*uMSwvhyTg8T?|}!UXbeWa=xrpLl&IX9%SX*GEkj9c?60Uy%0m|psRg;Vhd?ekHUcdsy0iAl@* zvN0=F>l6A=b++9g8SGB^&pvs-Ey24DV)kON>oG9||B-f;)qHp}UTWu#8p7LG>0Jcu z=@$BhkW04Q93M^>$E#KG1!|?@YB`76m8}Iks+;I)&fucw=9BM^hFBjhz^P<_b)st|^kJL2K6cQ@ zdG>v5R<-IZw%)Gq3Vlq#hnODm!%Ac2$Jvt`i=);8dI)CdJH}IlV6?LiUDM=E$%eM6 ze#_6IbXqtc8GAfDS{|pM5^*GMANfS9;X2r3 z?D+tEsHXn)Asr#Cf{%i+iN?mkrISlqxI`S=Aa*r4_2!`>^cYo&+{Jx>S`;_RU6^%N z!Iw3sfv-Y&Xfld*>qc=38PJCN9cX&}3Oyh3Yn*bXV=^1^9Az=4Z{Cm+Qd z{L6nqL5&N${O;ATSa+!*lr`enmSDF)mJDFmh#lnLa4{j{xF3A9=dcStD$Bz;1Ik%2 z;27P-u~QPknO@i zs^san)IOcw8!xf}N2r$o_(-TGV~<^#lXmDi)9gwbdZ)utnWDub(@3ISCo-W6r;^r2 zY5XK&3|WK(+AJFftzEo>+Ltgu$0%KjdIrE9(Mj7j=)j@aME<{?GS?y?u>gED*d!j( z+vN<7%((Rs>w*{)i?r;8%2hxJ1RUM>u|@JN+j&Yoq~DJFi0 zAjYZC#`EKw=}X@XK!6_t52xE3&!q3+_krz^-^a*<(sF0_9v^oT?BV7R_DD^T#aabF z?E4_>B4t?dJ?1M{mJJJ9?{M>*yXmG7bh(Ig`qj0JU#vO|_r5col#&IVR}1rqa2yK8 zI}cUxm|_8BWI0zf7z`{m@}Ks0n@HUwYVk|c#vbrA6AmBH4V`2n#t*qZjwJZ0XiHvi z7WVk+`XJ3#K}5kEebaN5jYWjBu2$_7uv4@U zKwl2s`w5RjB?=DN8Fcl1%5!bBR4-KU_&D^~`Mc|W8KP=#LFj5*IR zlgO37k#tn4kFppetwn$|MK61k8XrtX8JuK ze9h%WII?IO^h5-#WWG)4!x(#iDMesxPMTUT?Ohi2)LF|6M8P;4>YoJhYKCzYo67Z( zH$~eIZ82H<5I0Q9zR8;J0z&f=7Ob(tAT@B4BlVbNePm*(vb~WD35u>U0@64_xVl(8 zxx2dGEzlfg^46_8(PREER(D>FShGv+3e`=)#}3I}Wsd@JUV?;Q$B_WDoDaX6_6LK&Lee8|92zrS0VcthZAHScZyfX? z*XqkrVIE$C}LP_wh4O_ z=#g0;LLaT?<7-Qte*K4Qy=kxWF_qlq<(%ILMGd^m>Rahs&GdqY(O6gd;E|=;*QiX` zXb|XAkD{gu@=~utijCaTl7IF&Ud_zzio}tRtr6-hHBKEw!7QY*J+a+OB6uie>ML5 zzX{Te`4*QB-&`$gP)9_&EH&QpG168Q!8W!=Se=G!rsdBo($PHF;FehfK1KwJibhoP(pRT#3|q%p(UVl`uN7a56}mm4}2eg?1ye%+MXk24`aW6u)3SYJo6{mV?;O==Ttc_ zzy9;r-}fS4Op;`e`{Rc>nKdybaDRY0MlO(2UqAakK40I&q0vGQqmJkLhT;B@CG2sl z@I5|m=9)gfzBtNYL*v{YucS@YV2|=4&qw+ixjuwGk|pfXucTw)nO$b=f#ZXG7Ye%w zdt6_XqISs|mzNQ+)vi!Op6cX!uS%#zSz`o_3G<=WyA=2cYLtf{xi&T7ew-hlmz`4l zbx2wtbq_}N=RU0uYaE4Y0ZDiO?xicjRlzA66cE6F?`x`n#U`*-w)P=zYJZ0xj08bd z6J0qum|e+k(rDya?~*iasl8dW$2QReUf}fjPq78(v(t{vnz9#?0H-GS1Y~u1`Soc| zxm|`Lg5~Q%%h&ieTg#_`ED0$RD^$qk)bla6J*l=`sColFVqxpNhT%=ewWRJm1|KNp ze;j^fW>*1n`O2hXM7XIqE*S zt!68I9bwyb#vbZkT()cneH6ck>il;itLq0V8bK-RWXRMzMm7%7uj#!zN;5G2nVcWOD$yGrXyrHGu5|IX~aH`}~iQ2Byfd(8+ASAdz6cC1 z@qvr)>6fhhEkcV!u3bm5;|>Z=BW=XCZl}t-Uop}7P*1=b@G-4wTerPS5}4%qhfQA| zS2sw%udv)lQf;Z9Vw6+$lu&-$eOUWJUqw-OUfLUPG^&XSiHLa2bWW9*4=OVTt0T$tv*s7w) z97&*bTWOe;>W3424L_B7%VR|mdBNRmt7T$+P{fp3uw8nx)`ylJqo`4g7FT7PVMqjI z1U{xb1xhx>kP&us7U-}>;{(IhV085J^9Kr!m$(~b|q|zK6osT4#r!v92e#9jeG%->lYBYf{*l_P6OW~ijIp49}vNA zi7Dsf%C1*t>iLK_p&qJ(DtPlfjgnwvw)GD9ptoJ9a7vboNUn0auzlnmM-#4?3L$-& z-m>L=OtA;uzpVV}QAQs*o|}(ShO1gw3`i73I~)h1^l`=UP3NV&Ev0Qy9Z|LeR}Y1! z3-(BWzl%HNdwh_gzxM4C+K!;UZ#WERw!J&C$vN8+@#n8`M&%to*O zR9OXl&b+jU&a>|iD0{C!M=DCZ9 zyEqjVXI7Mxq}e`Ano}RsFKlnjJB3_fM>UH0!DuD@#SldU%fGmB1G|xWgc=L~jDOsJ z)u`0{0MWIKaMv75LwHzxxtDQj>;e2ptkZ30@0GwuvDN%&yOQtYTibreM*$!5eH={# zF9IN&
    )Wq}*m4j8z1p3n!d!k&)j1{}|?rO*5=es>I}gl3L6pI2?MkJ*Xr?EcN| z8kyi?`O$ne2zwOE1$t9}CLoA%fF`bwC%5~yP<5c{S)V>K_V|0c3AbfH5224__&uEG zf?%+J!zGA-uj?m@0aBS59w+DxH~oEv>qGua1ZuqS9AG*Pg-S8YaKXP#N7)fIrTjU~h^0RpfN%%` zGCU*OjeO;b?^*Dp>j+&n1u!&iw*uHw;5PX1!pI5{=wrXgSli5d!Y+u2&dBffTuKC* z9;t7stL_0GACp&4*2NKnBk8$0-l=O@cz8XCt!JszlCeFctE}ZzxY9`!t>DgrK8^}v z=)BnC5%th2O%RQNwULH!n}`Fk&eR%3e(?ElpIdRUz#b(?wP=>l0=?wpvIcrf_C_h3 z?fWDV#nda$B^}g{wnVr|sNGM`Gr39=fuzLFRwLM)iK2epY>EbqKEAwp z?YcuN#vJ)8VUB9o^GjrKK#o@#dq}|aqb9wud-so1KosQRWhL`HZfA{nS-Sov-?mh{ z3A69x$?Y{fQLyMd>w6Tx$K8TH{%+z2o{tPaj6DXC+fCP=fDerxnLTf#?%nthM?#>y zzGrMxB{9liYvbYxm}A5c^PvgIRu{@rt`Fssc{e;47B>7?Kq=NCOjO&b`0iEJ)3cjS z-~-61=9J8u{x~j`_3yz4C%2#T5yzUW7tFTQ{%ApWPi>d~9DFP+5oZH@u%7MIL>@nq zi+q`w%Wq%i5F_#}7`GwF&AGX?_>+2HFIaC2`0&X|^h-vGXGQe7Rl*+Sz4x+z=uP=U zakd<0vtph=f_y*9dDZq^LV8-PSjcvALfF;dDeb3;uiXVP9s6Wu&4bVl(@(i1WKPus z^O#oJX1UpVpKeh&l|}!xkC<$inS)Sb{YsBr>4S=rcp0~Y0px?fs`KIwUry7GjE#vp zGHy}<57-^i1TIQGI+#+Z6_02fdq?a;>c5M*j4 z;POs*xfs5H@j+d=an$8;wrAfQ4^@_YIj?z4DKBwIG9449DIy=O>!S#*XWvIJm5pgx z+F||olaud10zJgQ$Xe&=^WL{#UQg&kphKU@uGyY{TE6E`|1lyn&)2`tevjY$XI9io z&mJf2vB-Dc6M?K?k6+Kv?^N`0rjH1`WLP%F9(NN}H|u-Mm7mphm6$$UzkNTjhkYM7 zKk$4M?6K6Ex6~b_+PwChvsT&EVL7Bg6w{uD2FLn8*(}02epO!`bMvYR#FDN&2hYLg zO2skc3s&wQA$W`^LUMg9ORaegoH(?O+UaGS7r-@bbP=JhW>zkK&1s+i#(*&D?1gI3J_P|M*a8&d1= zFzu+#GqF6``J(WMlt#D+e3+v{ zj84P~2kV3CLWI(Jt)7jevqx>@%w1MkjSgF6><+ot49`j!5*$&?lp=Uu$^KN`ETG35d4^oV*PN>GCEugO4Pq_H0Y=YQ(9y< zN$efzb@6WIdr&!O1lJILc!!2$WB;DJI}6>>JtFWBRs=jV^kQ&zFf)Q?+=ytKrRXFohV zTCB_MW)`s%>H1w^kFn?DHZo%(ef;t3>x+T`S!;vdWL-dh*UsCK7KlG^zF=?qv9U)$ zVN$i!0|h>EAJwzv7qk3I?km;f59}O7z5Hq_WD+u`Y(!g&^usKpF$`MzriF~a*rbCk zRiR~^{)^j|oc%ajqbF~{p9DUX1S+1O7YNp>D6xN-9Un&)%L|e~qf}(Eu}=JM1CP1) z4*du89M z)+||i%!)3tlR6&4$waz>MwzgOhuOvaWd#v)ht6R{tq+~czX!N6?h}v4`~a~+J_Ek88VB$#4X?+C4r80u8A*13tQmMn=cP5#n?F zueNz{-Ecn4@+1MDbQ|k4x-4*;(_^!4fUWNZMnd8hMWY591aVdEra2sTs(CVoKIZqT z8ub{TU|=@_;24u1jVY@S8WNDwAy>2P``Gn-2zY=!o<4p0Bdd_Jw)ksXRcAk5ORG(stV;VvRgMQ4d!#E&=D168dz`_60ezID z&@TwHw5eLvd+p_1 z6pxHaz?$lWdX^bigP#O?hD{|)0}(c%^`WJQJ=xgo`dDt9Zvl+Q2tD!^j0zSgEMz`n zFfu84Jf`V4IX*5me9dt>YOn*dBKEPn0<~*=8@d>Ei%_B@Ft7TT8Bb;G@d8pPhD{tF zAdf5We*WgmZ zRvfV;rD93JcWibs_~6a=fe#S1`!#O$oxL~JU-BtmOgO!Kp~9&!wUTsD35G?bV(Cn+ zfDapGf`mQCSE$(0HdbpP-Iwwe8lqz>H)|M{fq^;p&w) zezowY^Ws*itXw5sdj|O6Ja_=}bdsA>X^CSpz|@>V>_4JG+J@MiQzu(+Kgn+iDke(i&^Tb7ksd=QuFqjhgDV*ZtxR^5+ zj4t0w>ihT0Szmk~7xZ7 zKRr#$WF>n$P`stUj^94dpZZ|{BA=h))l`0U^1xfJXHQj(Rk-X`pkuvLa0 z1YXjIIH!ucG@+MoA0H3PmM+$HCHrKx%6yNyL|oK*Vn`~tt4v%^laj2 zdc&yB-8I#jf;9wD34V|}Yl!P&hVD!s=2}zLRtK){A`*mw3w7Hz+4TV%a=-BOp%Y#< z9ZCRBDuHAL+e(O{h3(_kT zhj<^B8ufx+!a2qFQ9~|99wP)|lITgK#@zbJ=;L|89@jGZkbSNn`3VJIWH-Mo*aNSJ zjfcEr7Aj5H<9f-1Gvjt?@FBm)Bl$hBvwNa^IOWB>(kkY0&OmP9|vYvkoHhj^^M2TXCX z0oOkaW`txMCF8|}xHp?M%bY6Lb7{e_+SgG}CcSJ)M1_jd6nRG0$giNxtTjHm#L@eJ zsu(stvF!K=f55E338f)M=D+gvl2vax(`=@?34Ej$I5e%bv3lg zHQO-cWA{St*`!1iJ7yO;J584UWylVYPcC1olHZf0PYkh;{PkwY&Xn9XOE{2Pd)R-s ztBm?0!l=;IlJ%3Sw!120fDd#&7M0x{(oasyly{$+!fiF3{BPu)oDrfbSgYlFDfCec>;bgI2cdM=PFG!seNG}DC7gzbgA~q%7gDtAP6Kf_H-}f|NdY0})*9r_yBrL3BR|hE&z} ziZ%G9Z^_fRZoR1sGs+OFA{reQjkU+d^e1CFotF@T7%owH!zwmZ5_ZZh(SM=#xcB3FaI$Xe{z$_j^F4$; z2)v9rA5M6=Hh9Tx#+pjM#VAo%nm8i$JoleE09qB=pl3{?elb--wZgO8*Gcdu7|V?v zcqKum7888!Vkvt7$RS!Ekx{~kfSO{h04#upgG0$g%EI*mI$|6ZSWq=So+nhazX%FW z>J*H4pcO)kY^laEgJFqalFa;oIF)=wISJF8+h$eRk9bOZ9HwYXLLS-UadmTbkmas3 zU)hAhFyoPKlkmrbfjNA8Ny``>tjT+@?&)tjqW3(^+ z@4?5^^Pv{@JkRRI>ePhCr=E||5`2-)hXcyw8tO4ufq-K(5Dwr*X@r*M-<)1;iz!~n z>2YzD*V!{DrBkhj3^SHtnR%Fa9p`qe4Oc&05>Vb>rx0zi$f@p}UOde(E)Q!Jow~;@ z3DBTRVxaVSY|&_QfKFQHjT6-H%va(WX2$^;Z&Tk)OFRfG$K{0xkC7ip07O9tQL>Qe zm{1(3sGp9l!Hzj52OF0&l%Y&IDyq+dEpw@soq(P;JQ76@XNDWfuWW@C%T|;ylkX^i zs(xSiT6r_VLoj&B0@|sbKWp;7_c|h}%U79V!wpy;6t*2i9g_+vYP6NU`eopo|O_s3Sr=VP{XTEdqO}(!6?!`5x)|@>jmteF-nv`Mn<#*R*U8 z)PNFVE*&&skH^{HgzMw)78)CIKE6rVBeHbK)C#X7BvUfo;XopA<3G92(?d*$@NeTZ zTVrwYOJ#@(%B=HC5$X_3l_GGsU2=5erL;cw#5ag;dB#uUu+Nu79NV>0xqu zyndS;7BUz!8Gm%IKD@k=bT?`D3kkPHzx|HwjA}o3SsGTFqv7kifkX zsd%@EP5B-jBihR-mo2ZkTHG5RH-DS~L|`9iZ%KQ;!`j(R$*2|6YF-_=wg)yRv=>|i zf1F%A&Vj@js-P4b%h>Blb3Sx8n_9E(5+ZtdzCGxu_-sN@)k0ElZF))Hm(*E&7GZrP zvUoe#Pm^EqH0OUS=!3MFTHKIQ+Qn!L;?5kamrQDvBXR@_H#Py5f^txz=P#r)Rs|SN zA6He-@*tgdkt#R*c7I{p$0P8O>apHS=wl-vXjnS7in?AsD(K@|;D@mXiM9eD$*WZgxJ9 z){x=)!^Z{ifj)43Ot8mtRef-U{3-AezDhfUC#eW|n(AlM8jIlS@ul0DHl|E>CH@vP+fI1Wjaav6l(ebx+uk;)M( zgKQd|B0B#;~*+s%-(ayN_C>DQbYRN_F%=n%5 z1AqiQetwgj9-C7k53om9j#w8v#!_nu;%1ba>xCu!@%F>Z!^_d|7rrkjAa9J*?tK%f z5axR*p(SM2a|dfPFa3DdDb`&&r@;rF4}>@VE#b5lDl+eMQJ_Hyo8yn)Q5q=g)`gr8 zzD-kY;b|LAI+L}}15WXP%73st_-LI#WU>>-Y5P8*54X5L4<{lc(Di0)1p^KFw~@*iLc#d72@P?SqDAR!L_G}sQ+?=FnynGMAqvv~6yBxV%~-N? ziKFc7`Di_v`UtpExiyiGPVy1pL*rEFe{DvdHh2kUwrZT zKgxsry?~MI{{i~x@W!a|SoabKTAI}xCXyI)fsX*E znncvG$BtAhN|*0dAeA{Gjt2K)T=mXcA8GY@>$n3MFD>2iu*3kVKvusaK5UQHl7Y2F zQMR_k*2t5{t0GU|URugwV~s4D9UoT?F9IJ%ABV~Du^a{!o|%FVaX*lPs(3%jge!_P zyt*uHv2433h11VWD*e#AhXgb81K5`e1nT$t5v9xKv>e8%Q$?oJd`z!abFs zpO`%z1Ti}O+hSX=2hOdQ=OQD)CdW2|@I;mis=`n!A!C5M6p3*OhgxM49x_&U-e!nF zmEoTWqV0x<)!8UvnT+^KoC|9oWD%b{!5LC&_erAxKBmEk_8gnM5afPv{y9eI{s4qf zt2)$8-m$^Q5*ob>kEtGpAz#FNix4$YW@ALrK@Ah83AA{Rr+LStB3;eDHJ9Gb?tZCf zC4AwmAzqz2g|KGZ-zLt-U5dL*a$Sr*o;*8$`suJ-rn5C#s1l{eo0RjCSs%n*NVGKo z$zQVbgg&;*RnBkh03WM-r0(X^vjjejJ~AHItAb8K?%5Atf0~^h#v1vX9{HoVKz^J2 z9%ts7p7;~!p=@5gqlC;-?fx6voYd3)OU7aE!HK!a=-z`0~x^c6lmMvzRZC)OWMk zw~7own~(3loA=>IiTv@)iv&M7g&n{%s*HQ({q`sqJZnkjUZc92wl^xi)q;;&bG-P> zF908)fqh{Y^r^$QWEGB?xrOH70eQ<*ydQjEfR6_byA&I-4Qur}jG3G96L~#YJ`36D zZ1ct$+}vr|2`iutz~3 zPi|z-e?LcJ-S}f5;A>r8E`joTv6DvRsu_G z1vD|VY1O!GO2C2I1UPU`PD_0t0g{wB&Hw)`otgXYe6u5|?dikDvMsN6SF<~J?z`{4 zKa7%T#DdEW;4<&=_4Rd@d!RNYME~fYGEgt?&W$~~?$g`Pp1i2gBmLV&9|9l2d!!HQ z#pF*DiC5FojsDr|{YVzEL_@klM$v^WmWcMXzSgyLep zx6>%!)G(Tf6GiO>^;vbog6d!;-%H?GTW0BoAGVxL7qTAg*;ky;Y$9hbm zX)$8J2b(~RF0dwL$!2`>?FkU4n;Cd04&dg^kMG}XT~aFoPT{)fKA>PGNYFqm4WQF| z+s#kkW%OZ`wF5l(L4F&O>|-7EKt5cY)g43mv8A5?Lzf*40w2BRgO@*~`QXxXnN9FH z&^6yG*Z*#^Ef)5(YwPovbJSbbmo!6QWeKx=$7BbcwH}BKX>0~E8f`7g$U4*@yf=UGNKP-hnEwX!A>sq_0VfEg5 z-}pmg%1N5momA?s<-%2MKy;ext{u`7`dbwMpCAM6*_aGVQnUZfxER~if=fW+MomvC z1Gibl3z@`8)6mUZ72@y;M71-^#kJr6u$|wtzg}{*NK3ysybi4$bBzS$r=Hi#_ zoA)29le)hEJ_yxfUK}l?3!sHdQ|N-xx2RM?;7}f&E%>i9s6FN4`9b$&4*`_cp$Jdr}9%VS@lh{b(BPkjFRY7=tFP%9`I3`3{!oS(8qWh z)zb~QQ~0aqPNO3U0$0cDbyBz9KuvWRd>DJ&$yy+#_hlj?@F7>X^7W{!ZD2l*hPa}= z-tin|f)nx$Ay)dLZt&cL&{C+-BAg%qcM+5B^2kpd6MbaJB5jta=kiWUDuzjOV+mcCPYdV1oioEj&C(hUYWXEV} zmp3^n7IL=BdGwA!YShSBsS7xIKj`b|$J~D=j4&tL^xb0o?K#yhf*w8gfcsdj6TDgw z9 zLLNW-=C^--c~u0gO`tL5KVy$)&#u1t-FCr>BM(A(C$CE%TaX8N7vm4e4{1&Bj_cxz zI)wRy)k|Z_xx9F8*ik;)f?FzH&c4j~u8?ai$i`Wz?3EwH+QjI;`3f%J83x_Q%NW59 z<}Hz|X3%_RrGI535?ex%61Mjr%7ic$>LZw87W~9X_#W8(h|T~49q1V#X_3IyDH+fM z?l9VN0y1K~{n=B%o(ZDs^*`?eo!LOQIwEwT!(zTIf)7m&`=M!Z)%x}w=TC0E&y!S^xp>y2ci zki3LDL$xOy27$}Mez-8w%om0FyIuE!J0cMGJ9B)SL}H&o1QhV}yFx=a;|eO_Q66?8#e6hHf*$$B zzCHtP5Fn60zkD1LRs)X*QOFxP7i?6^#-Cli{M~k~Gex;nh8`Jv{CNGS2IvF!1N?EF zu*WCc^<40>MiB=my~mSR`AqMpKF%ON&hAE?3s{=L5x~Q@Jcb8BW(2u+^9#uQ&}k48 zyiID+SHC?q{&IDd7THvRss%U+lUTZN+E1|~6~^$4X+>uv)54h*RWIf#0w2aKJL@QV-FB-F=mq$N zf{Z*)Ko*`ZqZPQphte(sX&2A?)%5)TS#+w{hSX)t|+ z_SDbJdlUH>GUP73D!G^0QU(jcs0f3VSt37~{)Ag4+w#-7wM;BxdAg!q-x(G0PE`vy zRVjztgyQ%pqmLAOh!0~AqmRe0?rt}WDC~2Wmodk%ooDoMZNW!Re0ZMDzrQZJk3WtA z9DUrm|2pY2vO;6O@i{ge!X6prwCLlj_)1(qy2>Re<&R)MG8D<%!o@5{RSv+*k(mQjbJFM1L2@i_Ay+&G33g%eEJ<9Wdzpbv2$SdH21^sf9pWUR=T^+siu zC9nUW7o7x*r-pz3vew+vkR~< zp_L%B9i(`eiH6N76_=8)7`#s!mzj3u&e)gx>Ps}6HU$#>?JrVS7cvk%_K@AiTM83B z-xEVPK9bdp5#!W6NuDX-*NFTCX4(`7z{8Z@3ESUlIS3_cDBPC4m^!G~=b z)qB)O8P-)M0!UIHsCMDy4uB6K`TU?&OcI9gE-zf_Nuh&sNB!!Ex3INb&b*wQ;BG>B zxr4($Nd?aHi{f%4-&z321crb_BDwSC5FEmeWB?vOVA%iy`7ZbQlN>%IuZX*M5aS*TJsHwFU2Snjwcgn35K@!{r|CF# zqjcMPdNr#VWN1Dj2H*WbJUIC_{-F(?>RrgYI+Bjz=^eX{d+=esZ1j@jK9(PMx~^ik zq~^CdzXHZ04^w_tmGHtV;WI)&Veoy!y_&s(4csx2=5dQ870u`^m)iEON?oXQ5&D4p zc-^88Zy4;6xsUbvqsJ&d1V8*QeG{{_fBoZi>T!DyuXQ<|rY{$l_fpNvuN7|omPMv= z=x|&G_$V)QozTY@1$Uff_))^pp2P1EM(Mz>T2>wfBa`2pW?`4cc%<#TzwPN}bNbHA6iGGb2y z{}eZFeJD6+-bP6F>_$DypMHCXNgAk@+8*y{J_uyC9r!Tpw8@y+2_Qk=bkO(IUFM^k zkPrBL454YJ!h!K43n+e~dW+Cj+tp=~9`hJWeOr?6s70sn5gqtY^TLEamZwGI!y>wm z_Qz%KHHN26YzWd?8AiW#S_>hD3DnRiQlUBwd>5|^1*35eNFeM>hQVoDVBra0=tBYc z@LQ;j>SOA`=}I8K1rAfY>`wze2Fh>s;Ek*VCS;AVy=Ad@q*R$mB3JvX(B!&lIQ%i4_#)PC#*ro0kPm5v&)rS3_ zObihG4Bs;So-6`=^wN`MOHYjA_R3FC-h;?qu`G6@s+-R8K^+mBYhCX-NUWsY=8RsvpB6 z7A->7K(0&QUoQ5!RkrSHfdfbnJ`kMt%m;Cp`M^O$NSm8o4i1~C$DjWNeEg@za`gmL z3d+?mnJcP)t*4aEBHJAm)o}%!M|1BA4_Ey?Mm0sI6L%leQWL06X3r+D@348hm&v7Cy562Qy!cGYAk|1wGVCi*0eT zBdSNHmg-(c31hTI2DP7@QyJb&Bff#k&X4sE>Cvony~Yo%Ks^7@rz`?jwP@WlMQ%_= zvDv8j0=jrfNb;*~$ZRTH=;M>zVx&M1p%36kTX6gGWh&p;4y#ohtftePmrs-PczXVI zAP;@<2LbrVPV0YOfA*Qc2aR4f!?4+&CiIbIA6;{Out)G7=_7~G$5+95y!-0x-I*f& z@Kt_&&m0btInBrNxj?X@1^62^lpV1 zyexHJ>_b_>N&}%B#GN!9G7TT-d4BR?8@3}ueh+N46gzSp8K1$N0Jl}Ok6CO=rOSTs z(H?cOH2o?0nGVc59nm@aO&+ z@aOD1bM@356vGgi0%rgnBfvIp_?q4e*%>y~EWDT)kaT z7Xf7K9Xg%7uxD|N9x0dpu0-D^5 zs4^de_2fuvs|!0o+P2?u20kv=3fow6RLK2jf9XI{<)JW8Aif27Y}zP=8vN#tGfzb5&j z@>m<+E=1C_Bslbk(tTam-H^i|e7yha8=YCu#{_$j zbD779@i=Ixjgo4gR~y1ImdYq8fFVD*R)OPsYr*w|9V^`3v4FD6YvU&C3*Eh9kyC~* zP}SWnx!MqUw~AF9FT&=O4iu37+$IzG@qU}`l4H3~>J`O_Pi-~OenrAZ<@8b?aBpN9 zw*8o(ZdQEUaw{&s_LPh$#K)Vl*ljttrDUg0Iu?$0yvS2naK2INGyagaU8ODOg?mgDdbfe(DsEGx0mQ!DkYAc%GE0p^331AO#8AE@Lw!P6AB7kkcR)*lj; zG_77p34PpFW`wt$@J{Iz{CqL)fDZ<}Qk%*xrKja)aw-!C$8j;?sGg$qW!@}wkfIWX z!MwRsF8LF_35Wq|XdTQwuZ1>&WJIm)ph$$mFk~eBiRG27;z>H9h+mZ0^(uz?gtCg= zrZ(N&nej-3c#%OL1>vKkB2_`P3(9h*lL*Rg7&aED62UrPgjj;U_&Nu@si|YqLJKz# zeY05D;Y)#?JPxNA(ZU^aJT*AiV8dpQxdb~JsN6ZV{*91?L45zLeN84e#n`ZU#Y=9qz7>&>I3xg zSm@&{{i{(r)?8~J1PyxGN5BuNdh<8`SRNPYNgv}@yvH@nM~6L#0)|rZW)<#Gbfp|q zY(IMu*rO#spgtn$l0H5eX_yWR7oMTcQQ|MI2Wm~L#jl}om$_q90z;O1rinYoS<59a zB8kD|h5=r`Y9XYxQ2Iv9$Hgd{Q!yVzyW+kj>SJT@fytQIK85*Tis;+k)h&YOQg(mh zJm^lx+|E`UKnXAbw%2OAk^Sw%YhMQ(N`zTuAXTXsG|U`{@hZ{cC$|l3xMc%uNXLrs?M66%O@Bb~ks5>hH?hx|OKfw=Frv-96 z{UybdvjjvE@A0FN0?bGG>q!WB6yD?67vpB_8sH9l{OiX)iv$e8=EG3vk6Qtl9q_UJ zl_ffFN5lzElhyr+B0Wer1MQx7og9wlun2Uiu5R{vpYa_BUI^b7HYBd1+#l6SiG46G6a zb^-D0t(1i?&XcPZSGGQd;Aw|3lWwni6l_Y&$DeNAa!%)P_n4F7dA-`CDCZu%1FI#y zd=n7QCa(JR3uSY&VoUDzW9B|iJZk%%xaejTym^KlpV6U`6|7awM7Me zh@v>u*~cUQ*{7AFsLt8TE9&>3fElpLaGuXRD0q04scoeF+N)y6B$5CvN>Se#>7;Z z6E2d~6i`C%z?oRh;;W*+nv|!u>1Orhq$p*fbrZ&1YK0$ThEiKlTMA_64;sFN$l zCQwM})M}prti!nxM#Gyij7dXLHZ9fx0b0P}f$p8D_Gn!mhU1|Hg3ouB3@OVsC`lRg z;FxW%9G&#TMyFHsVff)i!??KIe)-5#a2JLixULuUF=iTYGZ3MRNPS*19(WiO1#u<# z(WhRnpPy&s@$JWS8NU7a?Jv1dwJ;yX1?h=qK6>==AOs)J{*=_TdAQjB%qD1?ggyR6 z$uQB@y!g1U!5-p=8i`oK9x3PYddhsnS)WoL=l91UU+Hx?FRX2IPif70)_vf5DUFC$ z`&J++0jr7`=SxCkq!BD*Ot)TcmvQ*Xk!qoMoAS6q|2LKn_pWpys0jj`L zOYZOR`as^{e&;53wXhEp0*n!-zOKCXAT~6k6XyvM#e{4 z-5)(|=mYx11XR*}oJ1l3m(2*USJ9kaq^nf5^=5R!epCxbTZ1-5400YiBsit;hH|)nkF}o*Y|UY z&gi4^YkSg-0PkB_WHjH5WyfaNhG@H3Gv-IBQSu1^{2=|JNW=VAD%o0%8AlGv`O_0y zqqc2OZ019A_Ph)wCkFI~Ou*QUqK8JF8%YMU1h@n=RsL>~p!@Bb!5-(oe0TH4tq>D@Oz^|#1MHDYZrKp4tOOES;J^l>#0Gg!}9@yixp+}c@f%|xJet!#0r&CFc0HK9& zS_-Kjx~#%_2oJn5> z6nD^Z{7}~4G*%}_xn$ns@?x=Z8~)CJG2VFu^~1#Jy}!yyhP1(QwW5!kwi@e#tW%n{ zzTci|pC(7CVa-0+gcRn(`EKE`|AG0yUY*5x7p}CB{6#UD?aFfXU~iX$%m=4!hLd_^ zTDp5NI71=UzbnQC<=UNlkq@3Gb2;`4Z2-J?6gQEy4qh6MKyJmaG0Zq*<3GjjYG6XlT#48Y*|C??X z^)A;xm9yxlupea4c*(Zxh(BXsb2Nd@{YPCjG-eLq8{RwWnUz5-+($tlR-RIH3-giV zVdg&Oi>OBpc4buDNsZSM4dE%dqdf>zr+>`oqf#CzqE-Luvlpdd%oKX)1Nac&7B5L(MOLzaQYDQk+8=XMekv` zsjF71ov=ra0zNwCgVf8D^Ut&Dr>88PRk``38f266x#K)$bg0QW?bz-&yKI*-;2mw*K(8=BE+GwRq)o3pB65LOZ4pg0{bVlhtilVRTJTyA@O4AQ7268;I`1MA&^TtDFB zU{~8+@Xw*Bv(4)W%%>>-5%g>5<>RmX~<pKkh;G}B8x-pS&cV)?d;2>;Qks6o-Rorge}PRgX92~K@mC|xBR-u*t% zd=#4JD2OiYt<|!|A3Bb(KcxXN^bcnM#NV(+c#6@YngeM1PqD%16vZhL_z?3EGH3=R zfW{cf9>EkVauNo(4et=-H=D#4rS=>EEaDsOovR|0AZC5}Y6zJZuNcMXqaY8fKlUk3 z6Z&}g_=|DKRiG{+9Tnm}z6N)|d-TX7eUz`6`&guRT&G>UN3mKz{p?ji3BV6uFE^GjH0c@l8SYH7wi#97nqOoPw3-$%DJqLBRz+5F^KKSm0i-J%Sg|fHpcJH z9r2wr(eG$q1fQ{NvJ-|BdJuP4_el$$Id7m$!(3Hl%h?4D)2Yz2Xf5RRkpiuSz9RHg zbK4Yl@-Gx;gT*IJo`49?!{|+Td;ss)8kBitOeJ=8NvhQE2iJoN*nNTFzwR6++pxRsjV(3doX}F;rfNRk9+X(-!&hu zk&<6+*g!IUF~k|*{Uagrmg1|D?M+F*UE~&qXhS=iNdcI6HwJy$_ocLfh)mTf)j}+d za0#>8_v!R2j}vo@_>UM)ZdX^%@7$A>Yn#i1c21=|h$sIcrb$dlo9HpJ;bI|O@tlax z+SrAMl`bmw>f%9m#yFddS$%eGa%b!VhSGejp=`wEY8QKwXy4+hGv1!s`|Wt%;j0Qi zf@F*G+7be+GJoT86fjM;=-kmE4z z0S3vskHvbias=^_Yj897QM%<$p@(H4R}ZejW&N9!s`&19r}(~IxQ|yI^(<`Z=daQsEkFI{es^ z^jW@~-_JF+g&docWv`SK<5@q^rPQtjlxT??gxEQSzVn5U1NC*AnZU8}i18MI$ZM(5 z&mir=M?8~8G4j_at3VaJgix-lbCuiUNp5a?n&qJy=dhoxM@2vl^$irezf9 z#D!cK8FtgrHs~1tg~%?O_;~|ZsM~CWohJx-8;WJ=e__gaH()CYplFv3aMqpk7=5|4 zb^m5+*3{BPh7_S2=?oz!j12ATcoMME2m%%+9yvJpI2`?1ultBm1#h|9e)6=@eC((` z03RS@-eh(GsdjkK4}*_wg_XeOUr_ME*rs zA|+k^{;ylNu=ukv<rUBHFD+ABgv%UblK#H6 z0JMwhcb~i4F7D)@!CY4dYXU@SK5@{Z;wZKK-_tID4^9LT=b*^3%TrvB3E6cRd>rm- zOFBYp+>o{o6W`!gV}!&InxDCt;MSeE<#(y6-z497}?**auBl(Iq%7ZDzA&@UoOv|?1V+rvXtdc6nDGFxG9vItZKOfC9P zf8uCeN_UboeV^(X0rSz)PTaegKnVz!b`SZL5*m3A(R{?u%k2U#W|*|ZCl}{2fK~-$ zfW;@lQ}O6kV9oE|oka7ed{5qD5ir7_TU3K-?y3AvfkI}onq-*rw25A>OX~O#C#`5O zAhP*BN|C|hT^GPmJLeqgEU8YG(*uCdh32&$stsYSPVzFs56HN-ukI|~a9B%pU<1c4tFQGp2$HVmR z^M@_<@v!uO`*fYXR;6O8Eo%aM{20W?*ZP;DbB=H7Z2!Jo>#rR{p@Rzccqa7mjk%8| z=|UvlV_8mwvkk2Z#Y`Piv0YK2%S<%iE*hH8no>}7XLqlVBk#7h;9FI2DJHW+7PN%^w#!~x@o~E*0SFf- z7SNE0kHJPy1TWpG9$LO)lSEA0A8uO_*jKt>E_UPlG3S9sU9w%LZkC)w2m`J7H&#bBaMhfZhddY zuZP{8201ybEHe5K`_bN(a%|GMJlT8k5N;2cu*cCW$@?VrNqMdt83ZPLMNc1+LtKtG{@tAy_MV7HvEEdDnHA z?$W1La7$8D`k%B-e*Q#nXS7DSkOG3dRqQkZCiw4SDN@?jageJ1S6{8Z_g{;dYVSVI zo0|ydU)V%%7*^x`27PosV_=UQkG>kmj5ic|An33dlkTH+7K885q)o+(XoY_+Pb>Ub zHBI(cr_VpnHm5n%3I9QZJUrvSI6wQ>t&`d&%itqZA7^JTit0n?L&=wi8F5U~I9D$| zSro8S9Yu#htBmcZ2^&f80qx-f$wvbA$Qb7F`Fyp|pAzY`CU^GVynOgFg{TipPK`b2 z?V_BEpofM+3qD$dquS-kQ%fLDjRKk;A|C=52z(&#fFzzNN53cP-u2+*XP}Id=m-n(!?yfCqQRR=b&=mhKDF7R=v+GTpi z!_y4S$26sNWI3dirnPR^iXYT^>6!lr_%Ns~Xoh_|{6IKD@zlkkWgM7nh;;5dTpQE2i?S zUazf*y&lc1Kw(3U3?Tu4!JGG%4kp6}8)#HH&TLW+-8Z0a*9!XRw3h}B^R}CN1%72( z45C7yTZ9c1B>ovr&bW__v|C~k&65aF==ZeaIwII>l30#dz0ixs%0Nf?o(6dsY&Yx*%yUb`qEizp zQ$%O#Kp&r-Bl;-Oi9Uoq9;Tv~FPEb)4TXt|&G@CEhyOGA0TL1V$a8z*K7>Blk{veI zPoB|%C9*Egx7f|>$@%%m$}uA1%MC(u!Haf;dRxJdCX;jZJm*}R9negfK*aXVFKPdP z9{L~ucz6%B(m%_MFcf1G>AT-tKTIc0=mYQ(=wpIC#!`Bud75$V$06YBy&Ze^UMY@H z7D0OGAwMLVUx0j#ifaje*zRa0(DXW>6@e73A>xK|v196>+x;RD{@BJI@Ko1YG9=$2HcCx^Hu&N?k_QJpsEV+`zJ+74{h_him)edDN?wh(wR z44TR-^C8`IWqGm|QwBDwuEKGQ$8}cb8H~*;!l02Hb7sA7GzGEHBJN&>>KKVDb^z!_BbaKE^*}>;d@rrb8bFA5RkYsB<;dX$vRIxFj9jKxUu{fJ71w zjZ$P{3~p zK1xiIBAqN$DxCeAkN%Z<@ByYPTLs~{SMI=`2%IrT^x&hXw)Qd~$S?8LY1V`jy@H?A zxXV^UCSW}9xA1{O8F^WP{Pu>prVcc)gS5E4SguzxJ5+Ju7;*W1LajOID7Vw8PP&hb zJ=SyOE@PfoL9y7vL0#3#_fTX7e7J{^n2I3uwf|fo9l(1*aXI0w*2(v(@~f;vyk48F?*skcLH0Z;WeTN)BG2O`lApAvnEh3q_WV zmUjjq+X-=9b@A2~11rBIID4EcZqFj~g2g&cAHp7iKE7J7G+_%fR5Pf>X8h{Wb+O#q zsdwSKR`>D8dG6iSMV7CgK7a5mTdh~-qc(PVEL3y-^z4`0AreG!RZ0wQX3<9i2PQrq z2k~L*<6%0Gt5^3g1$??V9q)lXc2h1AvsATdYGnI#duQSNgNW%^F^_kzub*|y$8O>! z{5__Y=2HXYrneOpZSwczUaheaE~j`SqWo;~)m6FF&>>#ysYH!@iF6=AGkfrA6(Fl$ zavSv@Ophz zPJ(p9Vem0|g+*!W6yPJ}<=@)aVOP#6HDInK83s=dvntewwKYkuY<3)$6t+?YVwKRV ze>m)j7!7W&R|+<7QLx#+4Mru|Xl&@SEammvf!Ebn%JK5B&j&%;r2`*5+Z2wr)jVqM z1-WX=Rcq_C%YN{2P;e@hiGvg;mxT-2-R(nXR@0N8AB?wwy35HtnT?72c$czE`!vW+ z7#Dwkadfe<;fHF(^J3=my?{pq2S(b(HM=S2vKTmd<#Nzlr%!p-2xcH7OP?xe(i$FK z!wiG{F5;y7HyEJ6%8^M>PdxG;Mc_%r3NvWix{R*fkzfd96I*w0yZFvFe4#nfM!hj* zl7<30tSsISJ~W>6LN?VA_(=cLSAPd0OhhoyCng0vloS$9(T|=bOq^Ftz&dPD?lB;T z;-3LD!_dQf1mFneoxlSNNDW-SKvb=}O?odY1&!14CIyJ15B+IRkKz)bD1N}p@y~Mm z=!;#*xd?qcdvty}7wHihPUjmocea1L&gcW6(IF2)llxcM9iuvp;rVgrvjjd0^Ffmr z=Uf7OoLBJCbRz|P(DkjDu@{@uhjI|f$8h!Hx0_WhYHO*FLVTpyIRYn>h(fQt`ea-L z4ugWrUA$7#C3p|8$DYn|34Hu^KE{y27}Y$sS7$wA1@DD<9+?+;ruV{T;osxgVesJs zRV+?%1z8$WTS4H_+jVxSsKo{l1|NC%PDgotP@~k(dU?rRR39F-eZ(@gxyrrHGT?7} zjtMGBa+2o3pWfaOXMM1{dD0ABj0=dDgWw|&PQy4De7wtZ?OyajQ9`bC>6>*13h`nb zPPvL89TZ}8l6C*GP6oCu5{oU3Rt6uNix2cXYi7PkPw4&m_-4L7>cIyQFW$3KN?HRx zE_=-fX^_3lM<0W8^u`{5k93Ntx7uf~{-2qT0joy%rX5ZZwr%ep?&vE z54exgF8F|U#AvGgkc!UUpqvoNL6Cic8tJXb*f=`4p2P2}WGE`Z)4h0zMJ-mBc9}Kc z1Coojj3qPI9QdSD{G<+r$G`)3+V0f*@J;blTtSRatgAh4NZsP5z|s(npPF@%d}ZrX zS{hQD9i%(CJ}G^qc{%$*pyBY8M>9-^R6T^ehz*ub)_0jJ)au4vw;{rd@p4^?+ z4K)BNp^x9bPS8WuE*6}=#^e$=0C`B~w5j?7$1M*70*qq+JeaLNFuq0C->wft=IHqdcHUT|p z(b3vn2z+ertiHS1$pQAX`Fgiq4Vxz2z*3yhfJYfNFB4FnC6a&n_tjvm4%;i9 z7qcuC#r5*@ftj}pu4Qf;It!e7h4hg4WG45Cw42_^DGy~)Op=_g2SI_^eN1!;aDVhsy*%#&q!RQdi_sf)>=&_8gv=k6Rf&>vRV8aILbsy5`UQru?O! z%aKRmpwn9$E4SwM)8U8~BL-k+{0Bf|^~~S1)Tw8>DzF*Ngwzpixngi<$#DF@j!?2< zx&J$+%*Vt}PL&$8$0hfMaH3{m+BFDoK0D6H=waz>8b=U582J0nE{mmhQ^Ig8J$dn- zn^_7T&zI7x&UIHW|F}A>eR?bG9>&G?^hJk08U<}{F;>vWs@K5io9*4# z@E*b*w0CLx$~}4hJGZhN!dlEJvfYV>AqsivUkfdJ5TQDaYS@m>AnQtx#PmJ%0qEHj zo?1nDxDrquY?xg$NX<846}%kKA3_ZLyj{%;nbwzAOuI3$kz$zkjD;U?Z%Bs@z=;!N!s#636$-fA{ zgF_}`#9{EkN!Bc)ZaPju4eH&m=4jae|3~KIKx4VCFSvEAEy+;}!rZ`@AMbV}=f;nJ zpBpQ##}Amx?B(4~DtnteV8(gq*2{9Hv}JTlK!*XybPLI)25&L(j|fI%*7HaPd<2~s z4H7vml2{0hDD9^(n?^0^tZ`^lR3D5EFYMTRlBQu4$1`hzCov;{7u*7bdi-0!hr#Nc zXciN~G4jb1HxedeVnHG$B8bv!%l0;Un7SRfjD-B1;E!vF+$(R!s>!@sT@|X8-i(Bb zJO9Y-)LZWr=sNe)TmO<0b)QJ#0Njy0uOs7Sr9@wTH+zX}qYRdOOA~C9s#%0v(+m@3 z_W1j!=TC$BKySJy?UJy^<)$&xQiqtb>Q6bBuRSNjee|<9*yBu>m#~L8k9#@R_g{Tp zI1hrv3!0DfCvVHziGGnme0=vb3r* z`*oI><~3AD^6loLbgT!Txm&LDO8EhOFm&q-KmAtA0&9&SQ40vekIO0@H*ZcRR;Sr` z6InzXCytbN84W(LlaJse#aHMLx6~i@+p81%t6jY0ZoFOd1KEFRJO+!~@a_k}NBZwD z_+TAB=sq1XE6=a33RNSirM+>sV&p@N)XQO|I9+c(+}09_gdEYKkDs>lu!I}u#i%Sd zL7sNU-DTB`J(SXued*BRWS!NP@rZ{y*wR40P)#-$3;kl%c-wB+^~ji6MtLoBOO$F_ zxi0kFJ7ZKQbR(l$t+AwDs}Yvy?uJ9NkIcPfrkxhtp;t(Po+pG$ZD*zS*p2=zX9k4w zSl{<6egS=pz(Y1dfRuL86A!E1E=hNv%($@|G|)j~0jBZ76M1xuTx-cd##GrheRz9{ z27UvADhl%Sn_d2uE%6Ht8=Vi=4+y}i@5b8LqZ56I`EaF6!XDSz<|BiKVU$v%+I+0W ze_nrm{WX*FLHLm(t5Uz*RuD5pW4U{urMUNLYOJ5jVJq@T|0s8{>f=djD%W;1z~|%p z^RwsIq+Reg0N6k$za@%=YC<2U_X0I6Qn*@nv&iTp7v-?ea2|$ELRnJIzRcW*(Fc_~ z3DezwQO(uqEC=?e@#6RMO;ky>RRs-__U%yP6?&3_sjkD4%Du>+s7@RB>(VVVrXIrL z649S?4**P02?vH-$9GKG=xFsZ7V4wY&;8;r;^z!Lvg)$~ADW{Pw$niXB<+KwFWx*d zKDUzMW1ki=ddUZ69Vr(=FX73br7{%m%-y2aNp5=Mw#z1SbnWxxsg>-XqGxW+j?Aj^ zwDb)0#D-^61d>wy3_+Q$@Qx{kFQ(5;j`eY(K5jSYeGmA!k@GI;Y~($4K7L}YuJ0Q* zibm*pwDrtKuWaqX#|Yf38ywVP(J2`1M(uy321V%^2TN`LGxOo<9mxyKIl&T`*k*Qc zsNJ!HdovD}EPZuP*jyx&z1ywsgYnGt3PFLcLyFEo8<@;>y*MW}pO|0lTP3h@SR-m&r^-)b zFg*u&VJYeo$q__&{Y8gHY_Y<|pq`*k&HnYw)l`JTFA1bVqArhWwOno1yjuOflzbX| zps>-A4UvA1|h4<)%m|VdyhlJ zM-k4xx<6ORuB9I?UfJGzvWNHpd)Q$8#j8Iqht*0gRF%!f7yF6Llfrl%y6q@{NTq9%w#vdXDyJK05c49q`fXYs!=;E;_tZQJv~5nfQH;<^E%} zODDv~K8Z#h?bKiqFm4HyOz)y7AmX zq`l7)KTyk!@2&U9b4;1djOfg1NR-p%x3G>CjW8G$5EMAW7b(d>-7VX)BTKwkJj79= zcb`%3%1LgyH^rcWhO_PgnS+_l_C9eLX|KQK6pMnaN3FYa$x6v&P)KhXtqPT>u}s72DTet=D81RA4In zvdGxuG5kP}KjJIjoQa9_a@?_i=sp^yzovD4Swi z5g+GbVDeK{WsA9(wwf*56S}#2`G8-E?|!w8GWQTgXQkDK02EHH|UaUZ^HpV0k;mP3NJgHA`}L0 zT7l$;%ES~2s!ZE~H%c&SMkD!&3S`Go6Ox$F$m}C=13#QS*Dgs(xgfc_@IjZ}5!S=x zgJuY^k`vNq%yspNR zr+YR5A7?&MYU^<_7%fDKq2}7V?phRowyd67I%-b!MX?s21H$t=zMo50%wcqV6X5hh z_!a%QO8=9w$Fq08gx0ioj#0E%zob~w&c#AzR#|bqF&f9(k+#xh;yh{b?VvN+o!5J) zrhl&YkrRR-0<-8l9qDOSM(LcKH9Ga0e1oXe-LX}uYDVeL@9UqN)A+tXBjAGym#KWZ z3g_ya8nwv*ubgT?%>f-ihrJqL)~aWoxWVY?+EG+nlAnJaSoRs&g+D5qQ`gE0e9^O9 zoKgMFBD|hK$Q_!C*H4zFb9!%=v`hp1u0xQ9sBV^Lgar`Ug(()jnI1NN0rpt)`7ro6 zOkzjm>8Xd#JbkcH}{cZK<(6Z0l2{`N&C->#wukLj*+xXrX$2WNFEt zAASAemor%I#60%P)7(>ERva)Nf*-a`_0P{wUf&$GM}{AEc^_v-zlqlP81cc*zB+WH zyzIEv5JTg^qe^{{bOC+XSXSJ}-eQ`Nq}Z%49oZw-i0nB1giIqd-LROw=SM~H4P79= z5Ej)6Y`j@_pjc@0nX#4rf9Da$cztmBW$CANUv6q2W*bxs>SkQnqy&@fg5c`N(+;J% z=gt~qKz(sq4i)s zXs=w-Swd{~H5YyRDcuWH$$!uUYB`qfwkZeT!lOR>rP=Q9zpfha;e!!eet-{{ZC&bt zeaq#BQrqp|qtCG+IIT30xEF~(Cu{H&>L0Wjd~CK?cRnlK=zyJ_Bpu4=PmXOIS968y zZ4Ce;#KG*d@6OTpXBz&E|CW%Sj1S+vPxmNKk1`p;LpX_vidL%H$Jh_8>}bF_8)QI= zOlc6MUi3?&-7%H;h#qH6m-az;PQGAN%1 zoc~cwE7#z`@Jhz-W=SG|7AQspKBCLu#3q!8f!=rKL zzIc@Szydu;y8u2Oq)5Dnum|8HG@8S>y7SHHgJ`pk2HkrdR@o7^$4G1yOjNUThq;gu*|eEYo-a=O_3ttBN7VkF&limFKjd)27D~jgwB9$1AS7eWKfpR zHR>%dzSc>PuIGN&-zJ6yGu% zuqaLs6^1vhDC9l+>_ev6ltt-dGFVcN%xtutKK@aZ!KmB%D7@VTVUO%briP(TzX{iB z2N^5^vx<#1Mw3COsgvBvTCN|hfYG={3Y)M1gjnm>=e&wBr%59g6TB z-_Yp+66W>7i_VMZ04CE)Bfc%BMsF3hxJQ-+gJRUZIY1&(9bJr#NO73rk%}RI45`lL z%_Av3XzfC|3xd;!cV=J@T|DJ3wtTj_b9(yV^i(ZgU2Q9sW(PlnJ&uGuTKG|@kLAU; z_x|*Gjw$qTxeHxw)5pVCM~{w-KB9s?2|m&~%vS$=eN?15_7*i`h{Ri0b+pHv@b zCnJd=Hv7|^0h|bBe-Oh1&LlBTmfne>};zg@NvA%z0^{yu`PtGRhKrU zM&Y{vd^9M>jkKiYwzWE0m+872>#n?@)d2#0WK3a0#r$n^C?!Db0t{Pbm-d@nn1CTg z_mRLyiq)?Le01-_q`%8A$C{`m*TY+FC|q=FYCXu31I@=?mv%vGvj#po=0n@04Z2oU z01+EyDoJH`-;dj?Zw4QJx-y+YWQCNVH}IbnD)5NTUflxQg#$#C28}g1W$+PT zw05Cy#-FEWH6PV3z!f$i0wG#EM;#3>7}B6=L85A}c!jer+*mFEg$;%cnZh5o*=D4x zX$k9>20|uT#}jh-@SeE5CI6(<)>y7;xva*BX1cqE0}EFvBg~Tww^yie?91Ssw)*m% z&?1h7Z+JY%j5ME?+p=>U^`TXs$Ep+XvDc=oa*gfLBPw0!D%V(?s+sC=op-k%SmKF?V1Gxm6T z3iJ^60DYuwfj-i6{pm0FUfvqXxKu$)qJ*BU9{03|5QiBZaUPCuUSAo~e^#r1C%4As zY8L3@MGrm-{Gh+>pT7vNQ|eV+Q@PI6_5L31`B{FU^ozn5=nP62Qmr-=^ZsIHsuluL zkaqHE4|xRA&r?m{$N8lAm>tOT+(dN>Ela|d*SBlNiBwd&)Dr6$-6_wxuA1UvWrfGbu94+`bUz+@75a=9> z2m-w@j8IZopO`DMS7jH`;AyIRgaRb=Fq9O8BrlWid(_AkAY||dK@IID|!nREWw(2@|vK)1ZDKJB~ zJSVff*7I8tyQuCYyUvQ5brmiW88_2;I@`*8;Be}y;?UNX!%}N#84ta{oeXzu2Y1v%OzmB_uTsP{+#axkcM$kjveWTz=eE=S!gMA<%Ak5=eZcTMv^ZNX%fy<;DQ z=)amf_8F`_f)d-E!h0Bei1<+SMjsDut>*LEHQKA7$hkau0QP8nK2Uwo(>7s`7b&|i zc(y0z&u$dnL)ZiE<97b4;Nt<{<6-LWa`ZUCkH4QUrSX4%{~_Id{59AkJa18Y5QY{enCKeIPj{ zzAo|f)?%ht5zK}MAZg5IiCde7Ve=4^Jk%VWBu#x#9}f6vb$ixE>kPsRwWv{PRqKZv z?jZ4?Pd19Z`1QW5qI1E^IcB|0$(QT`ni&GchBk?Conj9r;3Iw6NY8Z!?|wNO#;OhU zX!;=s@o}&>;OwC=5A6FS0_?mE_*f-rpjP>PU8Eb=WCzt{4sV8Fx3qP7QMc?a?!=Hz z1Xn;Vmo51bW4z>DmaF3*%0$f+*ny99P<|B`l(quY2&6Der~LD`bN44eOL=3_Zvpku9Wc<5>4jJGzXMh~iT)>_z2rI{dzJyRdU z{_OZ4XDar{ADjam80C%5et7mB{cfj9B?508CI5D+8YdRqFdwirVh5|f2G3sLhI6{m zJJ1O+4qzdTdzq3<{P0Kx7pq;i@6}C9IWdk~87lTQe)Fc;7BWRvA;}XLuL%P1A-$)W z7O@ef37zm-pC|!*@CQyoU)!HSt5Sr(6lASb{$hMKUdmg*fyZ{be73|SY(F7fBe|uV7%4S;BHjVVh8!y(d$8A9m`n$+zEXr+vIz3A0 zBf*ak|9JoYA0PgC^w-BJUi@_0LJx(LE`**aVUItZyu6iWeDdPJhE+x%r|aB@0Z4@& z54H2JuV$+-9Vmr1^emx|x59Mg!_>zVdE~d^>8*pk!oGMF1&$Om>;xiEnp3)M_AIh& z*Q!v8Xsb6c$&5}JvNJ^uCfz{ey?ZGD#-V326;cz4`vxDQW<7zAO)I(ddG=gVeJu0k z+Tf!VE^*bsU2(AgNe&C;1Sd1`p#>x*C@4VO6zKajoR^Vw#cG9lRxyNrzVg?UT0C2Q zd$!MGbdBn>an~|8?5`*WZfBrU4JXMQ?Xs1(8XTs2X5JX0@9<6GXXa^g-lgvs!t8fm z&E<~G!&P~T4Brj)zzS*@lII0cZ&UDb0r0We;Z%UkK@VT@T%jApBw;~JeLl|rF7RR8 z>NY(XOHpS^Yg^_I!i=&3e%Hl=m&(;;nfbAE`G7!?5wyKg)7l^MJw2q=DG`x(KAVtp zxpvi(ICd;F9~xcZA{5{W$%~Oh_~ zprHhcS3L$rFvv_QOkpH8SIB}LR3sC4s}s;wiMlSW90R$4M(f{3PtWWvLZEz$v>;?N zI#EsL)BeY$bg?QxTU^FVSAB9Fmr>69}YWkHe>_pG%4aJn{!&_@Q`!)yGdSj*bfa`0HQq-~a2~yN`4H z{PU~R+Rj!V4f;qQf*t`r((^rke)9TS?g2S47Ds!XuI@|~r|cWNhoHx4t_OO1W3>c# zC<1*ve)~cJ`Y`k$68iY#!6IjVJj&^9}VvlyBAI@f`yb!K9u8jQczr%t!Y6IDf9Y@b>ISnWm46!_}aD^Ks}cHD^ly z=g-1xMop|glL~kRzBVz2`2xbNUtrc3SB|tKR@*s?GWFj1*Jn03Wp3DRANa za{oYOIUIFy>tGKuC55A|)d(H)(TiF;!KsovyS?vqT>OISH~4Tlq1VDGdhqe-w9CZ1 z&OKkf45dk*5IkipHu!53;JR1J*qwRAh>NRsdOwTQ_p^jPO#S)Q5v@iRxYn71IKmYq z=Uh^R<{Lv&*|&<@@kHEC&lOW*;EAduTv5$>EEed-(rp!>SZmeHIc<)tI!VNJi9-LK z-t^PBXTd?{uVO7^F>Yp8sZpztw6U7M@mm{BO3kpVh zS0xZ0gW-`dKpzF5EpE;S8@ ze}ht$Z8V^c|E~gZckoc zUM&qd+L))D(odid={*4GfNbzGFa=GY&PKhRmE z3zxiPn^S`i+2dd_$~4F#p#<%;+ezUtSxdSg5q5t2?Q1BZ+%FW)-du zOAkH-)v`Qxc~Fq0{+(dv=7Lj@;YQ}8M+2SaV>|fpM54PgQ^lZ3&PnC@ocZeUA5XWb zv0POStA{$C-q?EVbwMG4NTp7g4fuctr0QihN^KL|N2?232OlOtCefo0xv_`dLyrCR zq9M^tZJ{r!j&`nQPHVZ8ls0tKhg|E#=73tuyl2*=de9m#EF!NpBO%MW1^Gh>8adES zn077XU*Py42dB|8A7z&Y*vpS-KGLThZm~sWlSZYynn@pf<1sA!XCHpCG>HnMIW>jO?!Rk?JJ62z#dNnccjl0ZxZ_0pQSUf zHL@l$1_dJTv@WOSI-@FO$^dIJFhc?6orca3=dq2reJbk1NHzSgjn%o;N#3keLgJ0;AsGV5)Mc-Y<_kh9AL&EN_ZnLyF9EUOMJ}7YM1HjY=NTp4?B+@SL zlSsl0AmVgGzD!5k*7dqphfrpVEqY;1DEjI$`3k3~f@hp|vlVYdfhqd*xJ|4jkK1RU zq`AjFT!8w*KO521(La0=eCS{8D?`C?qpSyfY>|A&qbM@%F;N{kPRk*#)i`5^CpyrE zJE#Z4YmM3=PSPWK-U1r>W6m8hkLT^;;-`M;oGR2bO#hC{cNjXZv@aK7#gW zH6NIa<#_q}dMO8~m1Kh>wV(guW#~P+tP9gL{vHW?Jj!H((;CF`*?9lpC*ZlpH2LojwZXM{aaD@_HabOy*A zK>lQRG~&X)rh*TuV2O(HC+Muo#1`d~$yK=A$rZo{41!%#5zpgG-#H1{?V?@EPc$b~ zU$>V9@1(x<;3M#C>+_+E>HzqN-nN5V{dO&=2h$UhVR+BE>aDfBVxM7+ZCVoOMe3Z1 z%tYJv#su=%CftNe6)k#pI?}^XoVSsQ6)L`LmirBMX-E;z9q6I-8ljvTWP!c9@ku+J z^j?gMJ5S$)+{22Gw$|3v$E$=rX0AZpGhiE(@m$?}{aoJbq+K9Cdhn63NAe)g*T!03 z?P`#WJyPX~0^Y;i2Pg#D$JYgBB4j~WV#}^5GJP`Cy+@sE=3CNGkUn*5q;`viYnNW{l@ zP{4{7#Out5-4kbSCEqfP#pfd%XPm#V$upFR;=9#+d?w9D+Y65)JUHSG(N+$5Mx&pI zgT!v!0=tfr$c)hVt((iiOT-Oh!4Ip$-n!n-^Mu4kL;1`zc5kl^8u*06>24>tae1Pu znS?!5Xqi8&wMl)t~gphQoXk1t6qP^&k`1Kv-|ljCt6&c` zetEKm`VjmO_Be0@dwej`1RK}`7FoKwe*6E#05f2quA#6pOp^Scmuk zd}P|=&6}ef_aEJwtw0|xeo*SPZ}UNp+UI40BJjb&wQZH28`lj1K0*w;-yA6YAc&fBs%cvU zkn@d!DhH8Fk3Mq8GF4M(1|%?KO}*s+9|ZTB5$Pi5?Y&*j5L>_pYg52ZsEYI4U8l00 zYS$ert99@}d>VY%h||a!hf|2Cnu*`gHkeZd&Tm7^fJtMQqoe!3qAUN}c$Vk{`gSFZ zot{%Ouwxd5km{~tB?Ab)^Yh=8aFltkYbWoaq&-#}55R{y4mP`8vl!j~`#^CR36|#^ zKvTNYvXJTj(uyW#cj~{RL_5T{ThlJ_B3*JUz)|(G7?CzHJ=Z#|MdJ!c6AT`=m^9pC zM|c)IWD~~(yUYmn6~6DHA5a9XG*WcGCgYc2PnZk9deuIg&6~aM)f`*{2t3>M|6Ga2 z*_V&f3Ok3mk4|q|ut%1izI}0N#M0DsK)$m-tiCMnV{Um1_yB!CeI)qtXpyi-`gHF# zuk2Rio0GqMo@~`K^nm*Sf`Ae-^2py#j=s3{5$tj8)~%aggFdEy?cA<)FGc8j^5-k7 z24(Hly-noworFG=I#Tpv(;NaHe@Y*(FOBT^IPuwnVl<*%3w8LIJAT56zKI}5=~?1<^pjc9d7Z;=g?t?6vI^k|6LMD~F zr1MnHYa9k0p>S?3kv{B2?x{@Y01Q9gk{SP7jM!_l1wJGgl!RZk5 z#dI;rv<7;P2_rly{ZO-|_(>uc?pKKwe9UJ*CiD?w<FQWzW~g*+74BkIRSN( zr5DaGvFk3`5fl+;Rt|uJy`$7N5^h6*K*EZ+#n)#stw{Mt2j{}hvl|e7XDansC`I2O0j(POMmaf&!@V#d0>~&Ly`IvKru?-HgO7ZD zo<0h+?Vcaw%(H~22f|&pf2*-v-WsDg#<-b}*^Zt!BzLo+tL@wZJ``I7r+%knvZxoiNmdQk zP!8~q`Flfn@!YvzpUo3Dwba;$yBp%_F~saG z`9kzJ*EFmlo^BN(yEPwn3T4U_lxc(o-bbYzYi7dKI&@L_twfE1*pN=F*+l4D#6ShA zB9Z~>W{Zo2JlN4|SK|`F;MuN{P1@}#P@be8HKP1dXETY5eoKrAl^gh19$b-WlY~n&SfQcb~^HF zL#f90$#WIC{Gp*f{6SC{d-C{Nj-T~y4SJ-{9G5ftD6k;KM&NPpbKplt4jFwERm0#2 zsFgA=cQX30^aHhru*Zq&Y!mhn_;~RA)`H$OZS0S?Ucq}jonVhQM}i;9ynJ~u4l@&w z!Irvcx`>^ScG3Qc1xhOeFdYG=)vsh!9&DWu3B|Y2|M>FnVdgP8ne2Yk`qT()13tVl zwbmE)@yi(i!RB(pOi0YfT*Zn8*EC4E3Hq-QI`Yt1FVkhYC_Yd;b_EbQZC+Y(r9j)c zo^OfbL0NdR(ubN)wi)MzGdA_C3Gnf&6w^#T32#su%HT9%y8<3*q;~@wE!WSXO zWP{$m?q$(jLLYYB=g@yTD1}bgBQNT7fhPAQx?WadfR8BZ(L3inM4ZV6A7zq5a^2?y z8VZBSzubbw0EAJoqH>Iut7Ym9eKfO|;VV>wWAd*185TUG+R9U>B7;*Ob%M1;p@sC+ zy9OVIVJ-7P<5oB_zz2cA9(&ITWy2xjsA9-v!!-A@q6`b{04d$DZ)ofmagLw@ahq|n zT3R3CJVv*=c4g^ASf5bYcpNG!qs>wL-S*1K+Waf9hp3OK<^$g2;;z90jiF2b*@N-% z>B&8?N3Z&r8l0Z~^xM&xXbvdj6jEW%t~`BGJKVd_M5>NOH8s}HvaZN)qrnG#lh}c}&gb3MF-9H| zr6-UNf`Fu^sS08jREQM7!=0*3x1bwQYZj@`9frrW=VJjnfeTG_g?rtKEZ?Za(Fj57 z$|Gj28oP@A;ivTescXn0u*Z>z4~ss!Y8QBqGHLEjz{mdhII{{3?XkgMok-YYwVV&6 zvgcrrKR-z_j-0XxIAGqRjS2X8{?*0n*Ao2rF@Ijq-*qzqjvwQ%I*~7D%FnEbVZI$1}6VsQ56UM${K+1{c2w#1rlE(?7<#7 z6d}YN#Dw>n4~Qp%uC|zr?SlDqZ*YOjPOr9JsDE>cZQ!G$xh|}OkHO%BUeZk?4qxsC zL?XrSl`EsJ&dI*=R>K9TKSJJLvico=v=+J>E*XC47Wka7*fe2}WjS)?Je*Mk>e^wK zw$YH{T+E zH;ctkjj>^DRN<3QxK%7(Wnp?86MUqhL|p7K_|kJ3q&Eo~@+{yH3o?Y7)uza)4?G_+kUi>Lad`$tFCn+EoP`2c(TxxpUuyk|%-g*}vYxi?`xD)B*y zZNVOC){NJn?-F4yGw&f;D40O#Bmd}h8TT?l@$!$CE?>TU{ra^&er$eq`P${{=^>Zy zJM)6%qmR$^rvN{<-(FrFRF_Txq>MeT2z`8$(T8{sk}jlOD)z|ehi=<-Es8hNbx3r6!dXrW}|g2R$O;$xkpum*yKZ_hI8AM0G4nlaOzIHiBSRY!e<6@ zs_5IvA5=@YQS+fO4*u0pZysH9)B9QValzNu9(q(p{`=MOvlPpr10NyeZ~JDnV@ zBqP-cV%kpRdXJmoEJ8x}EEiUGgioH5BFsGJNE>-b?w=`Y|CDJnP$MaLH7a^W2{aD8yzMua3{j*s> zc>^`!a==GiIW#fTYdbopVH4D7J~&wowVdjrmP|8KfW1ae#*n5cg7`(O!6r_GG z5ATI26!cLM2x8Ex1$qAR*40ZFFJ8QyqTq`Tgrr|wzZ{X#$K%uR|JsmpA?^j~lDLnP zx0kcTmI{Kyh${yPeFX7=x0pVZc1Z+I7OyxB_08QIS2O%D_-LBkUTm<3^DZiP$q?j` z;D^vh#vbG_XXX7@GFPELO^oc;*~?a^u|pV~lQR)ereKwB%pQ$>oj7$SZu_!V#))KR zhTpA!Fc{=8Qy=pBSX+EMA(F~ajz3#w=EF2U#ejNAy}ee1geBuL6CW4on6}Bk=|Unt zN@@Y@(IOBVMNfsNt-E~#KF+U$sqHg7(Y`KzPjnAlyWfKbqBrhdkIfK;T+csNLJ@FJ zME{FuGbRf*n2(Q_+5$ehP1||XqDD=lC8}BvA?QZ%L2S`{?1mg-s3JtXQ#@J3EI{f& z;3J;hY;`}YFcY!XA&3cp(6{$x8Ke*?;t~{5#O2$%!BUar`N@ zzyIRK)vK2-75pKDarruNc`dFAeF%JLliMPMA17}wj=3T@eHH9M?2lgt^iUu-jcS+p z@DX|VxS)@WJybd~fAzf zco~UoI-4kcsflogr(}O^2L{^PR-mL@jN)K9|E}@H*yLhx;lkNWeaNtlfXyU<+?)Fj z+3)%3fr;A^by=4 zy8B)AC|GTKY{x)sZ@Yx#?E3&8Xg&ymGQwtAV)82oRsIi-^E<<#`f>m;BjYW$Vh=56b2jnXX z$2I9p+{U+ zS8~GYRd@bk0UL6esASfNAE+s&963?lUuNtZ4$fP>oPEmG^S~Yt`k?@}SCkyG(s-@%pghG*chrJUmadJ4)tY_wHt= zL(5zakw-ZQkB?2F624;R2gwzes6Ab-4$8e7vhInh&@LvN_RT zLvOLx@RTL$%BveryQBboe7dWxMs=BR=s`i-H3bC~P5z!=&~yN7LPp=hMf6cAd}prL zF@7sk{;s(&u{l|F_QUaKp_BoC2)vop5csgx0}uaD*8)CvEY^{nnu)YUUzqsqMu+V3 zFkK8(^@7Jn?Zh7a4oT`_Grp@kMmDigydj2RYK%d9drEC>|4m<5YeI%7p&s;qZdO}e zi%tHhAwWqNi6DxkjP{6@2fMW|wA;zoGLBZjX&WF|uIiRCB`pZ#qTTc!h9gx246y+C zh$)^V4^QEg2iN$36e#fo-t%8}QN=>dRNw;p;lYo|$0lDote7kEKKx_ykZ{hWbNRqx zEMt!=+44ea4|fC`GS`*}i=zkfHC5b(_)s7?jhxF^rtW<^X9U(v*yHHr^K6!Wduvj} z^oJtx9yhNf@Nq-v;}QrX$2LSH66C(w5U~qdkB)x8Gh9;o&d@8$Mgz zJpJbM^t6W_IuIs53ic59arerNggvD7XycjDN9azg?xTtODIOms?xS5@I;T!ZOSaD8 zvB03=DG`(e4d$rNO?M2E5x7HxbVgpad9+hB?X$NQr+e+WXz;O|Pq>|L6hy5q=;yWaebk`1jNdg}~zpknque<|Wz()(mdhoIS1aZ~((I*>@ z9#o6qZPhLx0UyhuzJFZSgLa{}xnN1T)f!LN`~a`WW1W|-S$|d}18sU@h#?#$%&Tux z&3RJ^WmVEgDXD}#X2_EQqKyey>B$l*2Y9wFyCI2l-Fh%Xm>o2u6q^p#p3(<*vxG>I#uT~r zl*7zH2Z7h7gVBSJxgw^V7-I!{1oI)4L1S;4!`S1|m2q#6+VR%*Vs<}Uh%208fcQZ4 z(P0na7@Cp}tMT#4pNtBK4U|OwOa`dgyX#5y-+p^@zlb%clvRmF0u7fl_Bbt_^n^Z63hq#;EnfjZPQOgq znqipWj`BIKEHaduuoq#ZqR_&AeX#^!(z*pEJj5S&(fO8dEV;De_^Rs2!#p>3~&4+Nb>&bNX2__*d{DFC54 zDR_1+^UMO>RhS8cAmc&|Ri4|lR+GOJ?g_=mZ~^)Ndk`Ejx({dUu{f+vFD8vf>neXX zMBzAWRNb+5!oWASJeVZx9H^vdwWjkPd{kXIvRk{ys`&608(_lI8u@vtNFhP`ZU=V19+*D>U6}qUf*aa_8v>4d zgixR}9(9&&U=&sXrm6%*VOZw(MA%4+JqB zaKa>ohsqXvbzU@@4|TO|>S?NjzRlfsRJ#E;@6oJ#WO+Kl=_gFa=ovW3HYf7rWaP1s ziiL9UjQH(ECnz)ut`LcYhJ69^9YVzSB4#>uBuqh%eWC$}uyx-pcMtaMgD|c6o`sud zfR7lWoyD04ufhUUuU+np@( z{*)c;*5fK%asq8b=ng$=$Bp&8NEnEYnR0L6yG{A*UE2;xzIm_J6 z8*OgRN$bjs3^Tzut)$`%!a`$O=1S$U8EW`zv(=y+uF6#*?dhTXbjet~K(j?eP*G}2 zeoyvi-hC>DBR5KgZJPFnaX(=XgAc4+&TG6+Jan033v%29juzg-lGED|AVGgT zSD(4-V-G$;zc5~Zp*AlGeTe!n>jCmearbdTA7-CwgZC!mf(IVgefSBFCHJ4L!}@ zqosbgcOCdZ!(u-!gAZ2NQBd3R-&O1E6(ynZfz6C2Zj$#7-J~k3`1h_72+y%zq}?@} zv)&_7b)`X2iZX=^>)^x7cic{$LKtXl3p0`ez|q$0BlTDmXl6YZNC8h*>ppG3uWdSD z@GKmzR8ahd z0Pk&ADHT1^hFRi0?l#y%(RR~+5!mDCU>xh|l5f(QTJ+mM z9#_)G@>*nGpg-;*C?RaLo;ugPymfFxRkHTz7{-b|zIo8rx=`@~{7{>hf<7*S(wTKUuJqlLW)hwq&IpiyDYMn$Z0WO{X1PEZ~?_ z2hv;1G3~|Z`uhItsOy-z;+qqqKFlTe^s)^wONW;ffR9CJz=>Ie8hFb4pb#HYmNEr1 z!wcIa;zP66=mWUhvnYC=l1VqTnb7ijx(ej?0z@oTs&kL7V?q#aGbD5u0Nk!`LsJ}QH#%q zkN^a><_zz7Ll^KWbwjF(Nos`R7JWLwivZO?D!&3iylUK+4V~p8x)Cu)bX+kWDa^-7h(A!B7Q33bC{JS>TRgI&KDK5)3+Vx#>C=a z?(yiD4+n+%puL4*K?^>z>f<qctV5t2^;A4i2 zM(8H2v&r_$VR!2CBnf^GKKiFyZ!D+(?Zd#MjYYj2x86B)@f5??IL>$uV|vKn5g#yU zHCFc*%MXGY+YMhBw}1a}+zH=b&-UdgYylr_ViaArfb|A9ZTg47-TMK~FfAy}44i^o z1{h(P@WM-b&zVmBVy3dw1twxm6I{Du(a&lv1;(Yq26#*X0uMg+R!^26RCqo;ysb1U_c^4Ak&Yd2HpR-7Ft#f?{b7fm^VyxtKL z&uPG-cT+E&L+g8%d#78z2vYV3>rJ60&oG|{_5ge!`jE$miI0~@hr0&>@614%(OX@6 z@%GhQfe-ah%d;&3^f*oZTr&0;^NP?a#M=FPnXpF!9u<4=X-LpCvb~p{Az_be2~IfP z`N!3F>3aqmSIf_Lk!eY{fF6p)7cWnqcQw6qb|Ip3e-dmwd3kI9%E3W_9mLL%-tN`a z*D3QNvZqBJCt^NsM~k`76ZH7Y%hxYo7xZDsI|qDRIk@%WRR$kZ;sfd|4>UL8BzE(ixTSLzp2G408 zI^?!*Km3cjbK#ESxPq{xnOU&JL=Y3n7`*0Tj1wCy9N<7g4upW8$w}b< z|Cn@l-RiHWcNcKpxk6}nwVK_T?U}BwTet4{i$APS-J0(ps_?deG0hXT%=T>k{i|~_ z7~6$CRO%8Yk%rp)d$>{8K7I$Q-r#YvYCi<0M+@-r{uBLHW3i2{X#a#dgkQh^hC1-k z_+og{)DQ95y5-BUIoi#%OTo@K)hq-b6l-FozTozC89b8n7S7K{PM%#A^%rhF#-n!$>5x2`A3nc zrl-ag(Ub&?+M@3*s&_#TxKCHZK6DG6NAs#en8bxS@#h-TicxCHI`YA0zWeGkq%d~EsL%;1(;?8 z60L3auibl;u}2EInkpL6N5&p0KpzElM14yEhj``f8<8HYs=CxYA_1r@KlCJH-zuVj zBk7EVh(^!O>M=4Ba{oDSkQ(l=cr=)c=C(AvZ<#67S1c^cJqWH}{W%52YrA`*2B+ z#z1@sdB5G74=hb~fe&=8Tyim+R*)l%sc%bHTLqbmt>9y`YDFI}L3dh-K&(7w8rbl^ zL<+(0nyf&WfoU~U%5Bevm)}_!4g4hfhH@VWeXyt*7s98oSEmEdmJWCvPx86^wm--e z`E z+xcL-+#1VO-Ik!)1-S~i7j%UO!|AQBz#c91u-imnkEb_Ij!sXEKC+MZl=15-^A_uy z&ol1<_>kBXqYsdWvBx-j;*K|$r`%&>51|iF|67wTl4&IDankY_S5G^@0Wx`cn*S%{ zjGocQaP6tk2f7bB$ryN;`B3Zr=hs$86N=lhW`~bc&C74J)0TdabV*TwN8vpZ_{iwv zW7Yh`Va2|Ant%DtJwp#i&wL1dT+TpF<1h$1XI_M@M>6F|seC7hY9iMy)3lre zC~ss{2(}FJC6~I~xF(D6SUOJBN0}{*J_s9urJomnT%R5W@&I}OKe)gGJ`(Y9;T&t= zWke%$5g+3?RiQywYKyfB+c$k4a&f@NSqnaL{0yDOKM7FS(EFo{pA9~AfV46-_-K32 zck=u#rMB%0^x(tp_MS>bMPa=_zt8+&k%rdRS$er1d=M^g>cEFqa7{kG8^wyCLOOmw z&Kshx*3bmmq&o$)14%0F=9CR@(lHV;;^1sEXz{=;=p$5U6*~~2ZLrS=uUIWH@M$Uh zgr3q}Iyes8-asbJorNU?tNSV>BMNCXZJTyYHsGPdG6PBg@WHjnK4lr)(SNlev|^;< zVhs2wG*+ki(Ff|BI9jlQDZA@ z20KacBCvdcL-a0Tr1R~%$7FxNDk;b^HHP)lo_D#ZHqE0cW1NLO(n>mG4`p4J2J2Do z^7N}bQ`c5#WvlssulA?oggu^$_z?IA$%pG~K_6A`F-^7tA0yH{b~Gn{5BP?*eTyc4 zkOA1^SLto_Aqqra0FM0grJr&p+C%8$bd}JD8sGQH7T$nE($wouug!;(3^Yf3qzy6& z`}jAnAH4QHyR&UEOf&8A_`%~GPc!%NB%=?zl^q<^`EyPJl5DGP+N1mj`VjS@%**Xx z&O;>SOf+b640D`uF;04i#sg#?_;9r1=4Hl{QyQmKwgnNoEU`tjS`CF_1z^EP3Gj&~ zr=awfj?rgAxd#sTs8Fdb;DdMv>d<%pwAjS1KiP^mxcT;|^_xEreAFvWNrp@CTnC(r z6+I3MTd*VTLTu}5D=I}KxiyQ!sE;6KSucQXvZ*WpX%~Dxh;86wG>~v{Y3l%PO&|T! z3?5`D&GozU(DM+tPLafcrcNI)AIpPuRVX=^gewp}?GB|Q&wckY8~d8rngEKE`=4DXnp&H*9aK^_=w&v^wg|Z6w)p}q*T4NIHl!8FjWVYHmuQTNk?Zu z?NFA59e}NB0WmIZRL`<3+HVM}emhiYc>x?Gw~NX-WHAhEazlC_l)h{A>qK*vik2goCZb|?DM9)6s-4}*{NwL~6WnXkByr`Og; zQ{Ib`6b5`8&+99%lhv5RUSrqQ*fugQe-QR4aiw<3$(y2bH=_@t7ky;K>F17L4x`*x z3^HVE9fe}cI(wXNJYymVi;-^eUY}Ia*h1tbVv#y~jL2A0Aa>R|r?1wHD}a&rkjq8hQ3V^*jK zXPwWpqwV11A5W-k*+6r*SA@KOfee4U72CXB^Dz!xAT~AU>+7QksNUg}fcY@^&|=(W ze$~UtJwpsWP-5(tkk!@un~Ys*98QNoIl)s5a)<|CQ;mV26{Vq^F3JWrC7%vk`Rx-! zL>kNaZ5-~u{5Fm^pUvAsRayyslr!RzudZH+3OL93HTVd!&cVmXA1an&!xc@VR1{&7 z-U0#FPFUVij}~B|Ytu?CT{L+>@ZRc(`70Yr^j58Hlcm9i_Vm?PKus8Kk)jyUd?=#5 z9tcBe7m$U1Ml{CKL>(m^CDyaWR#f;w~?rCVt;LrJe6urmLcPj4H0fIhZxAKyH=wK}w^C$+J8-w%fM?Wa#e z@lh&mg+3zSKCJh6eQQ3!Tg>XJaV*&5K?NWFBJa_~hZ%cZ277=ch?izOh_m#il*?KB zH+#RznU~_T-iIDR?t16Lf+DVG^bt_Z%!le#Mk;Q_e1zUZ&;#N_=p+62>0rsiq-lK4 zk-3knUx@QC>mlqB@IxU6rorN-vmTN%UKRk41{V#TrpE*3vKoM2>6hS zY4qR_mSc;3^nLahPeD*qexMn$*%(AZN3CF?M#^a6JMHb3H`n#-@23E4T6*vyB*C-+ z#;d!fz|==* zO>J@d+t;7W3BrIr>}wjlM~gndASHTpu@4jW2t;(!(jRBS7$jT39RQEWyPP@sa(d~P z^846?9zY*UKlHR;JifU;DSJU@nrKe4zWO9}nTsyBf#eG?#^{i3 z8Pa!sX3Sq>bC?q;!!&nZAA~dYYJ6(&A@m^xVr{&UNA;6Qkmi-_#ohuw&VN5g!`A%v zD4H<{5!R0*n;-8xpT_AnjRGHUI`DDsUlX7YM|<}l+aN)4O&2}*P*TJJ)^)pOFG6i2 z@xG8F*$JBjNDau3KM_h>auQu3YAvt}v z#2=4787BGlf;|d!*h_kkuO4UKqfNWy2686Z^c2(h)?~wSo z{`8}jdc!DM{Ba^#2e3om>46Y>7_<=c&-3PgjqK$pW> zc5P06A1TT7I)e{oUF7hQYHU*k?E(6De0vpbUH~6ukWTZ}uf%Dza-s< zjSvW@8QmKTUDL4azDf(m@SHIL0r*%p!R87ApGSX5)Yi`NH>GxtUhj=}p7V|AfkD(q zF;9AnF5uhQ;DfR+HL+aPWDA5{CO)`!Z%>?O;$uFOB}kn$?WoS7Ro~uG#}mCCsoMf6 zrv$Apy$Qjo_v4={W$7|cL`Q}E{OC8L@VzY#r^g}+!ga&YOl>aG-MX+{A;wL|WdS~L z4(CPs-Y%QT0Hz}PVRZGkN-Y3B-oK^(Kmv_%N-nZ%>)Q7|!+5>zi{7<_UDP0(Ps0&* zoX2^7bM9h^j{1m!TgUJRCO+x|34ILt5*x#wGO(x>@4$!NPUkgI2eQ}adLRJBU{J}q z&W<{V;;T(emn26ljWlM6XCg>w>@r$m4YX=JurMWegIEb!fO=f@TIM6KixhaCAjB8= zfDeKpqIhKVZG)z+D-FRNeo1VkwiVk*YTCo~-E48MgJhw}RAqp-@<@(&5N?_}1zw0( z)NzZ0-8KDF#u8`2U;|azx-#}4=>qk!#2)*H0FN@DefM}a_D}-haim=;^nmrqJ=cEo z_|v&zP!8&JaCm?I;x5pGAe{NgQ5cfvAMGCz2}vyQhyE*B7NCbSE&iGRM1P!aC&2I` zpa<9ksVnb6k0&FvUp)PEeN=t61YM49?qG;Tb_5X_J>(ejjI+9+>+dK!?G->q z!&+C{%@blG_73MEQy)|s60~4Bm*&7r!F&t^NXJexO6DA8kB@G}NH~}C{hX?=!ixqH zx@mY3N&x9iyEC)9++^_aL(6=;!@!&e-&ynO+dS}I@jlOElM85r18nK-67-N=4N=74 zfy}DfWI@k-cyfif*#sX|y}IykFO;&6cEf0gaqmv>(e3Bx>@&<`}zFX)We(5Xh%tRBP$l=2nFW}kW?8PN;g8*R-& zV>zl__C*{ump9kuy0J^o!@wgj8qnIUTuNs((^-kx%zdGo= zN&yA|Sm;J!KZHZdy(Xf@gqW{BlDTU77qNstVLfK>kxbx!e`S4ixZ>dOX6BC)`Y6~# z=%bJ-4-^m|f*(R3N0T#U2a^EeRME$?XCe7$7vy4x@gZSRsA<%&b4 zN{h4G2jPnSTky7`tD@)Rx8t6-#ki-ezfvefczqP}q^`9E)W^j{GOv$2$%n_hLm!bG zBiG-aqe;1v=CMV?gNxbRR4#JCI(j|d_@;;#E%?Kv-#|e8lqy`-qH9hQ}=l%0N zaK~F{kbg%|0s}mY#&VN;yHE*hQh$(yK7%tZ>RZ7_cThU;LA6VcQE);nzB0Q@Fc~=` zvODe4aydJ|$5<=3m)@G&^ZAv$Kvvo(`&IA}F@{(c(-PL3GB&;cLq5uYk9WnwelHK< z{bK%GJIvuhi(B{J=%EUu*UzLJg7|IQAzK;=JjNQp(cA{iz?B&22z(#{b4J)A66ZF0 zK?lCF)~)g`p;}Oc61`LeRYM@=(1rp&_6$bCWpv0w1{%vDJ#r_$B?QoZZ}zaosDQlm zBIiM^tA|ubJ(WiTOmum09SU2o@*qr+c^dlxlxNp%AZ>M#u&V<)Xg3Ov(dsb@kfJn5 zfVZelFws9;UA^`BZKDrk4?M>7FMZv(cWs_CUI3@b1uIhx^Nplf4UNdk0$6I;%09sV%B$o6Odst@d9c{=)GZ_skv4$GaU) z#iisM9kq{sWgPsWGgmloxGn9nzfd`1m?j~BlAWqEPXqt>{*Q7EQ-)&8v5kiq%fDAgVzTlMlt5if|Kmix3WqauWXgWl}b-I>lxSO;`?m zCVE>lL?&(LNKhhAjhE4{v@G|{6@@0!!FZYBLKf7r_C{fDa%+VNy~gr-V0| zv(}ElCF!T4EE!Ac+;lc)d}~4I3wi<{7t4EX{M9!Ki2tP;)PFvfq!0o4`0LBHsxsyv z=ojDvjf|O(G6>6+e?0EeF3SLXTr~J-lZd#3mjYN0ISyolSB)ZCewNP%)h_AFQKk$y zLYn6y(q>5;_+!&|4{Zn+aU&Aax0%vS*y96He%)B%UGIh;`lFxD(xomgD8oKE!!ZYb zG@Z`}N80yEO~h=k{iJd-f~yH#;+zfZz(@5WU8YM~{2|{6cr#46M0?QP11)&HL?P%1 zlNOUB;HHgc!suQgTjcXG_TXczYkEMnYu@w_9=N1mHdV5iIxFCP?6}xGms&(DMiqm@ zySX9npeJIEO-h?*F?*N^gSqOYJ+||aAqf%O&@;{qKMory%Y6Fq`qxsOrdYnVZ*=J651*`08}uRQF{jArN;u6}v%Sq|Y3K@Y?pIX)|K`{QBm3_imOJW}NJHzepW zuqEi8*!QdzknTH7^_7N3;UV#WO=%Gb!QV|e@cQUA9}AjU)W=b2g+Wh#x47-;?Dd~7 z6!4L@=(IV>^H?-q`15==9SeMvNwgC>8shs1+bMF~=-V6JJ*M@aWt%GD?6yS8|3$Ra zM+P6$4ETuJ&05gexU95mr4h@~cY_ZcPV?X~plO&7LF)Yl_(1yFYd(H7_~?%QCioC! zOo64sJ46pQ?qrUD11GboXYg)0P4rN0E;;|LjLfba{M~H<+dBzEua4B62svqMx~@kx zkuJpoc-T|WX|lp_gn-}ds(o06M2uW*yiuZFpxBt{|FM%keK}PK>&imDJ?yqFH!5J|a+JECX!6qmxZ9=MLa90IVoeyE0_#(V&lIPg{TG zoXf{^0UuEcae%5a&9z^qoJ$I$k1p?`DCpz2*<0-Or|ZLP7}*%-mw(g!^=B{cd}yty z(=Pg|fzL)U_)2;YQ3UE_+Mo}@aD%%l#O_FM1) z;!uPKW(FTG|N6m&uol^2Sh`dUDlX(Vl>YzkMnPnokG;C^-7N6IfGZ(vz&O#dDIz~g zZFhl>UA@qP< zjWH^$?*9#0>^r%vtqIBe5qI;?4cBDmu@amQp_ zH6ONu4cB?=>d-BsJn2QMu{{Ae z2oL2Tl~Qk=_$wZcCrPQ=ML{U{PaeKddWTY50S^#}lpoTjX71zWdO>@PvtxadxR0`H z556|-A>u>42k=AK?dB?PX0>NuLKTLl7*4uYvJ*s?pR&gMN$Lp zLU?`PD`1sNI1V1J&%Sllj`qUl>5lDvN*z4uKN`G^&DSr^_6g|bSv|%Z2S*n*U&Qt_ zBJ>nWZ9DM6qJ3L$7Y@CxD(M>IQj)%D*%07(e*k=tc6mGaFnAZd8ET0sW#*1_d%L9r z!Uf&rw|GO~U#YVry3nk@7vyw(`Mau=c6FJ%_+zm;g_#;X>r1N}U?3LqwNW`hvd%#v zu)z*uk+ZPF`hM6;cu5cVXfqphwp_|n(bT{sFae^5bC7Rrhw%3U(T<-ulegW0U$QN>jz7kLSH9 zl0??vifBkPR>WoBnTMME-JsN7^S49sZb)en(?ny{%0KMD@54A3nad4n28%+70@6^!fo} z5AhyqrZ3H@i4Qf$d38KvWZNwMJ@6m#_!mgV34Q$H>#y&0B`*Z^E`}d>GWrnma5U)S*IDiHb;2GAbSMlx zKp)cWK6(E1)(U<|8;r{2VRh@-4S0{P&_!973_cS27=%5164*ys;kx<-J|L)uqopFF zvh(4A)aXmj5t#O!4c$zfA?4U?mFdFnY5v>!i@KTuKL~-3SKr_7z(;eM%{4u+PQ=IC z4K|X)SSlc$-VHwXHkR5PsYO48JU`FtwCc|9v_~JjnTy|_5tlSuIxabQnBWQA=KlKx z&+WIsrg#EzJd{Qa)dIQ++Y1pz@1b<`yY1CCG#{!k$`Q-XDw~WOcJw8*V&4Tmh;86Q zkW#N!I0B~X)&#qz9%~|eM-2k~M(HuF)2~wwNS5?U*ugAW#O@x0eN-mzgVgzG&{i46 zapc@oKVaP8Xi17zS1I<#P2@p&-a~${>v)&Sfws~-oGKkLZ#5;|etReM)>j-sNRufj zIc3j;o7xL+3mI3Kw}*P!Ghz&dwkftYKZhm#V_eb z4Hvpx|3mgvuaKhbS0rB!1!-VErX6TwDr%81NR$vOpaZ@v-B&jmO8E8B^ozi^B^4dVVC80(nCO_BVR2S5J>-sgFvBYjxp4HU` z1CL%#MZ&-l9@NSYMFB?|bLj%~=fA@9k&l9@qwH(5XgY3F36{}^c1r3^3qLe=t<^N? zZ+HCBSB-vZE5ZRWew^y`b%{Xk&`K5D3uLH<-OW7bc^EH%usNk7H}pKb5?f-j6?=?sh8v!Cmh(2G_Y_hXh++@qz9o^tM~=8*#z>BWQ3d3oT){^L+o{I(lUo8G z7MvPpl!T6Bns4RTREw43hX0e6^rmKj2bTCPze;6pDIB`=BkxDd2~ zqeUO-;q&KT{rQ-_%Tpx5U_LZqX5A-x4+6cXh!2ZyToxek5fh-v_fVa(c!I2k({cOw zw3@w8qU-`IS~&6ypGv6GhZv{-Xk^eO*`s24nlx`Kcdcn=myU!bP|2s^7t8-GU2ToV z^m9A-h^uV4b*ZGrH86V_4aRL~<{jYU+}pv2XJh#i=(Rx20-2I5Sa;fcSo-YQD7PKE zvw&-RIVi`IZ1ouC1ek*m`q-+*))CC;LpA2X=G4ouZcruf=sm^w#i)Hz`KoJ^Qsc+dA6i_t- ziF8e&Jce!HW85&@0DSP~vB>sl;ph+u%G&y1p55qiU6bU{qg1(I!tOAix2(J7#$a5( zKX~7KB}AoKu!bLFh*^!0utyFwA06{yi?K%^tMHQu?Nv1C5(3VU2$ z<2^YBnVAb_ri?wlHuzw&x40uk`Y#^(FhBMBldA*n?2DLoMVnjE1N@FU^=9ZFq|D2+ z^q#uJPg`W$Fdw31UcA0Nm!pNyXI9)_pFDi*?ab@> zS^^y6J&=4TI`nZk=S(FCe^7WTMX!%14TL0kgKN%aaL%`-{e9-8z6!`s(00$9kNb(}p(s3nv{p z3Ue`qDb{%y9X|v?cs4YjAu_+;zM(#00Rq6(-(1i~dn{2vb7;eM2wFGnH z{jQg7MSRG$mdW*{>C+H?vLJktTfsY)Z8l05uMg&{H&YmW?9_bR_~yySgJ*aa!P1&e zM>n2467M1C(OaAfdOV1ha=(4@%XMRW9ZUIPl|amVo19C>d>DBsexY*J53fHu)!Qm` zjQcv5y6_D9SfwrEP>*w$ILKc{An^Ptuk@_6p#^=Y#>LUMf4Ou0?(47CnXKrAAF8;0 z;8LLUwL~9=9>mjJ^CIELlK2392zfw!G`bJPm7{setcQK&iavQr-{Yvnil-3x(XKy3 zk0vYp)envUPH~=67?~hM9EPnugh~& z$u-=6`Raq+;6oLqiTJn#SXO3Sl0!A*itAk3ak=Plg-g+avoT|kQQ#vfP6a-A?~OW8 zep>g>O0HvO&EUg8Fkp!-aHLp3)!*q6qQ`!G#@bZ3*z%S^=$Jh9-8)%-4JA zbpw1XC)dqVTh!C^NVRrAgt4k64LvluY-c`FyjAl-*&uEOV=O8e(HM(FfI7O|>64&QE)aP_a}4&N&@G!fW(R(c;3y&$ke95}o-Ut>irdwH$ED#}#?>vGpd{a?@&? z-Y&s>j6(}-l-aP+nwCmfFIMmOed@J`v1RPU{!#nq6OG1O)L+-~qA+OGkM?K)^C&Jd zf@n*3m0Rhu?QsTKXdAcaeABf>)Jdgp=y03LTP4-0Qp&GpVGp5?UU7=eSi&BUel^Q5 zq4qN!3$`u1#}`jB^nm$Dfyb$+4>2FPnOw#m(=-q+1wEM8x9^xc=+vEs@F-t3GW>X9 z>=6evA5KLf{FQBi&mg4eh#*OwZ?}Y>KdfT-exo$m#amSY^Z*E%x(g7~P|z%0`Ig%7D^=XcSSX=y@vChoDEV z*Wli_^U2|~l-89SdEib{u?)%GGH`m>Qk?ke+?#|GC{C2EdNhy|qnPeSp1dzN+ix)x z8JgpQd)9vo=40WNwy2BzVeRg`8bpgme?;6@O)_vqcbWM3ODT~YdPEQUQS@b-Mu6@( z!RvSEBQEq|4uQ%|;y9Hq+BK4Lm%giQ`(f@(yT}$?RClO04L+oYbo$?y{mrxsSm&*2 z7k|_)Q{OETFk{poNn%l+%UFr5r{I8M%Gd)lIwV2vBuAmv2d|Q0O+HTXTRp*1fk)n0 zZjhsVndQ2nG!7n(hY4ho!uQP*@xu61&CF(*NQHWUgppJgFKwZ8z7D`LjB z9u&7tfNKS5xe}8!P;tq{; z-xkUeJ@|D-9~p8S8+(MN{9u|-AHDd)1CR&A$0qhjsP6eEGcc`-D_Y_LOY`xZRUfSD zwpOZS>f@};GBR2N)`V^S(Xl-~w3%M=aUn-0J}USaJ%wq#XCQ*(P8FkbJUuqevkQD= z(Z@MR7xMOPiXnM+0Y37`d1o%gx3N{@X^Nec2_^$Hl;C37xel;tYDjUf45!Rq5QjPJ z^3qszFdO#je5$*^htP+%+Zs~^M9R~{W?}~BB-*pN_maLM>lVRJv#IO_(;6Ri=iE{>%w$teJf*+6rvD-Aa)n4#K*5+l;&(N9-ba(Q&7W<+K?md z0YktQ8!N~5LKvx+1HgwG=N<3gcp=>fgaiYiR#p}=K%zY?Kn}4pwo8ZSR>O<%QbFf~qdG5`8raos1Q_D6>Ia&X3o~0te^ph^r z$>Sp~(}Tms{IT#;KW-UK(6y?!CxC?w->B?Xf=&G5)h!K7O=35}2UT4qe4|GaxvrG2h~a6_ z>?e|uiq447HaJ2be>5QUFYOGX9Si4%Lj{y1=XaV4Xf^M1}R=J4MJaR3y z$liQOS%&GokZA^d6nsv1Pb6cj%j8@DADigon}?TIwZyiT@n{7(AARxgUW$d}qXb4D zc$_{6?14aZN|DEL!X7ul9>5RKNBE58h_ac7r!wt;aV}&1K;>1ngXtt82+0?k2TI@J z#YQ|x>LrRx4L|1L+4a&Rug$b<24avq8GW2g6GFkfDK+66K6)i*p{{5G{<3&A*7teoo*A&)T)?E`MGoE7~c?1+Hg4j0TA9;9~%M zj8V_mT>F#~C=;umt6y#kPTwc(GFbBwqfxJiLomLX^4;0mBxA!k)Eyc^HXL;vET*uqvbwQ4cFd4pL^ObsE%Vvhtj>Hta<9M_r^eU zB^`yA3+uWA#O9r+a`gNQTNI_uS4$sMrpGV>CrQ)KolfXf*@kRXoa9ixf@wM+qF1Ub zPFL_sC0}$qy=>bt}KAChmZ&0V-tOR@#VeC zD}e>uklN&9nC>6lcz7>IOME;h?b14ZBr4$UlaJMT{Ev$C>*0E@!Zp zf=%D>a`4UiOw@rRz(es}7x8iaEgf8QsmrDLNXhZC6LdX~Hma7LY2RH5p}iuM^R#=< zsC4`Mw{sV^ye_R=a^6J|rpU{rii5UOB?9(1;yEqN(PshpW1`Elq^L7g4^gb3Yzh*I zX#qZvq+-ZFYzH6x2eZ}TROD0JSPmyCLl8R1P`5B_FdtoY&0E2TX3stoZlFDF$(8H3 zagQGvDapSGGGCwu^TS3vw_HBYD3HL4qY#@YY6PBEkkh zGzc@=y%NE+}l`gKC`BBzv^$QWvX8QeC70|T+biAUguTw||uLNI-UoeF!jAr+~$ zJd9ZQ6~s4z)H=(AwgpgoHI`&LK!ymVs`zrtm-+y^?|$OK9zc(l`p6OJDcC)s13#`80P-U79z%g1 zT3Lv>VBseZSAQmE*Z>{*mYjc~1-TlV5Lsl*lW*!g|LGS6ANh^)ZlOJrFeHE7$*tou z_i<9{J#lll(ffS)@!fiv z%+s)6(JXmBW_gx~&79Qq;atd0t+*!YY2);&7r_0Dr!WHPbFGY1&R&HCG)=|dgJr;8i1K`SQ&=EQ%S>`v zQAelH>rcr$D!m3~T3g!V<(D5RbLrd<9OC@i+-~K2;aABD!2MeLh_@8Y$QL?~&f2#7 zurS{x@D`^>tI-;B3Rlz)e2_|eC-?}pZ|jYn(2w`See39_SkxPm-E`pN?V1m2Lee+j zgL=*7M2j*6!)u5zidwpwPMtetydBP$en{h>_xI@A#TAfz{>M3!fw_k2CrOns&gJRL zIGD7LtW%smzI*R5Js_p|7WparhwXBI-lj$HQyuQnfKcY#xF>w)%_- zc?f!>`1F&HPv#=r)=m$s69o~vcB~A^PFK3$(CK?9GJGOLOnuu%fMM&KJ{@2k(SQ=v zAZ?mPp~{F%ee5oi4et5PdaBSvd%BWQS@Q0he>k6+lZ#ArlqE`qdg1&J+1!+#(P5w| z@ZrUkk$zCHG?GVbV9VBk$)mu>%OoaT^v7%JB4hdb)B3R3TuwQtpoIo^`R0Lsc7$|! z7_|-2+ZD048Q2AHJ;EOWOq9#^*-ST?vR-QI4>CINl{y3`+ch6>5u{x%EUR63C+?Q+ z3___S_j~YD^MhzUepcE=UKXS9C6b7ZVQu8eS<;FlF+6j$JmOfaz@;@E?*D*j1JkuO zs@~&=OIetdBcTuJgy*H2yTsQSvqX8-B8kfNZm*Jh%c2sg0ZjM@kgMke`IBzvjNmY5-9ZGO* zeLMKzGtiTx)v>@w!pT#$Z^R=vqIFh?!nZNyTomR#toac3$h~bp&);8ses!qGV;pIW zmwAszF6{B?wNDfJ*b{}XT$K!$Lpg9A5CsM zQy;Z1c~)PXlB_G>BPl+@iM<6MxG|;3iScQS$+WW40Y2pZht!b(`alK0PHIB3UV_o7 zN#T0$zjJmz+)W%;6t}&*0;FsWX=3wN#0g30AxWJa($XZ9l!ibE=fL6nf0)k9eRqDd zBdPx$*p_5@rCrVL+_~?*`-bVa>oieIOk) zdcmn)4mZ_Z^4pf&h&Ci1Yh-8))ak_(^ExZ{4thrCB+-{eeLl7eh z!6OMRaDWeNJBJY=0s~f$)y8t38Bwe)#~8ivv|}EhOz$f_-~iui9~a<51n9|XNs@@v zD~GHm+SumGV8%hZ1nv~b<^xEa9LTURs2a605-=419c>9mM;Vu_t`|EMDD$|5BLd$I z-80r@hv933^~V-w7i{y9YHUfo>@pv@HTzeeoext~xj6L`lh8V_N1h*3>}Nin06$Wm zWIM%1h~fAoTWEZ3^R7P<^ic`u0rTM0Druza+HORPuhH0Gas-tHxX4Q z!4r&Trs&j?%}AvCpt7ajD%eABHh+^y<@ujJpU-jmrpf*=Z|@|h^{1Kn0DDmAV&=mH z$Y1_;uPA10))~qVp^w`ceWb5i_p$&V1$rd#QP9U&G3iLFTa6{Ey$1*5m8c0xL6K#1 zPM(dnS#aEoaiKijhui4nj>miGeM*%|-egV%FH~iMJQ~?Vw#t}_m-?Lhj!bLIofGy* z{nW4Y;G^@Q){2s)A&Lbq8R2Ka<6WYvR{fCvH~yI4T-{;Sxvw9;&1aX>X#+lXjg>IV z?<@VM1Hw^~GbI2YaqYp)qs0fD8+tio9#2A?)QCvNLk6J1YK>C_;dkxo+c)!BzAEX$P8!zCo|d=^Khv)8)jLGB zC(%xibwpC2Om_!9MKl;V79xD?V8sY{Tk=huYh-=>AfLSTJ|g;vo=)DGw6bZOIOYzwdL|3&Xrxm(T@t(Vwu;b@IA7 z4oAuIAlXkn!V1KFkVK6MTMxn>DKHr8s$E3hKltk2W{{=@MmY>$$hq{;1JTD5Q6J(x z{&FWbJ6ZMMV@TNJtFLX})kRF1`!!Zi_z1@)w99Agj4lKdfR{p1l@ZJ8G#*c%>5!C{)5g z(SQifZwC)>9uQ4yedR53b6b|HO-`GUg zj=Ix!wGGY3>;LHUaibHQww0)~CGZY)O6iaY_Xml!ZQozt`kwW)ePs)p-ooZu7gvA3 zoYyADrUbAh#r6qsoz9E9{La;vzs%v_-}YP>D)_+Zv{Tj$d!!lrmMGr09R06%z($Ke zDyED{H`4vaGrec#r${6dm{R`2%HLQY7qge>0f;iWAM)V@g`nj6D=P@S|fsO3r0I zlSR1lM{cCJp0{5;w{LmmFM0r?Ux-OaKQs22RGpsrGr1YVN{K7aJ8)uh}*BS()4L5C&QXPNp4Pe&A+fDcn2Yk`jtH#k}wZ9UPo<0fREiYLy{7Hdzm9E zm30Vl33PsJ!s(v;d|&j*9qXKQr?*RXanVluDhsLj{Gu5_y06D_fQnmekI6GGu%xl~ zceN!DoOYUzBC}Bj%+q>UNiWq?9hID8m-gEC^53Ihx9;QF;_ppul;&CPqGh^^FXEq-(C}Z27P#xcSd$X zANhD1dkB2ci?`c5K2PyKqT%~z$^EUJb88K;AE2iUf4VRcjzJ`jwQ1Kw24dGW)OGHd ztfP?}VBF-)z~tV(z7usBLg$GClQFfQ2%it-A9Ttz;Nv*J2euTQdVY_Qt1#N4=sl3f z(IUGN)wErZuwj6a0pNA9@acVdmRAA+X>Wo{a&6&DnTx>($S;H)`midl)9yf>DnRTp@Ov=7Z*dzMJrPyPb z5x4`rN79-O>onV{pj(QlrXHPYa0N2Ij?1SW5|nGw10?SUrlV?hI?n${@AS)pmp~rC zB*73;GJpQ_AD(==JyXJk&_ZRt^S9^59?%{Q{>b0+O+E6rTk|@TK71g;4#_S&p^r}T zu?s#*=H=G;JdF|>jSUR9jDay}9$RCd1B=4oQq0|Lb zH$YHjmYLt=yb(SQidIaRRUg70va}&>4)Jkl>4}YZ*M+-teAWgXOZ&u_yq9?!Z;Id{ zN_9PwczZ`MiCIUTZ|p>;^pPG4DU%L{F}=Z`tuJAY_S{b!AEYLoX|(k zyEMnsxey^c?E%Y^h#oXRadqv1SjaKy@p6m)KUCcK37w%3^IT{!YT6Fm6R`le3q@xS z2K7_TP4K#)@Q>Z6w~OXh>~#%3AB{=Q@7L+gi zGcs%ES``ClPJbO`r5G+Xf2d%*`A?SqY-M9@+n@FC1W zbj-(I@Zm~Jn~b6LI95H3)rY&_UjDMZ0kM~`$NF;0=;H%1BRkld?M1#XqmQ#yX@E&}WOdx!NxN``=+dOz?i=~` zld$oy#}|MB;bVYy9CwWr7>$l7i@1si(fHn}nQaAnvS`AWLh zdjW?`t-BC9IZ`D;?o6=T1e|vYi&*7~-ZBbQ+?1$Ht+=?1{-ClMhliLHK2I7KQ0ba? zAecYR4iHxUL`N1j!SzlFOsqe;cfZFTMjxm?GWOUU=OnX%Oan*9lymv!k--OzT{?qP zX+F~TufNH9k98aoQ?dz(WW9%qL(Fk#*7kipMC8)dAI^_AYbieBs<`BmYcVy@+XY)p zqzo~Fm?C(fjGO#lbKZLX;t%fgqPH5~QOP#QL+IoFyul6)zcD$j3wwz7C=i4Y^O3)# zI{nKnl|G{&!SnOx=U+Skd%%1s;&adF68@GBdrX^o?%Gw-gx&@8jh!$C{(>u*kl+{;pc zYk&gKQG!%Qy+~CjH#%aYfWS?xRUhEFnIWmZdfGy<+oFf})pztE>kP#eAF-K_?K17c zjCrWk7NC5*V#~GNA4Sg=|Ndut^~2RJqLbqY;<7$Xd*CNWd~Dscs|p0O7TTh#jC`6h z_DIMeBj*Jq+GX~xzx`!9&Ix-UX(}USvwej{2*8#@N@Vo0-JIsok&77irCl`fP)=@< zg95yJ((A`}D{C8gHoyr7*s)U(p)Ipff*NsB2ZR$Ef(T5{F}^WVu+bq=owwqwQYjGN zL)l^y42zC@bkSAVJKG0?eu9evzoiWcOsjT-^Ezs6O{msdPy9lT*z&TsUq{3A;1CVB zqdI&Hyyr4Jbc&fkXHtkJ#}=fI!BrovKfKrT9zq|AT5bFA)3a6W<}xlR(}Fz`_(;(Z zAA9Z9GXVMeyYpG?C``$u$kRu{9uHF=+r(#pH{w45^O2Pn&mWzQn@z?ZeD)-nQ!q!l z+px=^c7`oC+vtIZ#;GB4=mv)Q^Yo^(H3?A3KZtNGN%1tHk9*s*^=8rFU-M^5VSWF& zI*a9R0DS0HLLZi(92>dOE;P28&dADsJe3rZfJo3$sDs~B>m1Od zl=Vr4avp0P&2HpAmhV{1UtvHYbc@UhI(JnH)*l3nZ}_phy_k+!%!w3 zL-NAl(}p9ecoiaiPuiuoI0bxM>C-M!0^qfh4UVi30C2@>+O+y_sHll6z6-uE0tt!?_sKghg1 z$k<~O;6qW-aGETQJ-#vc0DE*c9|?Q>DPs?roQy2m|e{Fr$>{{-`qzsBu@RB`*|m%ZNy$jNqTHGcYRTb;%xN6zAp z+w*Up2yF;?q^SG{b{~p#(7(U6=#OLYA@orSmmavEO9wvyo%e4J>moc5aYO`}6sjRe z3CD3~nawpv%^48aD4-Cjs-02*v}?aLph*t^dzZdUeTX`c*N4#u;rSzDk5n*nc3#29 zRO%e&?XTCR$J;0R(8I|Dp|f-Cnp?GtEL;`KL;DMp(O4Fj)5NcjH-5YFB1#$nANr=q z_ug%%IWKQL`A5Xyp8|Ra^_k2Nj#zXB+n4(Q4d??wm@Yn8oZ5E2OsOl|>q2`>(_Xzv zmy@E}WmoD?v%OQ8523NW-~-KvGfz2m{KGC!--HRQN7DR7HsQb3eDppa2d*PBl558Y zV42iQmyL{ONm^Z(r<|&SJRgG{=a=1MalLfL&woOf4M`#6%(#Y42+{i4IdzljWwxhj zc%4T17U<(hS^j)m%HFORq`z!JXB@iH_V%QWq#|C&{d(#(-I^&##y(%j_P{EZFA)PM zhL6Hc6%jsxTZ~BhPg}OY0Y0REC_6yOpEkf&2;6PzVM0g>Rnc7)r9hop2aj4^Tko@H zB**hDOb)xziFnP9G=3Hm3vJX@2~Z*KlQdNM&0zH5(&wcg)s%RTq&iGt^a1=>n4Lbn zw<(KD=~%K@Z4$q7a=f1JJo@I5!3SxV#$H_^^zqZ59-U>MreW;jB=a7BP);HO?2&_; z6s`VqGs$griL`x>YK#v5mZ})XPCY`GyVV2z#AlNnQ5Tze`|0B^pH{OmkQ1R+HDq3% zezvvM7}IZ|w6|xEe)=BhVfcaSRJcR&C^@aq8{-%y%nd$L?e3=qeVFzDdvxgIUe3I% zP9!X2N;B&b8CPE?+KySyZxM7aYCH`6xP{uS5~O!51zEsN_c{?c#sKn`6 zVuTIiu*y<2%-hS_T0i(r1~Qi-4r8|x<>`xx6lnF1E2bGidd57D^W~e^HI6pLDOTkju=X9t<(zfS+uj&cmRB~C8&GA z#~7S|#2VE)1kPO9-5DG z)>uiW#=G1YrcdaxK{Fqj`*?qu@NGI+<#Hd}ic)6#S&kuk=!X$)O?Id>Rucpk7kJ}( zYZ6VwtnCkuk&J*RA8E+g73Cc5qKGyRBbG(D-{Am<9y{P{fK}E@#8jCNieLhKSj_>= zmG44dh?a;WvIj=d;QVD=crm>2Sk4L8l6xiBn zh{PeGER^!YzIErK^9Yk=`O00Nrf(DaklzPyz2iL^>f>qp|Hr2fw&%tk(d*WjVSVxQ z_tYu>jl!1&_IOm{*>}=?1c{R0pM>9YzVc-B@xZi)B0-Hk+($+qw9kk46iYoGtBl=q zDP(=0yrpeadx|+Jqx-_*h9&^~az8z*J`tGH%x;yWJ~Ee^erozSoip{}E?NY6i+tnl zIa1T9^m^IKgIa&tyL{>K?EYBv9&0i`Qf(NWt#m~kspE&(IL50DgF@BK>nIs~B=EG` z-=!B>zTW~qbWt-*%wHp&Dkn(hrBHw0m{0%8f3o39Vc?FPel;ga!MnFF-@kjaP5@-e zhjE<_Nm&6{U8nZQWB7R;)8|dvKeFYv92#q5aLZ+PH6IcG5q$WJjyWhjBJh#EG+p&o zZU?~!NB?kRIaSzo1>X|*KrK2mKr836*kiC* z`L-(rNk3K1$^>X4kq*}?J1M7t`@NsEvpZ#{y}ib02)@rXwB~PQe8G%t1yslvdhnq) zQ;w8?fC6K-&R5UDgUTegDgf9S)EgQ~OV=^&Kxdz}XkrcS)kCIjc{@HRv<`)viogkk zs;B&4Ve0qH|g&Si7+?yXyQQy6`GO6Db^Ok7{x9fq(o)Xq6=zn&`gDCmP? zTM-{S%*W4#_fW%S07$-_jmrP19{RMg1%GtFqv$<8dAOd6dW1xo<$Ee`&FI5kr=X@Dc__S_;rEdbrm=@&yUOT8$PM(-5Fdr}h`4x^ zGB4|m1tiq3WqxPAlh8*eHbwJsKmRcL$bKIYfDbin6{H)ET?uzMP&z80;#U}AQU_KQ z$N7*YPp{)RYgX^tN8weDTx zT4HQJ`0$}%&a~zOhf``@s{Peyhk>Cs&7kY4irjk52UzDnfseAQnsXeKQXnm39QVas zjV7R5B1OxIO~xJt5&($wUD06bw1*?Tq0Kt&-n9(cuGRe`P+LnHm3Y3( z8!~T$1B9dF%GA6aha>ee|@4cn=?ouC4rh z^WwW_;yspv(^j$2VUMvaRC53mrqk_%LXPPF1VD@qDUy`fb zIsiVP3L(P?D!6dN69CgupNBNRy zq`+(}g?W#HKAt^#_Uz)(H@9bHfcT7@6B<6U-n3&q?k^*$P9-4#6moaa8d4`cW#Nb1 zx_3@#03wyP;xJc``n^PoJ399OADygKpYQ3Mqfj3P4p$d}k@U;;S+NPt0^f9q0R$1=AEz6^ZM(&eP%bR1;AE$gjV>`(;QBNN$az zabbcFQ1G&SxAa5c!#{VyM=8_-e5AYTWb5+dI8<7oLfLeg7jSH&U3%1-l<*m)wVo0%W>rep2qBJu$BMswb&mpyqjY@W5I_mHkMV-E=lZw*4 zn7&Fh?dJvgdz{S)TSt*QO8+H57(@h!bkxvVsSZ%$(}l$^tiu8|sh|frz2v3U*`Zed z=I2#2?v=~`3c1=z|LJ_tD!GrGt??^KgrKPXCbbvVMtNIY%TVR?P4xAsY_9da{2%=m zBGz|4zI|Kh1MZ`<`N*N1i@0Xzr$Xwm4(uW7L$RYc^&BefF_#`~eSP3`WBZwq2k2wb zE=7U2*yB&0U#yNd*~-&R?yM-nx&8m-uBU78V5LF*Gj?q_S^a!a0W#nxI9&z zx+v8u9>@ipNAo+m$V$9>O#oy{0OZ>n1%SlPd&0$To=Ji@9;iz61xgjBdwaVOdjzK= zX7KuogpO6z)W4PK>?HUPoi;uA@T(mLA8su;G`(Gp4FDJF2Ke=zhL`v=Xo68D*R2vS z=jk^~fck)wQF&Bi=1wn9i;~aa7+cT0)q)Qba71<50uRQ0J+2vjWVoqA77n^7K&@#g zD_?4yNxeFzR=LTnNSC06gTG6^y@1UB^os5bSU<$Eqt7T|)-%vguuXNk)q6xz*~%>- zpyI(QevJWZ?BPD8X4C{eRAQrnfW10z5TdkM74rt5dZRF&Q=1BTm(XY7$HZfxT&VE8h_jOsl%i7R{+PfS}zdfP?&JU1w39fgQu*b(A3w!`SY_IOFwzk1n1C_IR{QePD1}96SGXv69-2 z_40|($MfeG>ui+45sx9<4t?}Qhyz;)dZ6ru2fApCA*YEV&pJ(g=_=sJp zd)AU4kF(e5y?HYVP^R($u*aNLr%!z3z#ax4LLZ_&E;9PK_;6Mdli5bTWoKvS_rDF-OE~)P0eWkYjq}ziJ zn@(`p?XVpylc;vFve1<;Xg&^skG=Nl`skz4tMW?qND`orskz^}c?1a8?=@rx0!HKdv@O^}8Og>|y)+^@-G2HMy+{71NgLt=wMU-WbIxToTWG3?QCzPs_C4w4 z_k(}pC!v6P?tUT+b09bLGemK&3-|HIPYV1n=|RSY{fqmL(~l>K`xtHcyy%xRpMUo_ zAGjWSEQ{-?8t-I?NoJWo$zLa$BeK)T&!;r82|OLNv&2pN-S#{!Wv4ZgWnE!y ze>5(~JMZIgComBOo=Uul5%7@@?(Z=_SI$4peAa-xxty~GB#Thju~=$NcPKw5IEGZB z9s(c4VS9DrSpNYZiuOI|+o7}z;A5}Dsf!Lf*$-(ff`G?M(Uw@^t!eOadSm-8?VhqE z2SbD5N^0n`kz~2+u2eR~|H#`;^)BX6cmkRHVU!d?Xa(3Ul=KATB%} z9Lp-vLDe25Kd*SIZKl!^V5uP;`kzpi1|KOLMZh>ASjoYT?+Dc1>48TaDN~EtD_cYB9npP_}PC$!aeevqsEL_o~ zB1Dg@-ar;r9yLmSRm>exM2SA7Tv*&v-dF)2i7a|8|92@;suuHF!6E`6=LvwE)b7uo z^9wt$N7ECDedw7(;G;hn1|QcgI3*ak@*i~vG5}D#+-kR_KCrcSI6c@{&P9xf{f-Yz zg@6y^Pz~j#CQn8^Q#NwjzI$=yx<=q$7>c=RZU?u{#M#2votiv>5224#xr@LF@UchX zaxHNmlTupF9OCg*FSn6_1bp;i^DAaX$|kuq13$^nD&G>TaeFCd#n@2(?t8 zx|&`dA7r-Uw;^#szS}qTtbKyRuSQQNyMhCg-it=MZp0K(^JFfpb!Wk`t#*<`Mi=?O z9^_p5iWhi~+;yvn^0d}tc|OhOUtK(Wcv0cUcT1l!D?U>6*kc{;%2PBn+1^Xo1IdSG z=`O7I_|u>MRP-K0dQW1n3)rmPZldn7buEglox2nE#*RIRLoVDa23_kDi*y(;6vLab zWL{Dv@X-o9bi37`I{xtZ(}F&#&Xat}aQ-Nvj}Ch%jP(lZ^ejdC7%o2Aw%{YSRp7_@ z$Fh#w&AW8yBXJ*|n0n2}aUm7UEasMy5%~2lmI%A4?(zlrs7lmca?J`TF6)p^xSHzK z42g#fN9>GHs1MREJK&>GALA_QWBW_zXigMU)b#)AyCQhd=&v1=bYbjN_dag+{m}|4 zp5i%~ebJw&gLiw-??!gDIwikQ|4saqnDKJ=YN-O4J zVH=?bY%9_;AH**B7!5wqe01H@8*V+D`TRae<>5%?W#K zFQ*Z*t!ze2iY9uIA6ZEv-;f-8GL5{5j_r$g+taMF26a?dfKa)(hlgx!4bMlUU6`8s z$_ot|xWuj4I^zhhDs2;{bcX7s0Uy1dZ-Eay#2NJYA*~^G*y}||0xV>)-Pws;8s%fj z9xJb?M=YzhBt_UvS^#K9kW!yufw^!oC3@IqjYhSf1amxV;mv{fdS~asR(SpXaTeh` zP>tF;TM*7WVG)fC3yM1+I;=l}_NbJ5n|BfO@x{Ztn}R*^p|aR$)WAsCl3L{m63E{A8pj%X=r&+V9>G2>>eeKtIHQo^Tczq4RBkZq?op3>-p|^%a>}(%p@RA}6$LJ>~U*rDYrLQIna5D|xwlW+w4O{hP{{ zZQmuC?&=9A^nZIQ4OKQrU(FP?1HgE+E)CB13v;hZEFcEt<(qk3rcg%EBCid-3}nM- z4DfNf+ftwOK+k-5$kJ;is{gP)*4hoyT#Lor6?zAJT=_4+$C1HDAetq*^F5M=iWsV1 z`cGsb6k|cqrwMyp`CzYXnutS?U?_SIoN(}N7ZNGhyf~&_X^YAUzW}HvqmOCKWQ@!J z2r*U~a`_||pkzofy)x<-vydIVJ3^WUYY_ukba~JKkh=)+KSTyk!(!4AGcySuRuBuM z;G52}=u!4hE%k+w)c+>z{k4MAWs{0Y+yN9Y8Ex>0-ZbDtfj&hKwROVE(D+W^sxGO6 zl8$%6)-n7j&+g5`m5@b>+l_i*urR}AS__8wc>U3>Cgq}7dW}i)@zw41`YgbQ%r~Q{ z)X50;$k7lVDIh*bx;(GEN0-rGZ?<=T%-93!1JNnaqt$#omv$sJ#31K#prPQXLzSw* zrS}1?ko_AbSWYF+pF7CW+1p9`bDFsi`FeDF)WQ$fyJXJi%P04?)6B@)t&pF-2;4(duc-4$DQG%eoDrzxiF2)1@LB*Uln`PlM{fJdjcl*( z4{JjMd$P5)@RfsZmt+TCHJ=LbuoHhv}K{wy)_@A8hVcn?y<%g zttQ}9?_%tH+6Z$k6-s8_3R^c`GAps^o{6NY)q-@?#ZBEkJY6-o6T#FVWDJ98m(4D+SeVNFCK!~RB<$gjR>pGgNgMr;A_tgfq zK$}J%ZRPUH1W{d*K_4aFi94@$ z-?>};-Xx8Pk68=xpw004sPArJpxemH8Y!w<>sLKKVta=^uk~>GJ`wKy!qhi0W61qS zi{XdZF2hb}jpb*fyY*fAmrB}8r*0LG>1JyM)|V-^Zkb;-<;<4-RveQz(^IO{sK1|j{v-eeJCJ{bJ1L8sx zJuJAaqkxE_4crQyB5|jpO=)DC>4)A|zI$V8w!AqN)H~)7;2wi_r7Rgvgg(;N3s5A0 z>$S4#gR5^}ZG~)3-L=!pS#3_`r3G$b!(GCH$6;Z0ivER!>J&j$t6oCcIDm3P*_n1Z zimS^B+oNRxMRq03Iks)){5L$!5RtZn#~MbhO-c3P6Z7F}mon5*9n!;%B`vB9VHDc8A(8}_g= z6LY$~^`o#y$9xb`v0B=>WbE-s*kh$6cPoMdX0e(SG9itqXmPH+*jn%rx}jdU%^8IA z2h07qfNTo-NL^|kchE!stoQ(X6!dX>I|*J-4q2s7^YF#rggkyo|2w^@n2&@x67DGf zzf0(2ZK50@P&xLXk9+xxfC14^xOL}vEk+cs$ZX^?ji-Ds;2FwS4{7MqU)AO6fDg*n z5okt6mg!p$lim%~3C`&%Up7H~G~ffyqg>L9UHWMeAYHx<*NS}|w{!u1H4mC`yaEz} z?pC+Q3@_JEI^yP%^z)LWiY$eE_CA06qeJBxBbUgB;Bjt$dNzewarF zK4}n7vAprM$r}-vR-B#X`7ph%TkaBl3%={`x2IKkw6Hlckxcq3NadzZbqo;(jpe{Q z|6Xt!om{HTb8M`vKvyxEfzrOl4;8FrleNv->kLMqr1nPUVQ!! z$QR_mA8zN2YTb~$oso=@Xd!>7>0sceJj#QGFVLhrq%4VO&=!d?xYVxFg^5kEjIT9QX4PdB><}Yc)o1c_p(F!I9S}G2_Q!glu z_P~>Fk?v@JBPD2;d%*z}>Kg1pjctVO3PFzq>8Edp2Y)GeV-ZW{ zqu`JHEu)WQ!4l4|UP?#0V>mbZFbIhNc;q3W%*zR)k0FAhNFRfqo+KFR;07hQ0pb2T zvMOA!S6UKa62#wG^ih60Im!n8z-cil*X(WB0s08|3$heO30WzkGWdfXHqra>mwjRAD5bLs>vTy=tKy z#^IDWAUJIkJT@95wbJ+|DXa?=Lw(rc^l(>Ou+mU5R1W8YsYBh(zZjVkTBAyG?EKa) zwZu)ab*0icCmZ8)8zYt=sIli5PfPw#$F;S>IRHMci~B%y%Jv#bnEg@;EN_{QPOL}_ zf2hO4md(ZH0b>B%VOpU5DW#0@4I)+FDJMd_O;#~ZMzMcY%(Sj zw90%)f~B2~6OtvF9tqkWgb~klItHQ`QpVk?bwynnHK9lBYJ(em#aXWcnc8_fz=!!; zXM1+sH=CP_&ruYRvE2eRjy9xI%4>5ody6UBS{DVX)6YIyO*DLOz(?};F!s1G^${kg zIrijTo_s#f+LahL(nKDow6OFZ4(94k?m-)U={@R-jwQ3wE>XCT?wk{Ws$&Q+7JB?5 z166Z=5mnrX^eNyVXg)IJQ@J_K+q*yi@o5J=y0-cdAL2glmbq{v;1Jw}px*r1_vyfj z^-wc?b03nM>c0R;Mju0f4`rckLXh6v@p+qhvDG@YE)lnH-M%wJ6RB%iSc#jm?6r){ zpg!9xpNX(Tq@rDwD5N#|$U;;z)F(?x)Cs{=WzTe<4_ltRWphfWIKq9yufNFUiL3dg zIQ%`}Bc7c)*w4eP3q0M{XvV3_BSd>JxyD~+PX$)U?o#r{4%q7>zyB*NO?TsppiwTe ze6>Bxth>xDm!ZRD=|3TV!!|Xh2K4UJwU|G~BBPly_PE~7PM{A3#v8dTcg`C?lviTJ z{ZW&lzQ!neVMTn{Uj3lvgVne?+40)eOt;c6@uW7D82@L7Q`PY1jkz}2J;f1RBCcUx zQ#cVfUjhnbH@C{B$%fFDmD1ojv)Au+dmq8pfff40D1sF zKFR1KXSo!fM}$5;{f3lQi#;5wx4n?p>BEl(e{!m>E-oF#l=k@i-e>nreDt)3fk%#y z@5~u<5Mv6N3c9By1(F_jL2uhF$e0ztpa&;2X&?*0heQG90r@oRQ$;-1#6?*#l3-7J zt=T(wcyU2tk3GCXf4|+F%x~l-cEIB!JvR{_+w6UB^@0wCvPo*y*%50*3qGPRLCZ}b zKnuNqz=!mPZ`5A3e_MSWa9WtYo>Ogv+{WURRsJuIak|A!pal%6F^c+qQPCBJm^B^F z?_OLzY<%WcI0fzfo`9O#SViH7$uQ6Mly!QG{Z3L@)LYMG-aKW26fu+Q9E6_yMej(C%G~()_6ai z4D?-3byV|CBl1vlzUy^CA7ZU`U!*2tiZr{R4+)zC5|l)fYz^e?imlX6n_D}Z+i|;_ z(ojC)R?ihzz*t%puh0{ zZYo=M4c<;irpi}q<<6eKaQV#BT25L-BD!9}@D{7~AtxDSDk^936B|Fpc&65%Ylw2t39@ zIZXDI&7#Rxt}>tdvIu2^9;X5ya_W+ON5&6b1SRs~a#+v5T1e5CGDfvwQhaQ&PSI{E zFO)G4R44F)@wA)fKs2kru>n!zsixlg!~8lE?;YX3TZ)tBpAX(&ZnN1~;MR47@ddNK zOvH|wC_v9M!-8rWXo{Mq+wJB15Au8{Gz9n{NWf$xdd*bYR9{nQi?(Q)49I6v>blw< zwpZ`dE-V{hSahI$$90B^T1IfFtF2-QKG1xK`S7gS8E>-YCdaD?4=a>S)pId-QYkiI z8nWbl2!y@4-s$yrN*{C~C3-ngnY0=M#+VR8_@UI!^@H}Q?MYD3hg#eQV?`isz;Lh$ zD)zb30>vo(q+-7^s5=rG;gG?~3h_;=W_B#8gKBZomX`C{6p!d*V1a5{+baoq1NN0KWrW=G9jyetG#kp(~kfaA)OsrrB;#GBxl-s ze?pnkokV2=KKwXYX#4oUB1NVx6mXgM0DH6rFAyL4ac5WwI`VSTKu){Z<5^%2s1MMG zutzWzia|eC*;}mSTtFVs1ZYi_bV<-7d5aa^BQ}M%)7XDx9I$<`f}@RpR{2xiKMX#| z;Euay-*qwWBVV|WKjhA}y8-s-(Z^iShlmd(K%kFwSi8Inef2Fo&D_U_tC)ov*CDmr zn9pu~dcVaU9r$o$^ufs={p8v*+q$|$R}_cA)E&G==3Rt6TAWQ`BFG*HX?GlL#u3u) zYEFjKm%N4QZD-k>_6_4goS=taZ--xmL-tj=C_9sg5BZ>4_JU7Rip5p6>W^1ellCi` zYB}ZyeV{;^rQmj&HbY9hpqbqtUbp`GX1h8EdrYD~6r^m2edV;w(BfUpx9QR`tDVdC z)vrm|c<8N=q{{PRvVA`j=oRL4;KH^9t@x1nyxrSUf7f39u*n$U!}e4z!q+36&!xdf zZ!!k<*vou0?5EPYh8KwRT>0!vk)Bb_=QuM30t@AJDeQ3t%R8bY7Z65$5Y zkr&eLlPIZ`M2TE;YOgP3?u~Aev*#a~ zyKxd;SER7qw^;pj?V@L8Sy}620@Q*`?n!?j{VxG3bd6Ln0N%}#j}MLutW=(%_omDx zZ>LEjxl9IShFmsV+YZi1aqq}H)XxfOetsnHK+y!&Yc7UE;ze3lA?1DBV%}agD)-oS zF=ZDIyU4kdAD55t4e*a~toRX8LhU?}^d3NuUGPDpu{-$>h3e&I7s8nJRP-KSEr|~j zFZ6a%!OQo5`6=aGR2QrLD3OoL=4^Za$3JJSsREDFo+}Xb@k#O)v%g2Qur^_bqjVg; zNX+Y_H{R&M2dflIVWZi0^o{31roUx6GM_XntZ?fjm>KT`7*4kz|D4cA4?OzBON}3e zJ^&vlKAVj`ehA{@`&M&Wg&!Ak8cUJUN09K8A!qU+%Y5g}?SwcEfe#=^(tQlWNw^y8 zh*r{v8b+DzV$%?Yz|}G-9-AVGA{TL&wS-l@FGI6r2b8H8-24rg5h;cAx-d`NH_Q-XMVjbx{z zV}NQH?wX7d{|0=FW8^ggSmv+v-7J_J*}2`0RZwz|jcJJ1s@miEm*1~~2zCQVkg!M6 zraI-KW{tRtDo!B9{skqmM)ssdbU$dP4wF@W7Qr)wCi&1ZhAmcvY3#kaF&Au^JKg#NnOjjm>y#JmB~Z5 zepU0u!D$!QQg-z+`fpexMVQ0O4KF;XcnM;Nbw5XidLblmC+q=h;+U~X{<3P~K`-9; z>?lWKQeDatItwfmIVtGgm~Vm36YsJ4=r+*fV7W`WeICWt4mT>ySHznYdjLHyAU?iv z1orrRbrea2>Jc}|@OyhZV~@VjrS~|szlX6$Il04E@7N|AuogCvYZNmJ+}tbwsrS#J za%TN^G|UHGOt_HdC_}>*T4B4M0Yl+F*poJZ9)C9S$Q8%WpWK?yqrhmfDm+>z-N$!7 zWX&nqLxJd{%g<%^r*w> z5zR*}yWpdp#d@_Bcbiraz{|qlRfc99Gw(sudwLqT0eN@!u3!(Di>da@?hmkuWvD?i z`Fp|V+ud8i?h17F2rUvksi^zBn2qVELuN|wBHkizD2Uh6>bxW1BLbbVaY_a3j8;w| zm_;(s$i?C`j;oa~ISUzLHVM#AAxIO#r;$vlH8HxKJUBIGI7{&Z8y1k16;pw!TlnAPV@`Xb2OAFi9n4m`u;C&GJls&x155m= zDT`YekZE&y6HXoEfzL<5AJN@oL?%@S)||1&&A%FZkafw#M{jYe{6NAUTeqGN4|5vA zk*#WMe{5)v{pK$A_Yn5@I%AJ{Zssjitdfv&rnMN*Q!gM|Ms~X0xvEJ1E`YJ2Kv_?* zQZev>HQATy_}wPFQlFP(p!WISAAXbUNpkXtluJu|fIU(?{O5kO6I8_}3fpT?`Fhax70@Y85U zGZmLqx9o2x=-)K9h6ah5zNvy)c|dc1micCZ5~D;2&YIq4F6@esi2MJ0(q^AUo< zQe>luGF8*WN0|>+$iAzsfD7=$2}5ZF%2-r_dH{U57slFTOztYb4?gIswx=+r^37y8 zA%r>wLePGgE$^I~&ZZG*bFqC(`S$3~UPU8Y#IL+o%tjlW++4vLkS~8vivO3wF^F9D zC?8{;^m64qBd)=+2~HmMPM%2d=hhYl7a6ZGt@?>5Y#{~;Separa50MsqW4HOMO|?K zY50le+sr#{SDu*Ud}Om~nd~w;_&I7mM;2#Va)&BDrlmfI=?*_JnLt2B6Gtj%15SuV zmax<|jlCv78y25O{UWOUcFM%kL_mZ%we}|RV1a%FmD)D9WXpRQC1a4@Q5o#ar^Drq zgV4ii7h{m^>Cs0DW}S z2k0ZadwlcjuU{vBk3t?v2;_wZNF4WdMMA4i7SvYgF(Q4V2Cd=6H!ORYJ)+v7gky!} zHwKmFWwzt)!+)hdFY5GiTy6Se`Wx}^UpJP-TF>APo0M)ZX6Zh<#&WK80eR@-d2oBy zncwPCQbp~GL03Y7vuX>fji2@bb$_1=UbHepEOVpWF5h))6?H|;9v@T4C+9MOjvfuj#H^7- zjBL%H!rL!?j9H-kg`oM zu#Lf9I1*nVmkDD}^77(&5Tz-?{YkqY^>z`!(P8Th4}cFPq$5X<%`GmNj1I9Nc&v-w zx4)QO80UObPpjvE&oFE;e=-N~=zD@FK}F+7MI1Y0XbeDUs6=rP+4n9n6Yw_3kBmJ& z0(J;`ka1!A`^l$w3icpdXR0NyVmHKl06!3%cEm@<9{;>I6i@Yh3^5C)(B%0@^+zp-c0qJ@8?;xq`S{KqvfeeH=iKL&S&C$G>mv68caRUfSH|p|H%K`V{wRmn^yo&ZCq-XN-97 z&LWVM4pM)OK895DlF$d>!_lN%;@|B#8=q-{Bh9OY!G?ebdeaKXy5Nuz+1p zMqho@BP!DCdT}HrvlM)qoy`;L@h(A+NJk!S#Yc+M znnCIE1W_y@q_@i-Rl5K_^wEU0R+*g0JwZO}Le)05sDky=A;D>i-vb|jab^k)O{t>U zP%>N9Rb@D43&be^DDl%Ce_ov znFxR2~jflG}D!1fyv+6YoPx0Ii4B5LH@Uti1O6k~3+G z1PG>pnWLdrBF{#4f{8__#N4higwk~BA8SLLT$l$toDP8kW1}Lgu>eQ9ljCcpZ52s5 zBI%;PL1k#3#7`YBc0HKry3M7B5$z+CA@QdL3ZsG)>$Srzz4m*;LvF?PYAV=6QM3BJ zv3j|A_x4hdj(kthE{*v~R@kEj9@Nl{8`}RN1#Vfd=T$t z-eViv3E3GFL~U;lDMV}(25s7owaRxY)cf-)EFlUEbJ-LUXw*Bal zB1r%mau1I#)(O@+&;Ye4QNs`|Za;W&W`OJH^N>|ImC(oKNxHc3gpRZ7ser|7ztKHT z=WWOFd7ZIB46zb#&gO|MX0?6A=*~AnqL?pMNCC#mP+KRC9Ks!}E06}I< zPO>Iap+dzO=^-Nh@(e8U00S5=?`^fqj8;}*{RPcu<`_^#m~ZgW85}BX4IOw%KfBZ= z9*jN@-@&yz90l@LsX$(};A7=uS99N9ij{MT*n=KOO+USRdl=|` zmv|{P7JFG2@g8&3rf8HZ(#5~s-OSh{&em`_vv<89 z#s$eWEyX9s<`c4{Zf%TH{6naeNCD0P78FJwV?rOl{{3MJ_mo?~570-GdAa>n(S2A% zGAWAR$0t6=h8|zLr@omFL5~DJ9teG)z#FUv*q*D$ZE-lQ&1?zAN|Gnv9%K_CV^|! zLn|}FK8rl5aISp_0xeK$9n3RrgXo`3A=^6t=abpG2Vg`5Rzu*!dFpkga(=+RD`|ui!cl&$tB2*HIhTGo zydlUYWJEb6Yg#{SRpg&Z=S``&{q>s^`IvftQ)7=det!6Gp^w?hMEa*K%V+BH@-@xn zQW$$cePr`?ss~hD(O3S_Pj-%^^3a zVo)Vru6gVsg4_6f{7>M6w2Rmi%lt-xj{rk;^4hiO&LPVsBlVC-ZpaJ7pphkY z6vGzU(7iBnzN6jIpr&zCR~pDhNOLQLCyPmKUzi`>sRz?nVV^9D24F-@hX50JI)ydl z2u|JjG}sR|C!hn$8Kw#X3_g570&Mum_1s6m8XggX5I=f~9ULCg94tk)qeu%aJkV-D zK}iDIg|0F|Hqpb*Wx2fRg(OFxcCoAaXLmojGZ%SidDB%2p$y-0>x&2X?>~5u!N-@N z54n8wg40L;DBfbV@@*j!_P8VL(J>!KvMz}*`22@k#or@rXr%c_UjTv-;w|{_#cc%< zDA{Wp&5i)-oj2J8vNnI(hE+8a1(sO2%=v>qm+G`IAL^L*yPA)m6DRcW`+UH~+K;ssMgixJ$9SNx;q(02tmlR7TF6L~Q!OgTJg0Q?@x(f3B6Lw2^yMf|;n@ zUvjC-R~I=1usVW6=TiqttI2dPyboi`*L@2==(gTGTI*I075FZ)+NStnFFF{I7RXG0 zym+1P$8wcp8tVn9cO1;exg*^!tFM5^?#bI%&#s?cZ`tk0apYS_?ifs0MsQep&Ml zs)2CwBoRj=B-OocOY8( z%klOfvrl&M@)z?##S5$l;duNCMf7L6Yp`S z_>_f3E2%mtJyh5`pX`%TO&CZJg$uXPe|{GG^|B zzH*1ME($@96ha?%SPxQOx{ooTj}!(U3N#;JkBUB~K>9e_m-3nIaG5G@KLL7xJOCdZ z`l!?U#$TB2yM~I29@dl5(=U<)MTEd4Kt@90CpAZkL0Qdeh8jf^y1YL6&Mk4H?@>>< zbR+907c~>F0*xwHK*dJsY-Nc%NQ}z8x)gf&xk8TL8C>Rfv8V%BcEM&PAn=377|ov3m8@F5QxN4174jVgvUOp}YFttIi5Fr~hiwE^DIY z_n40=Q7M;K3=3tLT+pfw5yB4*gr?q08K3l|8GAe}Rw>6LP~OvY#P+X80fE@mn_G=5 z+dn~-)950&VcOM9b&F%KikiIk zvgh#O0H7S*;togPOfBFe1u#uJSLPCA7G6y(GpV4(E#5SO_ysLW5}bdtcmx`6wjykQeD`l!PTiB8&sDiz$by}zn42n!$ zWgH<7RfiGiV@iG>zyA3>>poyUR>TM3??|VuJw9#EwjBqf515a?kaj`z zk->-1hu}vjHWn8?OvCvNSJ?tT`m9UQecYUv6GmWhXUJGhUHUo+{^8kN1EtY%)Bs_tusDTVpjKs|E`)h)q?u#8)w4=w%dhzah2xXJ04%zwN}0OV>{ zB566wN|PhOjU0FKm&A-LOMbxgTjOLr?}$h&i&JC?nc~4<9Iqpx1mbO$uYg-iHci+0K|CAK;%(4}p*N>>g_@H@f!A zj;c<7$8iNa5Rw8U3(mjmt~|!BGWL)-`j{lij{oIM>xe_wig;$Ed0C0#2VPG@-MJcp z1V&dk8P`(@*dFxqFQ4<Mvuvs~JtbTv-47n{$%{kCB~ z9=GmdE$?CUF%+XPn<9@12Z{~IcfjnS8_T%Q9S~}tq6a#PE_~*W+$i=X}5~5Hg zwxFg(DfwuT9yT~NlZzg;asQ5|wzv$-6>5T~lT3X`t>1CV-0Grn?t1eiJU##)7#Bun z+pCS&K7air zl~Npuu90RCbgN z!#Ex;we6*@$L-Z?na!y6-{08r*OVig4|e2d2f;_1f|lTP4t|=>q7Cu1!H~t8kG0RoAA%2Cb;df1H z7AbB<6blk&vo^|&cRG*UTCiKknh0h!YW9%5*j{LrA6Ohu{06FR9G`-}k4}+_FNsva zMT)Ck<~|POw+Lr_o?d_Yaw)d%+5`sp(0+AvG#e7{sN-6&`qb6=@qg;#PB&R{C$a8Q zzN2V0yM|U9?Lh1mgj1?3RQ&<4iS*V*^blTVT?G@xk0cPQxtaVt;z$I)AyHW3>3F)r zNP1u>)r~6TMi84dO>Y>Dxqii`r!i1RJSU;QNubHA;>;C5kVYc296EZy2Q^JDc?Mpx z`%*}?aO=j$kRE-~h4}R2^C3GTBa8=p1n<#;k1r32KGfUgal#(UP>r`3klEm)@E!?# z1ohD?PJ7A6Pk;XW@#R-r9h3G-n%$7HnIejEwgA5j`+4>v6Jk020o4dSBJ|yWrgg(^MHU-e5rd%ra zc#uNqBYhz8v67|Dox=+Eu`l~D2q6V?8`D+Q8*SnY!JjtRaEP;AG;x+h_}USz=*uaUhzqCpDagE-E83iIu-CK*h-hcY$&6{TtZ{9q8 z`hFuC-S6H4_#jZr1l|z2Ej##1aBnEw?i1{;qAY>1*vDz+&#txi`#6mTTglwZMzG5%ZUmJbY^_woS zZu=YI{mm=`F9py-%ZsT1KxNpetFfHG2Sv4IwF;2ZS52-G(Zj}sYLLD&8@CXL`Qct; zvW;}~_ohaeuC~+-R+rbw6o+lq^QqAT_RPU_oj9V#R8GXy6R#&QOLEOkX?7R(=%EML zBOD&?etf>1Xc;am3ky_=eUkH3S??P)A{MBV}nt6}qWP7@Gl_-r_&yzcQ<~@$1 z4~UP_2qonyN)LUd+136*pR4vZ>RY=}wl$D{HBoNTVKhj^!DCg+Jgu5-V0cwG;Q>Ba z=n(F#NIS&ZdRc0)&r`zb+uUKljr~%W7JfYZ=gnQw;LPpuNcXXP6wC)n7g8?iui`<8 zR3Uw5N%Xm(oNkQA540ID@9>Far^gaCTbq_?xA3@P}ZQ#zebZTGj)L!*M*?d6^{td-@KBg}pF(%pGm)jBYIQSqAq+M)-8#mB=oW_rv z+3T0Kk_G+>5$tI`h~xI^6?|y+bpV3AV`tHmmPxn8Y{fx7rKIO@$OZk{i#XF`rD1#L zgf zq&t`lLP8z@t2t1F2=2gk>ggezzgz(lUgUW#*UrZeDMO&T-;~8!K!D7tB3+%DZyC64x zZ0zy)`|m$nPD||`cCISe$em#xfA_-=htY?b4rFHkqz|rqAEmJ5;7hD3Xme;6o4NVhQf7eb$w!Uwv6ahUE8g`@8pw&ST$T4DO?i zU%yZ2qx6M~?v$>#U7?Sb_aNm0^r+~gdWxRK)aT=qARC-QC( z;FqM`gj^I!*}TF_vs!Ac%kniwASS_%fDb<|vMVMQ041Vq#j=$HEWaJ=$=kC(YF+{O zK-Zs%kD->F4eCtmYc1Ba9(~A)CdQKpUckq^_8v3%z@jFsp<*abx>cGmZm+I{J}_fA z9B>~{7yCd%r96flV3dYEsiEH|{G586MX)cI@q9|ac5-4{phKYx)g8yjRr6Ux#Y+1k z-1vR)adr@VlmL84ZW8{u!%$>@(hhi0MupIWk9JHP2OnmKd#}T)bftB9gznIgP`XE? z10M3nhz=`0&teV63uV4fq(_2DE15?Ey`@|A2{u-|4AmKL$zwH?bYuJ=;e@Hst1!0ZT?s z-ZR(S6{36^S{i)V9RYa`MjHw>WAgYh9`UuU7cga8u*VJHN9(N~S`YoZo3O`Zq`VoT zeOB2UCkfdd@pyjp$a%<$-!%n@Z*_8aF(Z?O5 zkDu0>515Y?{P^zI?{6>CoTdm_OIS2a%O_Fmg1-lXkBEdj3i!DHS8*RPK*gKc>tWvB z{zKa1Mu|I7^P_e_cln&@d>NN)W*YDl4aKUh4&cLL zI!*lQtY7K~pQSbXcfki!E4lsm&t7~m;S)~MPN|n_08~C;EDGwCj?$T&EZmy)>M^cS zA9RSU^p~Ad=0(gr>mq1?pk8N6zyv;DcA|!H05> z$N`v(RorSTtBuCJ>L|TDXc^Fzb1urE1bDBF>PJ%=*Co39Z4x90<;nM9#kWFqC4l`B)Us&YZ|bVj4a93sYpHh}O=7 zwbE~>7o46*aVf1eQ0(B?!2-V*XSCvJt#AaBf>?`rs{e zGC}lp9nqil>5~f^XO{9hr&|VjiUq4rL2V3mBy#aT>{D1L+A-n?NadXo$D9sB=;ODu zP=mr}^u!IJ_(svg}i9N^aTnp3~ z>H%e5^uGtwE^r>lz=sXK#D{Le$3ax6eMV;!64Y9z*lR3Tf>Vge7^SvrZCp7}xg$kK zch96Ud~F2>kyy%+u*a)2*sAqMO5V(kY=_HSelHce^~?&(-h!EfL^>I$BU-N_N@B#N zV(AHm%>*FUmq+qg)me`V&L=^74@r7NcyX4@C+M>EFX$r?8Zu^a>ZC;N|7roI?d$TF z1D#~F_46f!g`qA+r_)8K`y+A1JN|{Xerko$o$IyMh=bsRRkQ*{L|s9Bxv-@c|56#- zc@J8;;rdyxdIBFQG;`Q6-aRfUx?HQzPBC2f6ojX}=bs=v<^$lv0;5%}#Vqg<^}NHa zn>U0#ZXAIh6?+V&Z%PaXooA621$!8I1n~j$(Yt&+{?^!Io1d@9fdhQZ+nuln)W`9> z%X>K_5CJ&)x~S zsGXW(<2mhGBT0T@Xab(3d|D9{;@J4YUTvPdIbObqu(J2-e7S5Z_z3I5P3VdscxtDG zTEjq_!g`p^-m13d+y@^Rkj3eO0U7hsURJ4)gpw=KzvJMe+e#n7AHD45XpnBP4{Y88 zUtDFmhq&y}jJbiF;93a`zWZ=n?g~DJJ@5e>I79QHU3!2IcBdjFEXrVz=$u4`XsIp7W$;n5!=vzaIS$HN4R@;M$$F1$FS=ihrKqm?(a5%RR>`7sfe)go zp7g9l06wHfKvxk?tO#GTuvtj`m^RydS4JNzLV&Q&FBti8)Yr|5rWqn)q(C~4%%p7d z%ClB4Eac0pUi(ZC!YR-O!VC7oQ0h0&KY)+@44UanHoSsO>nfYmp#dK!F2}74NDDsD z*QalMYTBSS*%AlB4sEl-1-?r6$@P|R7IBov#uRMufm$B4(Z`_K913@3`zPnL2%|x} zKnPH)aZ%2AYyx{6h98h0cR#)y&TBep&`1&5D%j(JGA{SP9={+srMJu1j}rFy$BhgZ z%6M_zRmf=)_V{H5J;=N4GanCg6i@Yet4ZEE4f`b{bFL%A!>`)-z%?~?w5tZs0KyYc zrVSATkzmviUE(zw0{dxV?d1!jbtL+|xVIGD?r!}fb04&IS=oHx^8xz!Hru-j(QU0% zjLggM$=8oC7u!#~6y{@vJ`@^QLNUTIb4DM12zji)$BjGNK`QGqs`0~#P3v*UTaE!zD?AJjK)&1cph4U(R}VNnZXCh0Ov8MQsx$X^sTOq$*^zaxZ-KGD%M?z=cpxB++MxN{$Kq{MegKyNi4ag z2snP--zOQ41eGpYf=Y+8i}Tz7M`qtrV{IfpmIhfk^~42}6zuti5#y@C!Em&teh)sb z2lyC>*izHmHGZ_Awi_3!T**kF>uUQyfRDHU=+hH_XB&ERRJ z7w|H-s3P7OZn0i;=!6dVXq3F;xUP1I=KB`Fz|x2w27JJ)&}$zk1ZbjUpI+fEt944B za=`c>|0>B}GQpM3m^ht;#sW%$4OSj8_nF{sbq?MQ!Z7Xg9fryPtNKzx?p{2jB;KQ_x2(cF9`PUmqpx zQHI6f$zK5#O%h$irYsCeLSYEOE4h99+I1a zKIHcy@ZnKXz{fVBk2?i@2!Vh@1U(ctZ)Egwy9^hl81pGojjZ8tuxIAgxpc5tcWmaU z7V{db31bF)D1eR@X}SoP%rX~1`sa@ebd{-(>t~{_>&kl&fcS?}>N1txpz1|K7MXu= zgDVp;-eUNyl-5_4d12+;sfB#~13p5es#X>7cG?hJlxDNLY6heEGV+ohHom`b)7 z__PgQq}VCJ{}lG9<(0-g@S$uh{D%>rcSun&n=4(kb#1cMvop(@7-xn|ISivq9RYPa zep($xpsHBxHhQ($scLdqjcX(6I|c`JchxRXAaKxG=y)0^Tw@QA2k>K+dinImc5q*c zc`oB7YDd!32JZp$@gSIwUjlr9Ju>g{x5RsBeXLzi7kjFo|Dv1=Nf*$E8p<1e6pzz{ zJucP9cBqLsO;37ev9l+0nLu*Aa%o41pS6BLA18v|8QeO_Fa!TCr|Nwgfs2i|>}ji) zljI>q^w(EHyS9&t#G^l8)k;j~i2_RK!`MT|4)d`JqmO^w+HFs^)eN-CnTCWuK6*r@ zZTScBv4$S$1I!)vr<0t(L2!|xtk0(fec&~=0v`!}5VsQ@HHD7MjS~SMQ8*dpl}!iy z01rhwQ`X%8yt>kzugITK)j#-#or0)rnXUeWYSIrTPE^xw@UdO8>H{B($_#)%SYb5j zmQt6T?I5@BZe?<<@O-A1=dDyEI|Z1UO~T<_It1~w!?iJlj_r0& zvZ1Cu<4{#pt;yIGnhz8zE%;aoPRG#`V^A)l=c($TvPu@aHg7s)ul~p21Li{qDgxde zQ)LCHWvfm!BYvF2z#989u*g5ZIh)ajsxPDqFMkC3@!5YN@fe3i)ACM3jd~}XMBA0Db6;R6iGQp2gJWy=?&%m;eY0zF_p(0rtS*;{NmPY37Y^_Uwr_D%L@8@p(o2hS?XzE))B z;e#3^I0<(-S5)$%T6+Xk_s8LdjzxqL==_QmDgztw{610FgY)yGj`7+yqmS(O(cur$E{dB8 zeOxLTCasK=z9pz5t2-RdxOSUi2P`dm`q}RzKnWZGCDI|9h|f!fC3@!__%Ldr0Ycbh z{sh213uATkKII3qYSe*Am_jbCFW8i~(2o}e1Ha&a#@?s}5mAu8Ue-##h zB2hI!yx1Act?dz`PM&?jLGZy_IR-we6HTF7%8L~xdOM%;NolRx{6FC1+B<`f^fF9C z_{XOa5+^~f`u6LQew)Um^+6ExH$|oN10i@wYV=c$>O8FLR=DGzx-9;fT zG)5!tCFo~4hm77mp#pqR{Hv*>L`|B)yo5vL&^Lyxw3e)4ZQH?l8~`8a0#+IU&V;ik zK32hPNh|Pg@V3m;qg1l9=`wm_qbOmYOI59lA1ooD$yOEdq z2ezRDt073n9ybj=z#rbrHhyEDB5z(?jj&L97|VvkjwZBKm!{P-!OkKxqU9wtsH^CI*? zG@=jLd?*Tr{NjE_A1KeuO)(M)PYicH`Yilk03XI49rsZOzm#B`iZ}WVz-GmjmLyF~ z5fB~`xVgc4lsinJwmTP!*L}SLK1x#GbwTRQ@`1cQsA4#>@)kZh-JOY#?P-YUu>Vs| zL7Ox+L#<&NoBXWj0`@O7uL-`W%>mZ@rM1fC>*r9*>zY8Gvp>I=5 zte&L1pO7f#`q{JRyJhQc)hr~e3uR;&d{E&6fr(S`Xgi~_#mKah&_D}5khL6RK2q3Y zYYefTY5i#m$)DLyoAl2G-W~)Wh&~U1k2KLSKw8a*lmNP4qDxzVQQMi<`P4@E?bGXI z(Kx_1iiNCF90}#Q#5aZ7h$x8?a#n=RkQ@qDL)O-i@T*?Cs9EXVf{$4+MHT&XNbUe1 zvBnwyc>ASudFuC4&AbE#Q~@H|&b30D(M}kcjOmaAJ#6%GguuBBX)HsP1$13Rm4StA z858IR@d>DgI>C&XBL|INu1~Mfh1Iv!Ct#-QHZ4@0$!-Ji#adgO%30T3*rJ72!;YLw z-l8fxzN6+{(zj1;4?|W5iE$G89lgRWcfQCqw)d?y1%8C&6!ej?$D`ZJR&_4mZ=sLL z*u%_+LfFIAE@WN4`RUIOGxjLtb6^goY6sae7Zf3?4WVbvrx`)kuEleEa&5@a)k7*O z$}@~7t!l3i+ta$cX;nZewMm!asP&poYo#rX;WGO8dp>5f9$=3{|WD+d4{1R6$h3TH1a zqRvFi=1OPg&Y^roL0S*h4e#8nrW^=xm>&Qet>sCx6B%7KbD}OB%kuiw88rz9%U6z< z)H>|dQU315@#nzl;p|CAMn9r)lq9S0xn z9;yfsBqCh--#1*RRfq?`M;H6xL-m0|*joSfU3DFWKo(bB9>&TkP1Hq_GYfmrO{c?< zSbV6oL^@Xu5+z;SEON5~AH}Zn6w)?Ye^Cik6Er4i((T}v(?GkNmlqluot-Xkk~gLT zoE)XHS=pb+xnr&ptEld;!kn-tbREYi#MnwKqO_n@Caf;Pm1(s<(0uG>11MqNG{lIn zTg=Jx>9jSmOI^KG3(wk4Y;aSsSS|%VPL+_|7=q}$+lMYsgF-qk^u@A4^jqf{8p3Ue zD?7zF1U@F1dz_DqW+MA#@L|1&PSxZnO)gE*N6~9&UYz$826EasdQx?nO zQZIbLecJ}5Ndog9V-6yKhrXiu5c>FALLZAm+eTfi)3|*2*T)_6f#6h`7jqw9+`aed ztwf7G`25qxPS2!Lr&0!67u zD1|AKkH!ZE9~A29YvH%kaWjZQb7%fgkjd06Up59eTy}V2{38*kvG{*6YT7FQVJ^fz;5kguH zU#3cptEjL&t)PR5xmn~`_-lBv7SrLVYqKky=8e2RNxOs~bM;OToLYGRzKP_RGgc~G zleBPNfsc%8j|fhAwL{Fu1+_VmYl&6L9jHQJiTSTWjf#h5TGXt#YpK(HVj8ijoO!uA z_XOfHO=AjSE)BJEhnqD5KEjhR@>?hvRNW{Y;b>AOp_~`V%w1Q4V?9pHf2H!@S2-Od zVRkE6R79<@R>LsAb$DUZ^vaIA7P2_sSiwj8)O0cMhu~rk=pQ{|<)9I^O+18I29D9T zh}F>{-m9n(j!pwyz#%>lodrBUFj9AM-&6wdu@Pk8T@>#Q)%i-n5?}m)pi4P|@__DW z$PNYgumV*dM~E7YT~+{31Hq4{R>uojOoT4-3+tSioM&N=fFFBRw)A+pGmK?Q)JN(n zMI{5}YpMwBQF#xe4@F+^zJ9DSPU$2R;RAlYTt3LyL&OKv2YDBm55;>)YkFBIl+j-K z%u{vprX_X=0{A$>SJ^#<^)b>|xLFWf##Lp}dODrQ=v_)ikMPXGozbJGzL&WL9NdIBB;C9xez@F7Emmlv_FS_|cQU7S7%KTkR*<$X*hN?o_l z&R&4Ts}bh7DdJp^Y|<}7oae)*5l8lhSf0On|E!upkw%JTc^`c2rBqm33GV6xa3kIB zS*mhbrdyZiDYWGfn@gkZpeM~&XTI6?$%7kGkJK$VcV=1bw_Q+$QYd z5cfe)W?QgFp2dwum6@{(Q0`-U_X{dr)^bxVZFpLJ{nuN&Nhf7IQ87RiQDp2v&gGEN z$6j08_kOrlu!muTQh>4CieV7c7iK`fSf)3koWk&>sin)+7PHYHRYL|^=eHe)0hC~k zxNf4>K@5y~6a_BP5TUE>L;*k{OeI_{nx2-1iVw`<->$LD0bg`MV z%4b~8c(q7h#8u%Dm2(5h`$BBHB~>4l@}w~g2$hMXBGvR|C+g!+iK#-nJI$z>__#_t zz{YYF@DaYk-iK&Q5DQ-wbPXhaO$h6_PT1>_01)_q$ia@x-ix#hxscuI)!S!j{x5MH zG#oc_<=zf_@SlEMZ)*B9Wn7-UOe;wQ;Ss$EP)n#ITJ-as)&$h?XgSWqWn55NbM648T?rhS}NzMOX`2yC?ThA0>v zvRinVi%ZxeUP{q}57zgy+(_l}>Rb^vJ@lwDg-G!#fIrRA(rn%4jIezC>X5O`YtIOMvFP!^aa3H-fs0_9an-jIjNcc)h`v!*9s<1J!FeC z7pIL1Ot_|FN-Y49OLp+Qt$NH!Z5*n^Z;0K|LrkflFYqhXZh!SWdOX$g#mXXJ8PlY> z0DE=sG;HqxJ)C(VKBmFTo%~M4?WifBvBz|hu}4~^QZx=9_bc=u?V^S5(U-S&rJ$#u|v8_MQ(LxVvKE!-v^zq59%~pIDQbEv1arr>*fy)QHN5URA?_~60 z(s`rd808MS)>l0z+Uvtag|{Ivq&%dezhaKif36wT$(hol-;9Z~aLRs*)rq)zmY8H_ z`PlkXy+I`6V=0#Adg9X-eDsEL3v8LI-Ke#WsL5jU#t+s z*4c_|&|tALL+93X=EYvxg^*XAa%9(P+Qr&d&uf;V0QNu$ziZbRm=OM2ax7i%0X{A| z@Zp@+?}87ZD(R2YJps1dp3`}mqCXM%NRj>{!xUJTUA=NKY3k+y@HW=Bpf~;17PANwAyI@1Bz~ z;=>Aj2-xbE7EOggpQrKo9aR#vbzg{QJYdZX@S%BJiQSp@v&9xi(X? zV-f1n;JBw2)lEJ4IB8AtMZgvvB&|iNQ%gmgp*&!Bd)lrV`7yo-DiC!$N0!3~iQJ}T z{v~uD$W1A8G4bI@XEAdhTYH_xqNXPl_aXF=f_C~aAJUuVxO?~RN0*ze{UZhf^wC>< z06r8#A0nenpP!UOOCg+58D>lmTr-z3g~=P+5X1YG-&<6s$3uNxh$WZI0|VI*l~nNI za}BSvd#(yqw|QZu-2)%V+;mc4I8wK-xE0Hixs|7nWsQv`(5l!|D6&>09hZJcR!Ht> z0OGVRlY-2gj7@{zOnxk{Uli#FCK1PF9(@MJ!S8W44pqEV=#g>&@18HoP+hx=FwAA% z1tscY-2_D&by3>T0^ptYcZsI5Q4RQ55S;!o_=pNdz(*Q91$^Ytpo}r%5o7Q%{Fkva z;f*7=g0NbB#5=PMZyfK)r;N2^BS4Ie66C<WCM4?>KQ>3o=J}GwqnYV$ zHd(A!uii2E=;2)0sul2&f>tKN-BW-MB?6+*S6F0(U>-`Mba%*3qOzW;t}_&V>kGwq zzxwv;dUe=c1=0h2Naa1&B7q7%s4z*Pp$Ygheno*=LDh>=9u;6w5x=U$>Y zgC;e})(2@DlwIzK2Sv>Xg}pMNk9pQUgHc6t~xI5Q7u80{e$` zcgl(Z_JI0$ILn?3Qdvftu;G^h1pgtfzfFHkmp4-xm$jx*;5)x{$hXo%U z^8xtyefjG*FP1T3k6A+UGHI!^Mqpi6?&;p<^a^VtD?06@@tkaXFgj|AvUzV2oO64SZ3 z4@F=P5PHk1hHT_<$^&#(*HDZmdAY#dnc! zQMuYwOkJ((1?Q#D)n7J(nqx}9MyGro1Zf2c>}BGa-Y(<=OB3VyRVjFJiRyNh_3E1A z+gl&bvj8Rx!()q3dF^o7r&3VYT57IZk|cJ@&QKAnXV4FFXdKi!SBBL@auv;_cs31`04YKm^;QuOTS{w+O0G6llj2nbmogFm)_A6zVEZTE=Mc z>dgmhwfdTv^y0Xtwt&lJhqZf26_VS>F3$uBdk{qHvR>+39-Iv&QCrq{`z1NXvnNjz z_6X{uw^r|&k3T+3*kg*ofZ}ADPmA8;)kg3E^svEt3bHPLdOoZN^)M+P%>9Z;yNJ=n zk_I6U-2#VJ52(@<*BN=}yP#rF!dI3U~FdjM)y}Q&h!7`idkWUWo0(yDF zkX-#F1FSzZH812`z#b%Biek5*j}i2-t5nK7B=jNO2Ob}S9?v`MQNV}LN1nqn-Uo-v z5pFzuFUd!Y8in*uTnmV9)tAYFVQv8r7)<@y}pC>c7-r(QHc#W$o)3(cP-TbK@{M6D*mvteK16KqA;!8pBofVp< z5~*IA0>JpN3_h;jh0z#Z)(9ZL9=}S~nSN%g+gVoab5% zu?#5SCuV4F*C^w(Iy`+@z0+GjFW$XtwwJ+&4CMhIbpO|HH+#+CBjXe;q8g0?A08m+ z$sLpJCu#sbgim!6bUtXQ{|4}}Hfa~CUhL2FwG^z z@r(u^oxv*ITTFuhk-AQU*!!Z8Fc@)$q^8gdRueqqY1H?-2<><){mnn>SR+X-e2b z;KPX*qYoF_rYQa%FG`;=FdN%}d0j3N_Q>c1chloqmwzGo_*2Fn%Wm=gFxuFb*(@3t z)Zzg0YE2U|<5~S`jBvnp+RkA#G7Ehu z^U~UkVQhL#e5AAaj~^2HP$=)BC`JY653<*o(8qC&Z4M!i6hh)G ztA(f!i$1o>N;k{O@mcLkT-Cgs8Vc3!Pk;}Yi+W7VQeGx(oZOp?h42~f&gmpxOrscc z2VL%J2a@2&n&8LJ?=t)Ve*{5pdZ!DR568_$W%+OATW-C}&|^)kM+zm1W4x=LHjMU_ zLJ5a2e4|V?>yTME<@`L!nQAaZ@4!bnvRfVapwoOR2DvRX;LuJ`BZMY@75JY**)Rh~ z+U4V|H(ggXkCR^pA1<}k$kzV8fRB>^AE&v@w#X@*02HtRd_XINi$!<0`kYIa~X+b{K5PDDjPJ z6ksR*?ZC%q>N37Bn;Ok1`A_Gji;J?hJB85>fa!}bqBVqPLu6^0;DNr?mBshH&z)l0 zfRC|x^O~#KLaC|IS~SGR5Y3;0C38Ve?GR_@0*R#oY4S?)V^poUlrDNBH{lvG?*aI@OurQv zjWyuo&%ZtFL{+FXsELzxxOnyQrO-zXh>yOdzAIf`4#it+skZqFtMZuHH4b&LJ?`*= z^j<7ZJPM~%?z&h!03S=&N94qs>!tF47`{@oE`&7M>}>M|HnTJ#K|QAU+EGDAuMe_IQ-yN$O@i&q7#nIPzsF5$Hqs z<9g;pzYb&A7(_KG8xzGz$#3gLT-X|XvyCAY$9&u7_eqgjNw1kROtrzO)w zX<4*dy#7LMf$#@m7QYZ58}Knw7l$@m%dOI%kz_ue;T6%s*Z4^%it;QpMXsJJqfkNq zh`K2@Y^5;rYQLV3pFh0)_SQGqblsq;H#5BfU!Z)s{uxFd-@X0#c})p`j6E!c7q7u` zSM8fU{-s2){bzorxno~qFqpgOj9we3wJf?d?Q*M&>%m7MHYcU^eXEB^AYfz63h_44 z8qq!*CxXvaw=q)0u{*)YBi&8)*?buCoT|rh(~7#;V`1WS zh-krga|v|g)EuA3b|7r>s?KJxYTEFm$wLc!r0B#R=mv#BGWM7?t#R>AY|ODF-s6d| zhl_0keW3av>+<7^!|veHb4wql0-#UUTGcsdzI1<8WF-CYTb)d0!m}9 z-iZavzzVFxB6&Ov?4_wf5z~*x)iojUnY)lC~qt|}eRh!1?q8#3R z`uh4j*L%(rthDrgmf207H%)p?(q9OQDDT25!JX#hzMUs*AS>lTX8+%QQ!dMm7wp?F z?}Mshu?dG$f2-Tuz*cv1`b|f~F*WcPJNEJ0FT5SWyCn?<;6o&@^d4^GTUE4jF(?bA zhGbru_v`vWFO{GoLGV_^yZkUtLct|K><*c5$&XP3-uD}(@_5~~!TgWl)J^ink{|l@ zRW8cmbo8MkcoUyCRRphBQXx~G*}n5oiwsTGsP>hk0es-3?s8WVWco91Ds*`XF1T)f zr_tefLgL7KR(miu5I%=Po&L$VwEe`c10QI+YR^kpsA&s6eC(}v9?BgVu5{Kp%g6F6;sLFw7ff@g6BU_|Y*RvFzqLmzN29G>1%S$E+=Ac0{ZQDyr?%1@Mb`Gxo<1gF70L`__% zE>wbIQ$lKPPZv$vX4IXU`*7rP-i@)LjV+yyPaRhw$J+8dMa_XHM>WhGka@Hbi(|}7 zgs%b5N0Eziri-y@kw)RPZ8{6~C;|8Yel(G>$J%_3v6)6QwmQ52_{rlG4e`-gtQ&sh z8rx@kc#oj?M4_CfCH3Op8F@t7#n=Plqh&snb6FDh*okPa{X=cVJPzt#kLnnmvw)jr zRjzH~oT5ENk0iTpWG~HAgd%Y1onZ9EocbBGMwXx_VyLG4_?u}JHA`h<)_@=D`b_TX z4tsn6Kho(d*hA>!U(eU`)gjy%;NxKQ(H6XbJxIGKGWRj#X%+b!!w%AtrB%b(?^m!Qa$*7WmXqd26!%PZpKf;DtQ^$suWxI7 z`t zqgq>sj5D!kNy+x}M1Q>hQ1Hh$;159x{Hq*&2i1*=Q0a{H=$m&xe@)0E*?JtJ$O`bm zs^!Z`<+(M5-r4D-M5ht%98c(g4`u5GK1z&NA9RI$nYzdqv8>VaB+OS^>eJi43*Yvk z1_|)73VgihjjoTcx94c2rhxqjb3OZ=q7u`|vANjW|2IA*P?g^+DiV*uhuyF$Capq2 zsI>8B@R0(a@Q9OmzFOa>tj zgKz|-KgfRTtovDNQJVvasg=5}n_qlBu+`DLGO|0;3gDolcz*q3@S#Rc4Rtei`6jbDF!YMIf$3Fja2_OVjRi(F1PFkSey84cxFmOA$m8~0dL*!i7KFaa zmWZ5-5|CBXN}lf^>_M^1W&TCEi@ZKU_3^{Su3`@y#I<=|m&=4bUi}jKfcZ$+V>*;s zO-olTUQ6LUMdV5}JWb;X<9nHzpyFnwUpkF}vuE0%Axsoz&X2k2a~&U*HzVWXT#N}n zJM+u1f$W>Qb#ED8t5_|cTz2dECD`Myh5690R`g-b$IF+`U;gy${JcmK%*W0)lsz1l z`)E!x{Giwc@bSp;XQhDU+7l8sFP zdo<6XtyEt-sR~2#@sQC&;z8w_Mxd?T7cTe|?^n9zq`BFQcQN2c^my+#*%}JloX{y|@GtXmSA`gDGo? zq+Is58+Ca$SBvXa{$pPV8Pg~cTFwFwY$!K_k6OqSBFl15-G2QGaiy^ly?adc99Y12}D+Y|1T# zGa&SN3(pa+855_FyD=sfz=!Tdy5d&V2_^qxCVO&d^qJtByY-U&V}U6r;UchCM!&PCwk*yuydhq1?aaPe=5)uU=HE{_s%Wt1q9 zTmftlBvY48lhL69%?H9>93n8i^>{t8I+WWcF^PQR&WaUp<6@V0$9Fis(=QJsuvgJ+6SZf+X;MdvD}Ew3q<~gmUPj6 zANgfWuU?gz-Zb-oKGsoor|0W=7doBmx@U(U5xL_02RA3chcT6&W@xM~8XBq+2$i!+ zI?t47q?^mEj5p$DmOADBuV~qVf5!bXC-8a5`IpaMKfHbSrho|*Y@)M8;7CyHqc&zK zzWwqxQ65R>kxV_V(mUE&7nyU6a!GsD{9NCtxfT#j*Toq!TN9mxNxi=MZE!5yS$hAVT|zL8!GU3CcftSn9r>ZT6u9|J4QyGhbVqD>p?#m_tSIQPk&1V zl~3d9562?sg%*7MW-8G2x2R#YmQfxrFFN6Na01@B0uqsXG&htgM_-ssaBfsFKTf6-*ck**o zotndQQ3W4prK6C(WCjCZN6*zxahkscd`y53$Z};z1D;m!;oM@_MA5XaWi8yH2t#dq zF$Qk7Gl7C)S~$}Zi{~1%@vvlZ;D#u}qA?(CczmWx>FB`x##oV+Sfuw5_PCk)klw>8 za}NP_PlxYQKXuTDG#?6@>KlLj_Q^OIl~3Nx349#J{qw(x^f2=Q{J`gk_Mp-y?hgFF>&+B?=rD^)ZzYX(|1N8CJQ!kbl>6IuB%#Aay^k0G=IZQNao@kXGJ@}}$1W|bd_?T*mKf56X zuvL?_PM@Xkn?zt^4AfLD%2(nf92H_|I~>l=cISxzNdV;2yD#6lOhaLNc@(9Dt4qK8 z^6t}z1UyzDkJ|+)Xn4&X_-G4!ir7L`h>>q7Mbv;Oo=VpPB49ylEoUCpS0!H~S7W8C zcOb(0(`w+LskA~(W*zIT+O!Y~5f>uj#C+_;uA~#0BgP7`-<6-(L70YuK#CKH2J852 zYZ3Xsj1b!>@8#FdUmh5SbEu7tUgwJD%s1iwtq^uMfo|(%$tzgmsJiRH$25dqgqq|u zq4NpjD_sG9-yBK487-nHi!b0q)}rz(CA2!rtOEdNi(ppPk!D?CN zEDfxHX=(jSM9M`ozaJU=Cd8niVO|PXQyb;=Y?Jp5@ma|&>UiNd{6MwxpaaduSfUos zX&2XtY2xQ~0=$$~ahOyjaE)?t50eS*WTF8duJ*T5i&^;~&O>oC^C8|NMSz$B(lg36 z_IPwZgO3zY9}V&_>`=Mw{dJtR%ZbRFQ%&#*d;FM55B-Mu0DN>tAOC#07xri%x_l9R zep$iuFf^$@#TiHK3?m8n@XWnc?+zYWh3z0W=HXC(h&JD~f*KcS5-8qh0Y2J(fB|3G zu4|sGeM#2!LfAvFBajEg2U(Y*;(hk=r^n}O9`}Hc^eakb*L%-^9tIzmh(026hOMBF z)3!Mn3wKsAUxz;K0zlwE4$FXN-I61Oh@cUlv$|@@2VE$dvMuo)uu?v+Ib6t2Ml{YP z;6r-&sm{bc;RP5gw0l&HAQj4u3$0#X7pWM#vL1YNFo7-3PqR&_s8MiGqSZ9v+4S9j;!#|N7zQx9`5Z`G%}YR7M(%*ug<`$Gf))cf5an zbsoUucBqPmlS&(4yTWZ&E6`kd>IxHFHwNv6%|cs<*rk-bU7Kl_IY%3uiBNs0O4oJ~ zE+Z0+g62btQFBN^hUyS948gME#@$Lgs#_c0*l{dAYC#f$;mHH0KGY7x?E6%!y{9(f2Puf<3ss1^ zBRQ4W5H0-NDGzeSEJi6GhWpOjJ>Zt#MgT8A#S*Vms&ivk9|EZ7`!B5r0+?awU z$N@9Trj?8zB6Py|s8v}L@>wfnYaL9`HvBjwL$q!fFkJUGE+{=hC&R6ysNbc)&YY#& z_dBUYS(x?8z|@$m+Y0%3i=B86sE_MxKJfSOroK8tiE+$1mj@YqJlcSdUTyk9@FQW5 z$);j!`laPh^z3>N_9)!PHt|BW3*3jWN6Fc8(Q5TP;6q<5MT;Gu+lrzvWI^dU%w+yml6 z{-%JBgg##V^mrZP2c$FGWrmuP9{z-moI69KDr)rE%eB7 zkaLA}+!fwVlw}MiSsR~5QJ|VL%a2Hn6FJun_^6wI61dIu2SN=WGl)fN%t~1M+ls8T zs9H}P&LMaYD~0cFA&Q&8$3%n3W{cA_7}2vllJMCS(r`7FCmiIr3Rji8oO_g$Nnnv# z)T0wjXJ=O;#;-oVfB!LIkhkv=3VGA`WhgE4=FOKc@7}#lsN>_;_n%+Sg-Dqh{!Pb3$r<2-6BMzv90e@~%u+$Q9dVB%O@CGh#V%RAhs-{P3Z{of zgy`WX&(U@_FlfuOc_$H=^_GYZ#iVW{8#j&uAB~1T3Mt@vfFDG>HKOlWwTzC`RYQ=T z)U5{{8i`tw)l*Ef4eLE{j0aB$zeeOYeD{Q{*)*1O(zll_ftVh1{3&M3Xlxu!zgz%I zqZLquvQz=qv;gMcaq3vWHcRLcR!5FYCY;_{m3gOmlW4AoY- zu82qp{D{V~VhcXVQ&t~^-I=Of;67^ia|hT%eqbKq%E^_Mp*CtTallGU9)-EF;=mC{=Mxm7~8p>;;P|ADp)Qude76_G{z0*sEk$+tVEtsC$W|7ZMx zk9!mL9ySQjar`3qP(h406dSRnJ^67n(brDb;4WQFc73Fc1sCOXShq%MJkpd<2(@hK zD#fq=a9(1(di^<}kgs1qe*E~M#>bCezrKI}`Eybbj%&%}%_ZZo52M)0UXB6Cy`Qwb z3Eg4UgWQ5DFTJdA*G$78bifDOHg7`9quzu8+Z7^WXvF2hNgJ@hn`_HiH*{5g$P2lN zunMe{evHLdY+9Jl7Hmp-FREOWRPWpi$|Oae$vtCht-ukWV&r-_ODSYJ(M5f(7A`7? zAfC`1oLHy8&4A?X81{{hwz)|KACtjHjyAUp`0!dBd_ZL`PL9EceUMw>1yC)D)5=Kl zF$@8KhM;* zv`uW69HNIXmk{>YMo|W`VYSv2e$sF*Y@iDExSs;>;er=4AApaf_qe}S##+Jy^atzy z#qVA=0q@Z<9~L(J{rRr?dth}KvVnq(!~z8+f-4K{gDc5KhZl#R!FAI2ZS~a&`(lG~ z+aR{BORJ=`zGE2QQq2qOR)8NpxfKIBat5*f34L5r=8}G2pLJ1)`?y#vjciEiP|Y2l z7Sv&TQ>9%%A5Xy^#qUElwTq5bAu3C%(~W9b0rrS^crdzh2T}HXv1vaQNTamBv0+sD z-DlD^pOWIRQqb>~1c%~;1lM3=#Kn)1T&`>futRcN-D2`9Uk@&bQCQ&Srv>=XCX{kRHg3)=c|BErLQg5oQ79;uv`0;0;mKeKmW^gqOE&;V+wY!0`@)}cF8wBr3sSey%ZN+Qe|G=t- z;E=MCT31wxlN;Sl%*8|9oK%UbwGOU1*2A$sajUvsWFC0RKeI&-){^-m!qu1WG$T{} zNe2ga{4kiIT!@k|*ZN~=zZBeyeF}9h6@iqzd>0Rrp_J-U(l1O<#GNd;#av$$yCgtbP(9?$>y{JDWg`eo{)w-|GR;qTAJbr)1Z+_yGw8U@4#$V_H< z-IlCtO3Jx_R-2m`exQnY*60ZccY7~!)doki;Q&$xPb!0k_SJAi;q?Nq;1-^Mg~>Bo z*FQ=3u}QjsJrpm2AI}r|81@I3g-$03_CX)cxole68iC+;dgrk0swwgWyD91XYD*N~+OPQTWAimtC08yk0DL&= zv|pjj>CB{F`ys0@iG>W>)LWSBmYr2Ks?Abt(5DW3xDj)-Sa(M!oWEnP4K(6Shi055 z1?w>oH}JLKuz6|Pm-r<|dM(Y!9M2l@VD_E3UA~fem|(EQ9VLSHo6P4SZ(&xJT|!PE z2kQ~;vi<-FakXgc^oab4eK81f-ZsVX6$u+53p6A$Y^P!`bF%oNo{hHpZ~=NBk5!^> z>4Xq)28|P2 zzMI4&*KaaKhU~4{X>&_4K%;+VLEJ4*k22p(I)qFotx+Sm6x0uvDW&qK*q9<^Ge@T@ zi}F9Nc&wG4xaY$|n~OQ_^omnskD0Xh=Bl3VGWK|c`NIv8(*}F&_u0_&TI})ccjcKz zAHCv~YL_tcyiC|*RPiqaw??VKhxDat(ZtCe03QLwGGqw1T;>&1+E5vQdc3?*`w1*M zhv<&}Cxj}{FyVvjQ!tEr@Zmm%F@$sx>q@xW&*nbx_z?W)RPlNkFud!~?M@_o` zKFXEdK#xRt-PxZ+o4SS;!|&rk4!}p7b}{tGalmhI>DsIX_$ckLN)|Iyev7r|+Q_)Z z!QexWE#?N>HLooCJ@}}Whn_&Il@~@(fI{-@ao8+SLYZ}zF!-SPHg+p-dxqOx?xDE0w z3|dRdAq>YVys`H4G>w)|LHRH916w6LFUit<4U0^in) zME7UlH-#S2hqqpaCY4l&SQU?AG25!aNeU`z$L*lQTGwhzGgEB9*oGbF*dgaz@Bt}G zy`Z2*yl}uX@lSmpD1C?F7^o|%5>oi3eV$C;%&z`ipihSivMdTL5j8;sAT6I2@})2z z^iY#R$07KCc=*uhqtkqJU2Tm$gx`7dJetQd@g880F7NWJHg+-g*yS@!k*?!B`FmWJ zC%zQ?hWaZD} zXZoT8ZE~Ro9ZtvD1E0mt;T;oc{4fc-JyP>>=8{dH0^4YB@YEvlmFK^-@m%aXV`fL4>({}z1M9h3v0 zM-RzSZT_qMM^i8)MX@VFyWs3-nV-O2Tig@SUw=!UUOlH^(7jYCfN)}Aw17LQ3gj8P zGAOQsbRNFsm{q%)G=*S>QZGVTybROWk%1il3v5-mITBIKRcwf4Fw%j2;Zz<_4g#n#;(6GnnhX3G6Xm{%|Sq;mk{C^P$8G9;X-MxZmkSwn8nJ7YN>a z+-*Q`fRDBxVHY#PHA8BGNh~I^R(8)5DmdgPs;;@JlbIEGDtIS?H?Mho9Yk;P?!vy!nZQHwJ7unz4#b z!v8jB(MKHOvT2OxK?*cmBe(?156V5rFxNkv-SjQU!Hx7!u$5w=wR66r=Ed7}5yaIS z@RQ|)tx~pu`xQ#R^AV?PnuHf8f1BdsF^|paBdPauxkTSiRh58V>cCHwIU+pbE}-~z zfIZ!OQYDu8Pex#PRyo_@Fc{$JgsWrTqiDE2xP~o3EzIQSXRC3L5`ZJ;LUhKufT=o#p{(K zg@c!t^ORdaFF#A$R@P`KNBtp{Nm$FbxC>`~6~#ScH-Uvr_*M%CaPSVA8! zwgoRuwTpQVF&YJZtfeKfscn|5BuHNF0zD9$l5>ejo=m4>!yyIdh_4~H7qX|pMW$XC zP@%>*b61Ydke&7A^`2#D8PJM`A_2%LmJPYjg^tolVtei+wNg^s5>aH3u z#9?90GeCwhM)1#b`%ifiVrtwA7+?ixpos1_P+VX9WN{0ei9*#+dRqz(+qKu4KC0g; zS#b(M2w?U}@?%X8Og!}CEOPenQ3iZ?2ABXJiUCvqmd^~r4)DRK;C84LHYfxrZsGX| z3>rOwb&#{4M!`IJIFg=fbAgtTWP&{(t@S_M73=}^QR$D)W9-45ePEC34(S}YYHS|` z_Q<~5E_MNYv>vA~UfdZE8;wEB^^Z?~n|Tk?E*<)az~$p&IW4{9VybqIHHB7mIpi^> z!EZzzc5H|n9Eb%gL>(0?0CF6dDt(oSItF86YA*fi8j+O96~5iDwE{=uL0 z;;#hE2k-;zk*vTYiJg);fnD8 z2wAOEaTBYX_e_jWz=u|FL8b1z8j7==TAdMM4NexB7JbzgkokW}@m0S89V`p!rU0KU zoo_9A-6Nxe#z6g}Z;h9b01-Us?i*}8qDr3|6EaURa-m6{fCq46BmXiE8|<7z_(~H& z;4^@ypGxWsjN{}AY)AUTJX3)`w!IdNz&KY<#8!Z<*K12bL&tgR;vEIORdv#uy7YuS z(o7Hf5cP3{J_`0Q@1bKgWXIQ3-eT(Zu>l_)`bfX;t^qyfK)OhL)}>&N;63s$Ds4-( zOI4hLJ%)@uMDA(AB;_I!#F$j~t&5~LMG)GIGL;~%vR!>#8sP+2%jh-wVq7o_4``>& zi&wDHidT_E1AnUmfu>FRSz6^HS$1=l-TJierk^9{uH;rP<|9YGB9CAFc;_7W(ZrN| zk%#Oy2KK<>)YwDd1N0GvHjpdzFiY)_2{?18N`^>&O11N*6F92ggLx5BJH=0?(NL+vQY zOryXFk14f)1kDX(1hmRi%S(fbYM%sd@w~w5*_f9R8wt*U|H9ZtUEej?vndi~F!W0p zO$U$+SU!lIWfT6SS{BNIlaf;63?xOcg>7@?d=8HEy0_FJsU(ryIx)f415{0CqH=E+ zsL(hVXjultC!<+v^Hw297NW27z_M6pQe{L;9l^BH__f55f}(4-%sD9yu>9fZwMhbu z5h+iVjjVz2(Ncx(DO-XbpF(vsc9|{J=pd0w-aA?&@_GeDa1hm33{gmm$|`NOB>V_S z$&?gm^oVO}e{MxdO+Q2(%iQ$7vepPK02e1uC?6X682aHifB;fSB3eY@Vf?z zs}$UzobnuIs51UUrM$_YBBZ9$N*5FInQMaM7`LQ>HQ_5A3oGzOf?^MPmeAn-l>wI` za9*DpcnEz^?E?A;@AS)zKK^*;JWN(_`$%7xrVPuy>^8O`KAvo_M-I@(VNw1^&}+lN zCiLZE0!bh;S`p%e$KtHch-0^Jg|(c zFZZ)4l`dMW^MnTu;3J}@1Yo1(_pnrFAO;L<4BJ2)$cGKX;pbGlUY#5=ys_yt;4#C| z(x}ErkX z*yK^_9|VRh{KpDA1C|L}kB*eGH<}mBUP4Z^SwDhlg#^Hq&(urW+pc(%81o*b?Jcy;DiCoXBgsAP zX{QUBthql>8j!&urpWd{R9HlcqKbp|AT;4f!HQ*f(?$lgA=44fQyH(o!O(=w$wb;k zcno*hrfaEdQd~a?Ufk%IMniqTM{qTDnDj}2ZSh&-)mPn{YYuMYE+%07RdVRr*c7a7 zEc{M`um{9Pr#cPfVcw&0BAJ2^Rr968o%`9s0e`U$e2DtE2(O5HYi>R*dXCP?rN6?s z7w_TLx8z;$`2c#PKmU5VuDc3%gY!FSeA5j+rYVLAGaOK#Q<|kt`XW z9~k~n+4Whr6dYWn#8QE;uO6VP)}?)};i%ceh76-=zu%uLowI4v`D4Kjphs8l0`^Gp z_|@->KJ=pLr7|?$l{C)s@F~Pc+u8-OX%pG+qd}@($Jc^W2hhh&%twbl)SRN}Y~ne3 z+u@vMty>g_4~j+I<(hbEppK?&$kU%fdPv>x9Wai>zQw&C3UN>v8ISINE6U>3V@6i* zRFw)1Z@bGyFm-eX$X7h2C6*OiVF21v8^f6N;H{ushU2_W%h^ly#!#o*P6?wl$~=_) z@ERZ~P-9TA(RHF9BfG9;tUbuCk2~0n8P}mnP+Jn~T{kY!-d)s;0zclrT}5)bz~t_h zNb=%=?$m4;Qt4aoJN#O3c{13{A&6-+D|E7a1jYs3easL@9ulZ6(p01L1RJ+7w z7O#u)2HI%U$f7uiSDeh{kpD9C#f}zkp4$QHS3&8Fg>ST>h}5WvUIKkh&?{KxL$;Cz z@3F_d^xHwLZD>u&xhR3<(C16oBmATO2l&X57q85FG>y2T{vgUU683o6C{q@kN3n-pT& zQIjhQ{=3?vlELDI;n~}Sea%o$mE1szP#&Sooex!V1Lav0nmcCYcw3`P>@Vt#SnG?q zPCjKMMVAKkO90^|utaSTqj!U&rxydct@zHwXSHbI$53q2M%Ix=oVjWy`HtMQ+KL6JraYhVTn37)}eRIUCIth-bq2! z0wY*=7|)2#5Z!Sk>8x@*3b4mU^pXESeSke;X5ZeTnfH)$Hs}NR0r(L0k$Dg8uQyd! zvA^CO9=~kd$etZx4>TX4_jtNa`y~aGZ=D4vz=v<$E+S<@-3iM0?H3_y^Oq1=l9`0ZeTtrV!3?$+pPPTG6AI& zjxUVR$JvuU=kiF{!{~!hHi+zIT1~33%-5T4rKEx^&4pT2Hps zS~T4^#&DL!a2fW8lQiKTj)Z?h*pYmeS`!5Wy&M4_n%6W-%1Ns)NFn#KfXmSsbNaSf z|G7Drd2&LbVkapP z`G60_u`;8VX>bXE9i-#<@7B47SL~q$b*}tKKiiS=vXcl`ldkmy=Umt<-rVSQ6Q0SH zm$B@aIQ~#v5-w*azTl|MlSI15;Kx9h?)0Ig<{dfXT}%D$F!gbvulS?__snN~Y{r#4 zo>!Bg!hGmUl^cj0LX6$c1P*`H?zGU|#oA=JRP#s*b*9p;-`Nl|JhI>bia>S0cAg!o2t*dafOFo>@Yo-eTijCu zodDUw$4n8-73Vcf-H-33=8o7x(8);x|D2AY3FJF27b5dToe?jqN6;(J6rrnO)>Lt6 z!@so#B6zVwM!WxoMg|r`O`gsWl=C@rPi*X7np(riqTyi;x!5!j4e72ms1_-!L6jHl zQ2kMw1l`d*dIa*wq;0nrVbk8%ybCag6b2!^PC4|hw$Un0p13C48YoPV{XKwJgAT^0 z+^jlQcC@YaFGR)6N+ZK|4x!hZH0KD5CR6k2Pg+@$j_|C2kB#bsF!NCaghN__&_rm9 z;ZG^-0r~)bbc$2)9>u&0YE5)vmdkB3rx{poPrQ<#FLaC&SWlO$VAvR^exbj8K zGvI?2q_z6#MYD2T7RRQ7q3VGvM++GlX4#vBsnaT2m^u>=i6GG{#~nuiKAIZ9rXD6p znxf#H&L1E+h4=t_zSYpzp>5-8)kr$s z!46wX_SXN(%14Qnd6ch@%U|k*UK#b6$2Og0-1D-PlrvW~3pMpYo9$2UcNe^bi0XDt zni~*PmVufBp**x0P+;Jy9%DV`jM5;bJ483q`)#bImc0`vZm%S)XO93f2hc-giug!X z&CvJ4poml>fvOIZKh+tHiphbDM{5%jPgr0Y;N|#ao6Jqks2j2gpfM+bd>dbHG{yN} zj4Z)6T9ks~;^PE9233NiIt|a{SCEqAf!D<5k-QN|%6ut~aRe!W4t(=dF%dI{!Or*Cveu9;bh-K`u7& zn2Zercg3J^nT{8+Nzz6{gT4aLgATn2>_?8?^9(v)Jo1LkpFuU&NW?eV#__)n`f|bh zD+>6?H4Ojd>ui?XMvfpnAOIdX!HYs7C5^@kYcv~*u)+sld~|I1{olzzXJvoY1+Hs< zG(+(ZK%+Z5D=SOjgZK>df$XD|PF_wiTjSEyv4`5-3VgtQfIa{po8IH&^%5Ml9q&5$ zxQN$J=wt91!(M$~O@%$C9ebQlON2*1x#xT`thk5r&NDL=n}eb5;eO>!3qnre~7}72q`nX;58WjCOEF*b&06qX9CO(8d0(`)HxWTX0F0wSX z7*hKhOQPUJSa56Y+tK=kQVm5f(X?80c)C-?r5J^QK~pJU1#CR#AmB?TGV(a(uGX(C z@fnq|MrXgBPkfci*QAC$Z_>~S7ycU`I{?D19D1MpGN2YS;Tdz?%m8t1Mj)w$fh{iFq* zm=DTb#yVSLk8`sGkIjymTj#)x6V~iyT#J)6VL4ol20Va!3JjO41X&bdxmw2&H>8+& z5`8;tBfLBioI)bA7+B-xMIiwZmSI)WIC@HaJFyLYJoXr)+@;6sKmPThqmRq#5EQvw zpTGXF($s=eH8D=;!=vHL)`ajW=)ffBGnjdysT@fcG^h6$qmR=RHyY6mf!)Q=_g7z^ zJ3%G?QaAA<#j=GJ9+*o?ZsZB05-&I!x&KP->%-M?+5$&-oeg5~Ya!y9; z5S2^zm7X%jAo}<6isO3X>@*3E^kXHJu*8X?rynkka2BP5%t&p+^^67d+GmSQXb)MB z2RuMIT1%Q{hqlM?E*_2X7F7+RODG_O_-G!$M>z~norZ_q%A#&}bm964AXtegWWrk> zXJX8?D)?BsAxx|eZl|BT=RIXAXfT1qgceL(a5i_!duXyS9wUcqM9@X1pbxDns6tQ* zd4E~7<+0$7*li(;p28(bCov!GJg6-QY9;ad%feB4RytcdV}=1@!0@FSQH>kuQ-4jA zVRcH(6JS4PJNn^eNXCXeNG(2dlB=7G?X9ta9*OxVPGcWFhh+`oCuYiw^Jp?^Q;-l$3{{1@d-ePo~*Lk*SOs8>^R=7-y zki15FUS!(Y&BapgK1|!@_A~iFMVI>;;kUr)T9ST*rZr zq6V0n{9a!lC{AszUeU+c? zW$ye^98Mo9PPbV5eubo@GGQ8&=XB(N4@6V(JiH=OXP3S|(=}%2#xIe~lR^pT36jXc z6-*bd-_W%>wn-5Z5%N^8BC~|a7QF$3HYLh6tngxGa%nK7R0+?Prh=GrE=H8G4!K%N zmZHx=ZigAEMzB;2^&AxN(Mvg}zJm`CWl`JWm82a$i@4v5rJTqjjL@-(8xcpA3Y0s?u5%Cg zD5vmY-EIe5Q|{}E=|xBlJesrXb3d(Aip0!$hLuoEb%|2aP7ovzbekQn2fF*|?8a5^4kbfcTJ_v>Ectv@DHstY@bCW9;#H#2&ZHp&H42Xb6A> z$+?xu%VzgkdkB-s+=BPXz(vb)N3C=>=RVHAWZS}#vwujZL>tub1j)Ho{1-*PA!aOd zxn{^%w8#vUw&pd?F;JqpUF4`-Emw^SA;2m3rHjczJqpGd zNm_qq^T`kbFNL;B-_ox@1A-%^wX}0a12ubB`6k%!Z2+QAbm%*b z!N}wRvRJX&5<@53?zq-DBZg+$-`B+9c_;z$JRqFz)k};aB8Q`kLf?0c-@4zGAPbU9 zG~o6Ym7NTog_23i!zQK^W^VHB6Qa<0h)Ngw@zIf3L_3#8OT}=E3_&b+X~D=7;uWK6 zjuX>+!=ZrmYn>XUofe`T;Tr#L>;d$E_ehntFVC~yAAzX9)rLLpV2{dtL}-zc#n{L5 zO?}(VOw+V`+fo1c9w?>q9>2gI6x#mt)3!iTlLKEJ8e1=m&GwP8gn(6akBP zbj{@%c~=UE2>}@|vC@YT3vajZu{4EZHfOj{@yAsJv8JWh2s3Qb&Kvsp+iSNs?eODQ z&by46m%so0^R;(4T@=lw<0|y=ys+q14{1|KJ0IZi`UcDTl=kv;PWDHH{K=oJJ89!LP%PK?WpAdCXz zYTr0V|B?7O0uR-??5s{htzc<1uRck2nq?2iL5c(xcn2ZqxV-+w#x=Nru*xSG)VenCc>#+EMna2Ch4m^;rNtU1b)-7bo z=?wVDi*D0Z`VnXlz(;|wn5Zjhg+2+HW6hcHS|b(v|2cmk6k>nf-adngf0+-e3eL%Z ze$Chyst7+E9;sn2U{bp|A5gy4sBVeroH{>?CQ}}0$raoSw<6+wdIp4bDn0*5g~4YfZ!xZXDl!-|ElbgB<2Mk57rDJG=z#|I_en~I0Y07g(X=kt z?*<=29@`1sL7fvXV2|d+^7?B-A9&Ood?=Rd<r!AY0(FMA zY9P$52=f>sN0wlzg{mkQj(X;mWNUz@t{zeh1;Ms>C(UhV6DFz^h zqTkdZ-o>&L?+rnSN+`)XT&ExglltK-{S=yC9;7C2qXKm}r;Vfenr!G|Z&hxyl4>AH zlaoypDCRtsmt|ibuS7J9vCblL*+pY$PvdS4pT&tMOYf9L zq8nWL1fzRKQcg&AFSw)Z1JvjzoSit!>KmJz7Se^Dpm|!(wpC2+!Dg|maVHgLExO9s z2iE*x+szC3NX&=bGj-xdF3CF<2wM#c?(}G?JQpMj`0xNVzBrQr?tRnoDg=9{hMKHB z*$)E0WHTRk#UtKBnvaG()S2x}Ry~kf+4>YH5uP??Pn&6ido8F^h5A+_t@D~gG z@t+-gtm|}&JK93Fc4_QubeK-Cqs2dzZA=1m;K;Ks#mKF5Zs&t)$AP6>0K^!~d4lKV zyeoTNk_Ll1Wf}~{c&!ywm_`Fcr2F{SKz#fn?^0wR`xW^9=kJ%RiCl#{4)3~;%hz3< zBk)1$<;Z*}rSd$RXFv@b3n}R1Xt17`58d-qXNowlMBK%LD8@#uxgN&(nS9GxkjjhvIO@>a!x95&J8dnU!S^)D1?BporEaChm1+Vl2 z^GmBa7oQOh*|GL`5hh)4g#(YXAnKLu`}ZSN;+1FUrD%`QC0LJQbuZoMr4xHfhM-Iv zw&G?D$L9)%F4iRMJ<(HA0H7X)z{VIGI9gNm#{yn8xF^hCvxK)PCufa}spXe69CU4} zxMyB^7RotB#tP`O*8gI3n*jsAbLAi{sL7=y5m*3K)_s6&169BWWT4*p*xPuV@ok2> z#1U&C!V0$01M^`XsvpHe8md~+Rj%HAYlMkG{Ek@#nS7vaSeOb258F~!!semGcsW(# z1Lgyh)0apF13r)po}6!M673k^@0YyiXN7JPQG)w*)Zh@{& zLD0S0qq#yIJiYZ;C)+Q(?gQq7Vi%Z?_fCB5@$HX4UarxNg~Di=!_6D|*z1yvK5E+K zfIe>1MVeJbh*Dat2kryx@zTLZx6^Z^e!wI$SQNQKEFyD>85n4UFI{ljx5wBAg)KoC zRAJOlc(utF{sbjzoIsKs9yhCh;+{rrQjez;(iaxJx+@bby(Z!Uurh+^$lx*nP>77i zygK<6ENqnjt?ub=rrzK{t7~Y&N9Lm>Ldt>mA5i)7bVfj}!aJWhOMo;^7*Q`}I&uvl ziz%yTmVK#m0wg|(H|9GK^NdH_IC!ANby9t8OGt9FL}5NAa6(YR8m3Qbir|nN@Tai# zY0#k0sr}6O5`EZPGK89K=aJ6CUk)aepJu>ZmGOTz$~WIXE2JoD(f|I)p3FgTi)5Z;R0Ppu0{OSUK? zm@)6do_qM4Gi%8~=27Z|hi7#e7jf zJ~(xj3u1ETQESM|8K-pvEE97i{Fws-IC8Vt!r*7X&O$MJ2mcqeRqGk*V$<3?YpY;sTf}Q`veEIcuf>#Dz;S z?LX&%ll4Gc^haIWivVe2B=gi-KEb|NB?;_Cq8OP*zbqbTD2{3jrB+G{d6s6aQ4^A( zCo{%s?V`T`Z}DLr%?ruooCZ$U)FpZwPOqb{Dqf&yXo*eTc ziujp(Uz|B}Gs4{5<7_6)Q^Lzqd^Pz023V#JJ`99A$%6Qn2j;odBKMM!#R55fAkRj( zQ;EE!+(y;Q=6u&)xL>qDsBq{MNtS9-PU?yATWs!PU+As{h%iBo`&Wp-Zfufazz%#L!b03#gHlLe`){wEO|*$@$5q_mk1 zQ%0W}CO$JF>q^B`_Xba1j+Bs7FN(j?5qy9?fFO5g9AbECX*YYgVUGenP@9JHw*4T! zy?(#V&+b`@>ub_N!3dFh4B4G`>wQDdN1{(7 z;TcH;AB@n)Hx;{BZ~9Bf!$}vpoGP}g%D1=gyGPheknmqG*ZYq@0(=z7$3ygSw{OU0 z1qqy_Lz-`PwEO&#%*)QlCGcV8S6AKZDnd%1Pi}#vaiy^QtQTg2N~-%hgcfRna1dXN zJ_KTYPmNTz&yQpT6bJfZV@pe_Z|uAb5C5Z^D0tb1WUv@z&Z2YDBrOWaxdF97JCA@Wft2~{nK&BVV&d+_x2 zoRo#3a0v}?>Uxlq@-+?sSm~vebXZ=FSSqUlI&E1g1;rD&kB?TIxYk)l13|eMP)RVn z^0K#UtziK<9c0BeiW_5Sw$wguRu z;ExS{D1Pk_7`glEE!rw!Z9AzTyGAkT1=?)64i@>X?7fV&^)5?~RbL-TdmI6=G zpkiHO=RxqHMtMNsY2=^TjJfTmqPTxhMo5J(b)hhe`lc&mB<5~PTX*ykyvMKYALm{0 z8H4xOVnZK4wyVZvH=Ng-JI-+?|#XIq1hiarEC8X$lJ*XvKY9R!Hl{a}*_R{gdxU@aqv*%xG ziehmxW2rm;(j_1aVPM)wB-E8t>R-0cHFUJT zvLJcxYf+cuMT}GNEfI=AQ(ek6=n&DZEQ0sSzHi52P#Ll4SwKSxnZHPZI)IL+^5>yg zrzXm%L-Ew?FGb~QrZ9Mqq5$Lq*D5oEkB}dCz(chSIT!{?H3Ehfs;3M^5kdbIF&|NT zqyYk{$UxJZ4t~1$*gDCdYo;?8p=~<7zbkkcZnAuym_Q(P6}-Mz%>X`<=pzG=yOvM{ zbO}$+=eyg!6yBpn!5%+eZ`XC{Hy%b_!X7`jel7+dn5zqY;Pj!`;m7CeWq+x+hh54R zOSsJ7+QY7ZrVF~DUsh8fj5pAr*xrc~06lRmxAhig$g^dPQSHR=bs*u0Qk^1clsM{Ozj+AF6c;$p_3whaP)u=;MC9CP{a0L42F;KYx$loVPmmj<=#%Pne~$>Rv95r2`x-1nk>Il9 zaPKyk_5(}mo&kf#iUb}hhM2YBI2l5qu$n<2$_l=&R4L|E3xOjML^a6yOzkPb%xXFW zLc)b3nEa`Kh}KCXN-y?69N^7b&yGdoS;KM^fD9TO&?0$E{Kg|(UVsb};uN1-1w$Ys zv${BP`U*o&we>hVm@5fqBK-IX5O7p6vu_b^nyN`Tr^8-_lcIDWyLAM`?3W;Its@B; z6NrsA0(}JJ(?Caf&8j~9uz%6PQs9GQm*1FsCSIz9Jr6(`*0E9<09-LV#;S_7&g;5N zc3l`|{}`iqSRVy8po$V}pCuA*SoF;7o}!fv@F6Br$EGBvUG8#?7o4bPBB}uO2N_rn zD4yYcoC~(x>W2EtO8n=}Jtml@(FFKd=M8&EWq=3!f&0jf^?!e!FVE{m1J8y`ed(V9eAqIMewk$II-k&f zFMT|%5CGu^Rtef>fQ@64t8L~qf#IW^L)RIlI6uz?eAolIOE)UJd+eXCpJ9C)_@u*{ z82rC|+MvfyeMoWoJEdL7x^x}sm)Gz2U12)%X(#oWyPaR&-s6c!?D2uvkcZI6_9B4~ z_uZk4=2pB;8}u;wLE2?XO8x~MpKskAXGuG$ArFi1YG@B=B3HAn`P|0pS@@OIH62R7 zS8mol)!2QwWJ+);m6(AH5E+|(Y`Ev9I+Jl-=Bt}i!8ENx9Zp-FrVok4VrZ%;W8eQ* zq~*<0K=01shg8BWZKX~shT)cJ)GsrQjkI}b0^ zif5pefD_!t*lTd9-nN`pj|e(2Wnmdv0_qR5&zF(BR@G)X@M`3)RfFC23}s?s|_?xj!KIFN^^d;Lws;%~OV+5IjbIiLz0c zz;I><@Zp(oq3$Z*mXxh@j3vPy z^EMavy>wLHtZtLiaxMZNrKcR&!%gMhHs#`)T<~V$HFG1%Ccr|Y+#;%~EWXIY)f*zgmJ_PDq#FcV1TnG!mMFij*KdyX7S7QiPkB>CB_HPi&7VR*8@H@BHRBs z>|?nxxs)D2PeBYRK+NLWu0&#&21E+9DO6liw~^EYl}M)?ZlgWz!hXN3xdK8_zj|0s z;kgQ(cxXb{;VV*KFeybU1{xhd_#u5;e zVGlzOzz5g^FSw2sA0_@dy5P1suA7I;RqO2J{7?ujA+_#4%>LORe_A`osWXh(wk3$@~862XP;N zmgX*KK0qJeHuUlKa$Q!!EpGQ~a63PLpsQ^qJ`6pG`?^N46L*!|Ln``sG4r8#j&)nH zB)l0G!P#F2%r)e^AZ=@15Rha|u#+qrElGiZY|+e%SJ#Jf;rt;cYH5AUGbrLH-akZ2 zHBhlL_=8u&5Oy;@{u<3L<4BRV?iZJG{5V zOgGZQ8RWTy%O*PeK_0Z$R{JdJaM1HT3@E@+a5UOkA<8sN`zblm;#2JGN|?JXin} z3>zCR^4)-sns%YiMGJ5?Hlp%IdXGRKfDe)`1$#UABmO>X}j|x5-qCKq%eAwGI;<*)f*J4}1M@A3R;1ePCk^G4R(1D#N*CQdoUi(|O zr_S$mVUAhn?40gxJGHXxXZ$5uAyWp)E3d-e)i<`ET)`@!!9GD1o-lS$bHw1s1VNz% z61T;ASFm@dko>T6gEc7m)Kl&A>BWgz8}RX<;*}hBEa3%w6jSd)!Dy@lIv6}KhIw6} z_pJ-2B`p+>dVu^k?Wt!R^=a&>iSGD*=x;rzKxqPOu+(J0DXLIa{w1WPF^~cqw1KxQ zW}hgCK><;k6&OaeEnyM{&vY%6M5BWbuz%bpBOPX$aXdtc~r8@`V4lkmjh zoPrg14 ze5mYde`7CV)0Dx7ZMyYQ_t{aGisTHNpkS@B70)QC8PyS%e#R=ht4{SM7*^a{G(X@=JXA1e| zp{pdUNh0^_(pfU@l-RKcXRTDnv&Y>vLuR7R7m8X|_OwfUcl4p$i_WRCE>63^e2BjK z^8WrZU#OG?e5{w#Wt{_kz+uXh7c6N8%rBh&6$L({09vysKw!_jYgewYSeR2D? zaioGpq|X$&PwtxnJ~Ar5 z<=i}ll6{!rJd%1wVo4JCbJo6)jOMP;cf#ji`)$+eAch)KcRK-mw3*7{(^x-AO5zWR z)9KWmXK`Qb9=>3v+CC+hVt0-4TJD=ts9f#0&=Haor`>PFpeR|GA%J2w6O9^rv;h+O zMP^D-I^>Ems&{z+4zUelJ_0ADOn?*=q^?FOVs`SxfFpnfDW!lKI*}UB@!>S7VtEgE z!kR_Fp6D_+rtX4MG5iuR)Z!TS_J~b1Hr#E?8bV(iuc){bk6;7i9=ER$?d=VDg(W17 zvV_Rs1Ai2ZSs)u&rb)?9w9^x<6t^405{FZOmtl@(7&)@h-77uI<=Hd4x`ztfaT|xq zHP{NR68fR?`n2PG_^zM?0;SAxHw`!pQSoDHlftA7GCkjrZ8F z$39a4Y0b6^dx#`ap!!IX)AxWL;yqeJe(rwi!3pQ%V|Z2;3QIRQTeQaDT^VFJbxswN zm87){201;sd8Rl^;!2vJ<7*noCB)6uC(7lmY`h1FnUKnY?2N_r!=EGb@jev0H1I)u z`~CiMro%p==E&EVuSOnVkAvjH@Z+X0G+a5j53mQs2bvFULNtWoe0i)`~RRkm4 zzbdB%ru3kFVt%RjdI0954_>dDohTs3&e4j6P8KZo^-dydJzr-%Z^CQAz++e6YM`0Z zkEx9o_il;ekbG8&0s8X-APN=*}Zbt)WMP_2E7kTp}%x>b19rnyZ?RVW(7D>Sxxc=L#%t z#iu(RjXkWudn3C7bt61qyGUj-bRF=!kEF(w8^%1$8Ivu^E)j7hE){x!J!F6jPmw-n zy1ev+3(N;{Q^1FEC_DCOo*XAgMzF`5b*T!yrlJqWpW7n1XIy$Sy1xV;Vxzk2I-IPQ zE@-twENJ-!KGG267sJ}6EBlJaFTznSOfC_1*bxBDU&(OyOUbQK2^nrUqVQgU6P|3f zzM+r5l6=5?5Wn7Ep1Vzl-pV)5vaa*})7MWRkH1X4nEMF22=1e&;jXs|JpdnylvD3g zYV=^KmU$$y+`gpOxkG&jDb}-=fMm(bGTWyCN6B3lEezU-40chwf`Y-ud0NVOHg;1e z_}EslSK#B!%`%<(4dZirbsf?&J;*<%+rcNG8BM4N_GQS<#B2)=W1J^{2lTc?Esn5CT(bYp z12~u^qoT~c_GBLF^jH?uK|&VSe3B{&BGp3NEPl$esQUeR(|WO~LH1{7*IKfI#6k53 z_z+l3&Pv9IL6@lK`h9h2oHr`_k^T>ysi{jNxiHVQMx+psK z*o3R6C%#p#m{`=;#SV)43(x)IZs{QL?Rou~n_u~u!=(Ucz_7wNRqIrX^v}A4mZ20Q z=iwDj5{YppzveH`cVTLB2V@Y|7Q0_eppsZj1U{n1=)>>Fja`n^$1cd((1#K)_Slr! zSWI-+9esQPd=&Nr@X`2>dziJZ1Bnwi-mP}j$7C$vtNGo@-5~9dWkVn4zS8)n%Z0rT zV@cUB{z`|?LwBHQp($pNrsg`E%GmHeTSrj{kE~U{xhf|f!Lna0FO?9wys=AeXKfuC zD{JruYl2N76U%G~fi=^;BGp+MH+OOW>-J(((Yhb<#9}$gtaIdAL>N3l;%@k8W@K?m zZYUHpZhJzF$}It`Xu(n#+rQ!%o2_Xrdfoq_3GJbCQ=8Ezinys;N0DA{YJBk-XzpKxZEUlSRYoKsrHZqQuM zAfCy>`O9(j5QNlaxz1qV)y4Njb2!%>iA@0G1=7{%V`#K!X<-`#o%K`XvOD_ zB4|PUw3ZPgqr)-sm_`cSnT?8ZPUL0h$M%iTl`SxrR=|Ap2<&l|X0yed&gAJdUtS*O zTns%FJN2>Si1(j+ngsBnc{xre*n=z$#7C~S)%y77&t~=wB=Y};ZK!!q@ilST^dJ~> zAjA3n*!5@JM|sY!>5oHg0F%EjW$}ZgV{=euOO=T(y%dLsiQ|`L-pA&EckG*d{60Pg z_ORju_<`os@%`=ZKR4283k@dDXSj6S4?edC?t?J;$U+-i&zx_EGTR+|;GHq&Mpq49 zVZ5mucpj|z>S-8rGOIs%V8+<793vICC>DIud1FLq1zjb%NhcnN+_Y8^po#WDzPNR@ zf^Mjz#AF&eYM9vIsmUHHI_q*&LqY%OV~3?I>Gr&u1dyg7ye348KwQ<4SPMt3wi&1l z7?y15m?h!Put!SAnonM6`dVTX$izn+xtx*}<7%^%20WuNS%;Toh@$%Xcq7AS!8C=q zrpf?ah2vzE&rlov(hcL=fy$AZBt9G;Jhv+@rMiheBJDBdYFh#>6GdFUTu?^}31#(! zVG1uUnzQ7qi)wD+6~G(^)AF8}6^}=x1Pd^@8DIL4#03tpbJA|W~x z4ShlKk$cPC=F>E%Gt+LoMJeotJrsbCM0*H+nELqn{#m?-%t*DoYU3>IVLOml1?ac&k-#hl06S72JldpEC42!k#kByi5{`1#{KGyZpHVhKSj2>Yh_RLEj z3{W2#eMBV{-xQ^i2Fm$HrLDr?BldHaA2hAO(1WxjtjIYIP?GD))q5N!{%1(-me5VY=ucnKm7gv*B8=R2+~M#%=Mu~BjEWDNkp8t zd&2-c)#Hpx)(G>l427&|Vm8giFemL156f?=tN|E)WId(vM#K1%xJNupYh5x&D)vpFHlik$-+`ht)+>2uw=FKneJ1Nfcb zmPlGixVc=N;Wa56<}FmVg{tg)f^fNXl#eFS@S=0i63 zBl>9m`0u~As-=*Ai*Xgo4|42!lkS6fOnrpv^l6DY6Gy`y(v{qeK62WHGaUW}vs$xL zO-5l+I&3%m?sm$=fGKI`d6NdU&*SjTXQ*$4;wS=tU^ z6x5S@HM&0*byBt3xSC1B;1I00CSB#>-9SWf>`soDz4-}dJFz^v{F6FXG$WX|>OJt@ zi{Da7qp|@>`%hU@U6Z<0wkbiqhMe`IH~|6#(d%{jdNtx@op5tH?f69*=urg-!g-T{=UMc9mq;K$tt^@QY2H>iYwFomWJ3TB zvmHhh*zTGXCc7FzRWI!C0|fM8AQhj3JPfis4F1q_8IqH~OiL-qmvy6RS>ngMAD%c= zm@F`HIlzpJV(oCL?QG_Q#&Sw{($R?-nzc${3LexOg9e}7GgUW0JEG3c&sh(97|JvVzT!C`DSZMj13x86;(AF=e}gVGI@{JoJvfj zqd*rlX8l=R;`L*}H}i-KM)SzS10Dr!K@pL>d)j3{XLuiJk;Z*c?H9YuggT*Hq*=DQ zH8UW)ES3)hIrM<1^rILvQL#zadNcSCDePOR?45X!OQIdW5l)k8P*80>Y(*YbkLMzX z>N%pM)!?r~6p@3KndQ2!o{zK`DtkCu@GFWEmDEG<955gKv}@bg{?U)Ljgtd(?lYq` zS&{lumKD^f)v4pw5^UK8oN%Cc<cNEC#3f`P1u{0zRtZ)YUHg*8JD|?fMi>I!nHeiHwbO zARC=hGgk;vu8*%jLE1hokdN8t!o+)bfU~h%an%-58bfI)R7zdyCkIYFe1c=}Z$bZE ziTe{+TWi_%LkAyJyV&B?@WZ_Uw@dN*5&*yfL;AE%ch_2f#czz>E~(sh#}$%EiZU?z zQ0(XdG%3MUc5f zPM}3aX|Xr$w{1M=ao-JOs6urSRvonG76Y4laNHXoIPT7Lbt;(h{?~atnJ{ z^kMvg&qp>_|Mkb-9A=6;Ik)!*X4p$WnO$o>O5_n{FE2(ayhL`rGphDj9T$LX z*V+WJ?G(_@zmdg0pdrp5i|%Y8rYRW_?kz4{2@fufcsJ@bM6Pv@5m2lJEEJ z^SmsM7-S9fF_@ixIGBAHe4GqE;#3-z3WMB=$Jp%>);`Q;81X>G7oYPpT^id>HL9*o zKw;}fN^95NQ_^!S8!4u@F_QX}R;J2#hKxRYNx0@!L+XHhqdE??Jy6{7P7H6--lU@jnJuIq{`c_xC}5>sBx-5toV`xyo=S@gR2?i=6nkeoE-OvRRJb{l|`aez?yd85u4?j4n(w`#DoU3o? z2cq+>?FeR9kVqcvx=^lGK_bke&rs^tBDu-l*nS(wF#^vMBG)(tQuRIU9vNZmY2d10 zGZsMtZWQny#u%I%cSp-?92-D$+Fd8t9ch?ogV+dJEz1f^x8=U25MIAn^y;)rbQvA; zDqh)iibfNzv-z!tCG|yEin=!O&~j!l-Gizs`IET1ST-DNg~wto^UTrHPHmc8lc=J^ z!ROtPR>Ijh%R_7j93Cz*YWm9Ae3)6Z;Fk^$~%)en1!`v88J_z?C$@uBW5Z$DnY z+~=8c8ic0}N6bbaIqhQdL&QgCKGvBtr&&E)3Qo70cIh5nQ(k1Lu2yB1_MnIRLTYUTkGpOVHDP66tFH;Q33lMDhfJ;v}ZFs(JPMMRw4C{ z7d4j?H_%q4*G2ayFf&@K4L3koBZvvcC^eR>$vsuDK`yOv&42$$|+k8-K>nI?e9fCiiYwh((E*p6BvZikzAn7voYo)hz%D z&oC*+%rv&CV?hx8DRhV6(l296)kNV;4XnN%P~dhe1NWta1^O&D#JVt z2bx$Dx-8I{4?tdmDW_7TwMfS4s7~RI%!le-o~M)~Umk*w>hba6$b5X;vB$@m9yh6_ zi@?Y2!-ze!$eH+n_K2P?|M}w<1-qJ&qcu^iIP`-M5u$M#%EUMV+!L7-*aLgZTie_Q z>*lkEGn2RL32s035bN1uI&494JIH9${g5poGBnwQl#5O4=sdFre}=J1Sb^Y68uR33 z<375}*g$-MJ$B$BJ1G#W1ExzrSV}&x2xno98tz)rM>d1Hb)x&l-Ql;#S5o5r=U^}MAiP5)= zfX8t6^1kiwQcc#h3AEQaFs{JDA!HF>6|h1m=y$gqMFL&42m?odtQvr%KsqVArIz+5 z4R*M$1hXyOY~hy(uBIGDcujI#Ld1hLKhP`y4}Bj0bXXQ0yj3Ry9qw+0x-W?)_5GT~|Q`pVBUXk39cNWi}W2?ahJ4SUpd`2PnV zpQ^7q@$G+vo!OG>L=Z$ROZI~&cp+fegJ2CF_zC|1r?8ZjeX3I;D3&|p>rGOtJ3A{Y z>y14)<$#dAv&exxzH1qm9`GIoJ%l~(ve#6du4HTCW_6z&;T)y~5*pU9vYeNQn8T;} zAbxfhR*sM{{}DjYP^+5 zpo8U+W|cP;P{#1&ja-40%!eKV;cdbn>w+Jx5Q|Zc9V`8HQFsw88;k9TH9J%GvoAg4 zWy2&9&cA(hQzj#i^B*R0Ej4+yuC~G+$EDjzD%~5fcnLmgNeN?h#rwx^zkoC9F7?Mb z`Pi|CVv>6#@3BJr#<$SJ^fP|WW0M=lpl!PJ$arc+c@J>t@o0fsL3mrkK({W4jYPbq#5aD zqaR??f;Hf1Nn;HM-6+5X7GrT~Rf4in$l4Jf>lf=LJvFwJSUn69fkU>XqNy9_CuyV` zMkt`GbQh-hJXmRqM9H;5$5iyj(T*oL%aE#Xp!HMet56isvFDm;TO4+zCD8T|Cq0`J zBpVI1#wN@+mB2Gh9ltOF-DVjRlT2E7e~ijdcNJ5*+eBxrE?4o>b;O04U`(RFiw=?} zWZy)50SARRwC9Z_hHPj!cI(%a+-jTeiml3tIl0j(gQwnPjmNHDw&T#go}e@ zT#Rm$Xg;pn*@8WO_+qOV-vt!&@zwqmfsY_Qz#fhF_~XdA9KFcaeT2!J+2DLQ5LaWz zO_SnUGC{Vd2&(9V0rI$z=uNgiS;dvP#aj!n36Vl%OXL+Rj2*fhp;J$>qxJeSSJPLk z&ED2^uC>*tIY9y|EcEgICzy{*@bN|;-@VbtBJ@G+#p7OyoW~n|{0R7H%!f-}03T&M z_Y`3Fr39`X*!WZN=pvlMq}qrIFHJustd%uqF-@V$_BpDbNyhU=c(~z%%GICs01D`g z4FG!4dsYwReVp5LpofE;pM(I5Ky<%Cl1H$BvLfGsXANe7Ts*0_<`+{Qe(I|4iMV%i z?fcd(s&d7Al#XtLkoNP(J|KK7(5eZGviDMtk1^SXga9mtvUPY0^_xZhG~-U9MiRns zHfrot*jyYfTl*^J$@;i*nz^cVU>-q~GZy<+*vqrBvym$tX66;!;a)#dY=UHqx=dSF z7cK`Xgr=8Y5?*3$PpoB?G_rm$szsLQi|tJDS)N$$$w@9%2dq-}k<=MB_~>Qsy*~jX zXe`8Id_XH>mhhxebAS)-e+mkqk!wqiGvruPR-~IJsSBq7&_EaBOuKCR1HLY*ahKrq zww6&}+t>$}M79-(7E$+Z6nNdEwOBg0FirNBC0hewRNa%B^kuJ?s}F&?+JZe8;CMrH zbar1qzAfxQoY2Sj2lluXU(`mBfB5`TPlfrQ$QJN1u*WZN?6H@}JauW+ai>T)3xZYS zUY5U=jG?8uf(DcjuG3Y!P?Qr-O6}&@p!RVEna_HES?t=#cDoRQN7`6|;(OkyI%xcB zQYd*S$g9(Acf0Ksw?F(&cNee+;G=0scO#c~=H*@uZrgyV_7*$$@qMU16usQ`htJoJ zD3jaQ#Aw7Sa6E$#cvG7!-m`zx9oIf$r9LfsKa;+KA%#ui88;$IAbB}iFiKM$twwXW znxY$3fPri$IBnui{;Y%LWH>C*JS|*seaSc`ox>QKu*R710o(>$kx zd;`DKk}EVY#A1`RXAs{@6KXEA;9>ewp*<;sR8yIJCw9s)mvX<6reV<0xO1S|B>n-E zna>%=GV!ZT%2Y`>GGD1K3z9+dx2es9&wlV#PSPOx7{1T%qxP9k$n+u%R_=NA#<; z&0V1@Q>k?GR?LS@Twy*o`uMjbN3I2U^D)FCM%A!l47*`-#l4>GQX_YU#LSV^)gz&0 zde}PZ$0yk1Rm&%)7rIoGBfM@O-(vAW_9fxRkKcZwix`bdHLiZZg5BUl$m3LGt2&q8 zKbQM4wCj3y9%bYAVm?IMF&?&)R+q8Eu%$I^6w>MEShy)#x~FA!Ze4*EF_y`QdW0fK z-ZrqtlQl&_i|;%h{22MT**o6RvD1M*UT^df*rO1k%WQ=!g(u!WefhcG9u0gz8r_eY z7om@Y9uOY}9|)nAwNqtQ@qBy=eS9PE;c)t0Ie;fN*k^!<=9aE;VPy$jkwA4x(E#o6 zy8*jm-C_lY6ehzH{XNm!1{x#nV+HxV7Sozld zC93=*lW)-n&EeARmFY_HgbT<`gkvbI?GfBH;#5jW8IC?t zmwA}CO*NSh?sk>#Ep-ofwzu()jC$cRmd*O&OR>IqZ2Buq;N!J7<;0J%VfaxZVek>u zN3;5{-oram*NE&;#n@Y%hkz$6s$x^#!Mq1Rw9{xj`UkVI9>yry1h_ z`lcJ0f2n#_cG+A8?LYUIXewYVV(eh(h!GqH;38(PT-yBs8p@IS@h|Kv>=8)nFT4-o zJ~fbrT_S9COBdY_^zj?m1Gy<49|j*nAK$;x$Kx?!(~+~zF;+Qz?D8fBlTOUx&MvbNO9`vM+kbZtAkvcAPY*74D8d2|aaN_R=R}E_+w>KG7 zIVm)hr%JEr(bXWccxjy@lK%&4s7JvPUfTN3dZT;4(1z|TTKCsdV6;jf-5oNh6ZHPu zK2Pr-(o|d?JMSNHhQl;Mw;7p{@y?{2wz(Kr4$wsK6l4@72a@zaQ@+#T!lzV(YMi6# ztJwUtX#%XoiF+z$9%`8Htv7*>ZN%z-x6UO^c9|QU64_Me7KY$A&cJNV%#oaJZWO6p zr_r&$ix`z`B*Kp^?eamgix?R&VULgd4nFo!1|RqV_iIj!G+Q6aN4{idF2sUFMI7$q|+wwhHGH+1Cbh(3z&GyC(eYY%Vb; ztG(i|umtg)B?|o;!(Jy3#>a2rcorK|Ui1+60rnv00{EbUb|*Hz{O0*^cmP`)@!HYH z*U{SLOHwYtx z>$)af#tcnNnQUt&VYvNe>4_u8XFLt?0rNrHBzzqE&l4d=O(GJtG)c|`HOi;X@lww< zck$eUAHHopvc1LliX4Fyl?G^H-Qfb4xyLv zN%fkg7e=vZ&arM=NM~=F8J&;^-Dq@K?JbupEB({3K<^bNfLhW`>0)qY6)vD>eZD3a zYeyWKKeW2?$^v*A7<_2il(^v{<3`UE03q!{pe*QqiruRn32wBjTYAj;XpW<2FY8e7 zy6H@F&SY7ArSQq6@q<~fSv5bv$LH%ACAQ=WhNr{p^#&iZR?h%^eD~v9@3G-u;HbUX zH$N&G^P!;FrNfWEe|>)8>NAjF&or^lE641?%P!1AKSmieX=wXs6Og2NwFZDPodS>u zWl7Vrz_*?*PWcI;Le1H&C*8KNJxyGU6T#!neHeOxJ(Bq-^znw6yY2(% z!Om9ixb9u%I`n|}7~tdf@>DM!+z}_gbEA(J?X;R5ahZBGw0MWJCpE_0zz-Rmr+zNe zt2x{+c{OK9Ec&VDI}6_*Cn?!C5h7R*%&+iOt-Im z&{xB5n^*;mUULf6y?9jWS;uvR;x8JCqz29mWa0b;5;Kv^h$f?HDV@Emg&k z)v?Dm8*R)$n|H5*dz@7Q&H;rZJEBF5l2s zrr4mYCUMZp;(P%M9gAirpjHDPa*bcy5p`e>fsfgL-p2XGV;Ou1lWbST=ycq zhprAen?1L`zx?^b;Xn2xX_vHDx9&sm=oekJ7l@=UOAx(GJP|jv?9NORv+}a1AnSYkn`(Q}r&!E}&hyxsMIfiI?_yb_ z55Nam7nqMKdD*L#zWi8mqeI&x_mA~+)_Mf(@xu;2gle6fHjek&Zh3j3j~6U;-}?%D zI4#!=#7z)e!49Bd+wMqO-&+ZiRbJ#$DcRi)DZlo8!zzU+3uPB06P!{|(2+i-g(d-| zxeGqBC{t+- zMh(9)bA@zK8gksriiRQ8&ijP$^iJ7I2~t=to8k$6^6aZKH32pFpg67=I^F{Qt6{*k z`Zf=<8+4~@6+SEfg=f%uq+vqyv3h-@zFqcWMJR3sLsC*OL2q=YaOo5W)eYL)#qq+W zd0%m%74~o*cOP;Bg0hJy9CZ=z{ZqWh{eeEaW}ksPSh-*80Y3JBujA|Q_Zr*%-i7V} zd_0yPvi-}Xi=vp$odM{??b=9^gB}Yp+Wgd}qg>crkf=e5$1tiQ*>9qg{uTHT z{5VRbzg=%QS|AgBJoYd8#fQ+xiS+oPI@W${H7mmrGsQkS#rFaDc(h_bm=Axlmz1^; zX!h^bslMj*x_G68xQH^iVy-@Z=0o#mE%%Akqh z%)tu4J+>-GTY5SHShMauu#N@fh!>TSX7jgk>+ohFttw}8^XLj)62|GLlsdoVwlOmi zeQ0dQ&E%9qfsfl-8WtfEf9>#_BGkvd1+P_s;`+pw#bttPL!O7Vou2wM)_;2lj~C9@>T7znPIo&%EHW4*K}x z=jWR)$pnYF(m`Db1|9=f!#B+KbSd`H8#0-mGbou6OzU|u2^-{HW6;kmR#&+{&2l_Y$DW;JY&^zst6OE3xG@FwHY_g=e3+v~GXJp9<0Wu}y5982j z-wH5pdv!d(CuO3CYD>Olj;+z-J>N*PTGocADfY8@X$Mbai%YmJ2n4)sVk5>pg+EsX zmh6s&paujB8yA_94bU%F2GiEpTwGc%D=~Z3W&xG5cWHGT9T_$QLX$V=u;}fOSf@l);qA!2*huFW)Z1$9Q(SMwJ-LfI-MS*mJ3XXyytI`FkeS z>Hk5Mug?GTc)_LfcNC5C0QxwK>XES2`LLEh$DU_L+fKc{_@;12fRCR~=;OPe4L-7* z-?1I&gZOs;hdAujW9dsiV06F#0DNdRpww3Tf=d;re@MLtr$5XRCg@o-*JacFOj}*r z@kc@7GaTM6kY%3O0ud^%yU1F}H9C88)Hp;4N;sAZt!Qn`XYJwWy9+N2EiljBXu2>{>$BB|Cmkm%#7S7t?i>|?`3`t{) zu$w<)9I)JA9w;o@wxYO)MTAbh4p-pgcuEOZH-nE}{sc2>{l{|IUlEs6(-ZVZ)#`9; zy~?HCavNALf5OyVp@VueJu=+8&S$&smDKV2c$c{pyA466%QhF0>E%1~;d+;hT?p{Q zTDF(_+j-U=3(3d#h8qb#NWNfm`umR`A2PwbY4a#uWpe7(gE0J|q zumAhVTfe!FpCjqg$d3RYKYw*wcfmK{12*ws>eo*VlWX?l^YJ0-qds5ajb+;qYaipa zRHrW`7M(lUDb1yFp;Q}Lp{^6fln=SjDUFV$et_#yhSqwjmy1lha9z8y(GM5~!+3-z z8A%%c27!`#98mKLgrtF?qX`Ahyq21_I%Sn5r8!GzVxniGb-P5jOr!FVn#MYMkB3qo zU^}t-UNKpvXM1epI0>b1UDrlxz#EP-5SnyP!>S-zm09Gi&$U!xEft_=U(ARV7TVN{ z4f_g4?*Dq}RnccZr?!b;0mw4yyE&`$>-00D`sg^qW6oD0#X`^8Jv<~dYHGcsex=>5 zQ>PmrzV#Q&t-yzl6M0tG7OiCke5isRrWy4hW@-l7(pd{dfonB_3 z?u9;nY|KYi+hUvk{f~R!;#G7WY=^?E*Hh?2_`@S-fREQZ?u%Qak%R1A-l%zbH2=vX zn@S6NxfXB{9FqZ3yM`A=q^=E*v(9+n)qH}+Nbh&)Cu*9enj&Qt@&3(vWlq*o)G`MQ z1pds9yu7)&>%Ai_w2tw{PUqU*#C%Jhrpzef!PLLtFtXx9%EuexkP6p6x~mAoX8?b6 zDnKSwvFzBIM69W4Hlw_5@fKUix!T++!YM!EdCG4o;%=jR8v*mu=@9nV3HLy~EEA`4 zTOZ7-Aujl93^vxeq@3|}p^ z$C3&7a73By*FU_}dG_%NCGm;*K=kn=F^N8Y|L%Ezd2lqBcKxVpT0l^qyf+sewOKC> zRrC<4*=#(i;JQR=c8+bPYsb~&FNwC%rt-L1XtTS;)HDJK&wpQE+%F&k(-DM#8@jj0 zcJ2f80RckZ#a15&_~1x4Mc=@`Ue8aVRLBpE#^i7cm_qZ>VvrPWF5+XXBW#X}Fsz)4 zD^)Oww{8t}ebyl+W_tnxDju-j?a&GQOIysvE-4im`~-l33Q{Gdp5erqWAz+M*q#zO zlJu#ATh8st<)P%1c1!Sqb4O8C*2!hBGteD`4r`TOPEE&B7<<~qx9g2nFc*$lJAFqI z=JnTR`z64Ky-SBirR_^;hnCfeS*|!dWoF+Xw3Q)?i8Y+wE}k$wIw$26Ja)T z$XimJj1JL^T-5u$a9hJ06H&oWye~IbFZrwsjRzuLknaGvhZ7SYQQ!mg@l^vKZ`+5D zPl1ou0X|kErw#DoM2r4V*=>shd>q9VzkMzC8d84{L*k&yl9v0dIJP7QI5E>OpC^xt znR#LX(}gq>s1Q?VhV($#|X*j+{(u*H~rH^9|YV`NcM-D7O)c zDB=OV+IJ}75eT%EqM@~<;7hAzuEwKnEI4}g56)zb&iSIHC)#RX_ckT+Z&+5@(}FF% zxY!5U?67C2XxPf?Z5qEe!oFIyiPVsAsn~{ipm!U-M3=mPd{R4OOSUogwzdxwq*^w3 zH&_}uROO>E*|g;~w#BRj1PxcchWe1J)9=6>ItvgV`p*j$0C}*J1?2tABU;vLvjkB_ zr0%BXMt}3@X+3XNSRRUx#$`z3+3B~@;0%(3`gsh&*Rbux?=2UA|E zm21;Qu9jD_P zUjuyjqR}Y-d!=2LabIC4SA%O$n|*xj=p$*51A%-#4)C#`2^M|x8Wp{vXKDv~N2I7l ztOx?*W*xS{SgMBH8LSW=!rNAw&2Q+X zrobnT2jdVHZyuQpgIg={Nr#xNr-nU=ddC0xl#Yg(6^HbmVR* z!r`Y=n)`Tf1DP8UG;b~%#$!vsrR4q8)=8oTU8G?nw%!arZmX)%0Ux%&xCS3)ffv^M z-V!yn7VC0(um+j6yPA43PfhbZ?Nv#v5UHPYQrrv}*2@#ISIxpLXIeGxbfo&I&SKEW z*Aok{sX=eX$4w`;3K`+N_C0~@)eF<;zdbI%$EM?M<&c21&SmQfvs~ILcT)X)+3q)7 zYFPjdY*D5cSo5(c1;hroxUNlkzJ{`2`^@Nstv?=69w=v353&MhlsqW+^A&gwO%xYoVSyOB>Yl+4pcI;YsTdtpS-c z9>1kbkldUPBMmdTxl_V`jZlRZ71IYZzH=K5B?~xeDDZzhpdo+OR2cvzxFw zrDCVFbds(H|WofwK>u@2yU1K^Q!k*m|t3TGDcA&>~dPD?v# zG^c zpI3j0>bWYTRH8eC6`RuahD7ETN0%8t3-lKJCFA?u&R zYP&70G{DVR@q=U~ZP*-86St$G|7+d-K1PohV-JWAx$Ie^}#MUitoL zS%}{EecYkwWCb}mCuPFLXQEvpcsdFy_))(!8#CrRgnAXe$l-L+UzJwa%o{m58Gq0Q@zm8TkgvaJZwZJy!!mr&>iEc6B^B-O z+byP|)Ko0Nj!O9pl2KJfAl8b34ERu~OILjS{N_Dg_m@I5SS=ZPcMAaCZPv#c7M*Q( z>`~muuU|dIootVh@S@TBPFnS|6s4+ z;bqyhdn?t!eJSO^{Qw_P@hhqoMv?5VKSmeEih<@|z?h1~0MhRe`+NCtJ>`^8r}mb1 zT1U2IcN?3)#|%A`cTu$q@&p9D`to>${a~e#{w(nEI@HOd7pHrnN~AKr7$>+(A7zAP z@Znw9xZv(_k9?88;Oqld+)K2V$}L@7<7&7&*QVeh2JN4Eq}t)XxT~Y7zGrMKbJCbvtLu7BJE~}E-sr7)Y9R+seEAdzjseAFHdA~97A5;8LU=E-XQhgPT zIQE~h<>^-IAZ#*|998QAjStGyb=_%}8ptZqtd&eAjTOF*lDO$zhI5)!IXa^$Tn=8i zORp8)%LDeJkyBl6r?hKowwKmgQ^9TVnGat5+cj+tLG`1srxFFQqCJFM^6<4b!_)p@SLuJu%Ol);DS4nH9rd(yjq5@u%FgKte) z64$J6P$mW7m}Fs!S=8V*p1dDlj$4YDnk}F-Ky?`eZ-lR-w+pkRe`R_J=-%oq3McM; zUIae6;v>MvmwTBu1&47O*_W>`qYv>O8adw>d_>Iq&KQ!WC-Jx;51NLC+;8MmxL^*P z?yIz`KZSmLR!?*`E6yQV7IY-3`5=jx7ml9-&w`@)8A;t)5(11xE}pQaHsftpnjH3~ zJE=K5Uu!<5XT!AJ6imCGl&s#*s(>UXNT%tjxXRhnwB8a%6Rrf>__}sI>5Nf8#QS?id7?u%PxVw&XGSf?&E(n6t)p@QewM9jxM9csmH!euObeWLr=RGC3$tcE7RDr9o zN&K{ihIjAk)41{5_aUOWm9ejnB{?j>ht>^vkE71z^Lbc{#i4LLl>fiK8=Vp-=3{r2 zc>nS1mml}a+~`!0dQs(X8yg1C6(>UT;5V*Q%O$8<~RWX-idljRO9RXMF2dtmWFyd6&Ekj~=664d?aHlYuL zk1rM9NFbD}ZWre?p5KBf`4@0iNvLDic-eR$;V2q#m?Z$-jMa1;cOP>jVx09S=h7ToYnEnvX#z3USE2}@eXUOHePyXTj~pM{Vce)+hYAN`(pAY zSr<)7X13eF$9@bmo++gofGNNfIIveb(3W(MaN)QS06L(E>BDN>;|ECfP$vy|891e< z!}{%+6;af#_FQTvQf>qQs_mWJLn5|YzMRpHI5C`0Aw^?T6Ra(pKLh7_-FzrHnw;Dk zI)B07*g`0kxLul&N^DhX zk*Y8vA&o*L8mo5}i>eI2aav?Lxz03#DGEbw1ALr&$$k0xD(h=8w0@y!@X_Gw;{tr( zt6uSy7_dWFQ+BfgdFsitF#)-goOt@}CK8u>6SO(mP*&|>G?rT`d`=O5r25PwHH%;s zOsZk;=OWuBXcxZI{mzy%*xfGPTgOVDWxpvh(D2vO<3Q0Va4hIVk200@hhKjq=YqK@ z;N!b@e(dF26yL_-NI)x=;y%hGMxfQq2e0O!sUeyBFYcqcROx+hclVq(!TKl3vutv& z6D<4L?D9i4L|Zp!1v1eOi{EB_v%qtaB%vn{+(MOmRKg|9@O*IZUg_m|P4m=;Rj3Eo zCaU<}$Au0zNPAJZeM0C>;c!y)d@zW69|>v!@4}barc=1xS224$i@&!#x=3y;xhivm ziLkhT8>NnS6(!Bhk07pWN&JLoc$SbSJ`Jrdb+j(dJGvnTOb!J<=Z3PcAuzNYn#GxgY}J)-DmPdKrQ zHo9VT16)poe3?r`3Rye>AZ8Bq0$S6tJGq~F@>y2ryiQ1qIk(KgQ7i+VymVez>~_C^ zwGBpmzsZ`}X1Y3&?p?gEw-kQ(&eL(7_e3RQa)o#?M7xD^jBh zs(2v1Sy=Rb0oFDu005a68l+*<<-2dY03ToOdJhU?ll`{n^nM9G8ua+}_}{l{A+w|4 z*)m{U2aShTo6u|pMJx~I_8^#C=UyuB=v$v>3i;B97LUBR1wb~Vn9Hrb(mX}1sUMw< z)N9I(^aY3-RNjXaC@8pk7s-Pr*|Bupb`1g7V3j=hwO8CCHbwF=@W=Pxz6SWrl0O~r`=ZPVImOqrqp?<>c*_H}> z{Gy|9!8>&5P&iy4RoArHWxXPLb(2id#Sxq!DXy7*tJECLgoIL9!+U>sNJSbD;`2tb zDeQ?9B$q(nj5l&(k%?Z`MKZxIixh)zQR>d++pFF8nE7)=D0ArRR`YZyZiV!Kjnu4m~Gk#H?t~ zJeBLcjtR$_aSABW4ohPlMg|lC!L5;}P~W?JNANfuS{{wsZR1P{Sm|F$ItW2JNm5-W zgC6*@-v&i(X^Y7Z$Wq3tAPP-$9!gkvIYRz5u&=RBomzsgWCJpl9uMGy0mJdT z;-Ub8$v4SVwvppyI(s|}@lDlBksGt6C9$3SCXq2 z;rJoChAZr@mNMDwE7N_TY}&linqCTzZU2GM*I)_YBYeds@Ug!|oP>5^w_X=XG_s7q zk7Tl0H@tBL_kl>dcLeH=ei5=(R=6=sEBIBYy?r-d|-3&fVC%VdIRnJBuJ@PoyT$6K81S!q;Ul%egAb#3YS@%DhhDe97+j@tv@T znGZtX<00@-0NyKMxqSdW?uX&W=Pp)m@y+86J~Xm8PpQf5Cu>e|F_j@#uE0(%8=kGJgF%*c)c=2I05|S9*fd?8ufvi zd*7zXWxl<&ZKiXz!YU1}p0+zvUwSLntjws(LE*na*Z4B&36&lbN{<0+&rGng-(zBYjt&XT$tPTJ?B$DvnU_KIknDe8u~(L~Y@*Xw zg1EaWRN4L~RiV(y3Hde#JowVW;7}+Fo$8D2N~p3rCyURnFH#-)NdJ89nMy8*zvvaZ z5xsmrnFz|*Q&>QbkV*Z~`(=m(pO$uz<@#&)EW zoOT(#2%NiUX3!Ir1b|qBS6XZ=w;>_$J>jel<)PCpNScT<>+_AjI2BvjEfAL2#d7l| zn!#D@_d`N}Mb$3Ew=X;(8-nZ0@k8Y3Ch$>_DHl0v{_urQ5;`SHZ0jJ|lK`?AaeV=z zs!tCD{GQ7$``zmYpef@N>SjpQPpi@u{>_4h349>iZfl#h(f{XM=wUo z55|@a19n8$>V<=BJTA6A@P3@PH~J9vP@KTW{Th6D$Q%g7W@8_qkD|jsmGOHJ0{U*D0kM?|9!f6mHpq*eaG-R5HsxJ-{#Fxz1l` zp2ND5DX;l@YX2#(P#hZ*WHREFoQ>rd21BEI;3DfQTyK7~^%N+=vw;bLI&GgXnnO&p z3>27Y2u-gBA2c=98dvrWL$5W8dnxp*9L;hlyEI?LE`&;`++juCM2CAWhr|$+!_ePq z#6&hA!=A7cO!J1W=*V(#d5B#W zSQ|``dFj@dOQf)Cdx(Zd$ZD+$(=Gf{Qla3phJU{W5~pkvvW|iP=)^MNm5if^X3ZJK zhBbVLSuF&>;`F9A;L~kehc>VDdFnaQrGd7Zf`-ZcSwnDoo4`jO+@++kC93lvC$gve z7Y-1qKT{MQn)=3{h8+*FqpNy;kt!ymDJ3M^uclg^=Xz=-1)7zbH@+Qo6(2( z3WZH?Jd;$uuD}O+4?4;1|NQz*VGkSHQ1rYaSR(`zIFnPR4!7>&fZ5REkWIfFc!a5W z6Qo!^2wqksQB3BbbFa%7LF+K>iatiU{P~8T0&1_ zGm}(XV*6Xf5{~mcvXKT8k!<;*-n77nv>&>ONBhx>eXms#+WfhJi9$*B9T@4ers~}E zO3b4-qVQQyB1<)%c_RzOVy?$aphM?bT+(CCJ_cqGYh>X(do*z#Qb0d5p~f}Gn=_UB zzZtdjK38Qh?%dgY9SxZ*X=kx#$FpfSpj|pn=2_d~)4{#fJkcOnki|AB_hbOqpH3?g zZY_n(aw^c7*B3H!qL>~ou&uwBGMr)Bc#&8z0Yz;(2;Qu%;u?IoVU4bWz(?H=I08(I ze@8!k_=7X%9B(hzZL6Qz8S=H!JQtMglgI*H;Dh0g(o5U-9KO)K=sx_Dz(?4t|L}Ug z{}SSZW;>1!K43n&-a`TQK;Fz-RPXd_@Ug8-_US#?J4$jZHkna$q@1CE=N-;qPEQ4D z14q{0)A?UTxtm7mUJ6P>;#zcgg2DtJ_(qd7oo15JWm<9B@DZU3o9ONFFJtGnuBzzJACA{|Y{&`C#cTJV%AS zW8jeE<2xPpzyAauPlt0|FqVnKlpp^je9tK{GY?Cw<&1PjE-*3x03 zF}<5bh?;?zB}?|di<~al5xXm}!C>_TKKeXcrjR0ihUUXdYrqOtyIFwFbMD(0#;%Z@ zE5I=@ahB=ArD42t5!Z1?63uKTB3E+3Z%g5MIW0J%L5@iV>Lo7VBhOasYM4j#7g7&+ zgRy^vlVpb!{oY}tM$3PaeoZjDgP{9_tE~Y=gRA(F9XYx_(B1#&MwO-d1$+bY;WNDq z9WnTkm{0Vw4yxaA1%%3E_w6 z0*jiis9pG$7q^L{dQINBHlFZUrx?YFvlAs#r89@W6YdxO`B`L0F9Rbb8u{x1J}_Fy zj=i%{H-$@T=kxX3i9W7bmjOPW$BnP$qv0Hinm_*d{B?kj4PaURQ`bTBdjhXPc3(5FL^BEZ-?K;M&UrYwdUkr$zh^;FQj>7cD&6D z!3xuJuvp=eIivqo8FK|e&@R?aA*~}lK&kU#d#$$suRQ%xgAy~$)ZD#)3X3I~g>v1u zIsmBVb9!DlcO&kHXFNL!OTszVE@f0u;l3#@Td1nr9iR6t*lUr=ZMXTZ7bW`%72#t}JH~fPQyPlU9oEI;F1gf!dg)D1TIo0KaH^#;!H1F;;*knYbqGTSer{E`^QeeT>A}^ZKmCC<-mRH#7cO8fkD?V zNu|>Vy{`MB(PrjCgWk&mqKGM7!We-Q4vx#^u$Tahg}$X;rlRgzQD>NQyN6zzDJYeo z6}*>+tSm8(4)A45vJ#j?mHy^}L9d=(dN2}V;j8kD#i2`3i@P_pp0 zKAd;;7H8=$S56OD6JV(Hj%)$U>Cp+zVs5j;4sInPkw^B3)-A^6vy2zB-KK=zW+Pf- zQjvWGV zpvUBluS0t+zuhrx-i2Af?cK=0$xwpEtl4oUH~r1+FH>}OL+$3IzBno&L7kBT9dD3l z@UbsLfN;t~rO2M!WQLnM40+D$W6y%kD_l4yk5z%#Ig?58MF9j~st03px%Jym{mHE) zp}@!YvR41&};m;tgCX}5m8K6mX-j}X(*%!Yf2N}phYCpX^$S7G3G(aK1e~hw0u0q zLK$hFsJvrHI(pu2%LcODh&1^Lrj3gYtLe{8F-9k30gs0Y~Rpf|BQYb0_isv3lCtEwg~=$Zq9cbU4f|5qwi1{%yKz|-jrA8l(k|2leB-esxX)j+TF^f4CaFq7=c0>h758P zKIuH!`<$}NzRsyM;F4UM{$iOEJtpSz%A|jKG^h%&Z;ltV)PG}-*Q-(H5LQ*4B4?qd z1brP}77rx+c=I05J;GCzsJ&gd9d1wuy&fN* zupS+Je14n`=_db%0+<_(-RD}TcKa~;_}ZsUt{4*r9LPP>~dIT69=CZ)0c*_kmf&=Xw%4{EFtNHy{%25Oar3j|_Y4W)|q zlvYL;nb~;chIl4%2NRB;w(B2EH>FW`bsH8#VK+VDRY}HeA+^P7nbOc^ zYP3plT3XXr^Y^foZ0$x$zFwuuwaRtyk@(}=Hs<{XKHTG|%A0$&OZU`W&$_j6iH?>w zbvLVeGf)J@bUx~-*G=f zKC(rW`pHu4#tWraLT%JSrl&uAbfr9w_d>nBer=G0wmhGM`S7q5+UG(^wPVWBUZ<6I zSzfE-oFH43qHh3S8!`IPp^X;A;7Z*YUNwEB{YH>>)faiy*#wcCuF^S<|*@z_C(@EwsMX5pNcWG?_7Fkq9T zg63c2`XZ^QkJyA+X+dE8=JwElkL)Mx_SyZ5PnTX(^ClIJTgEQ#hzeRrL0Aip9qqEU zHvo~*rXL&uq>Cg5H=+)`e_7hzq4yJRfXOh7!m@4w1SQIw6WzXnTk^_kn<5+ZCxijO z+?32ip2a$Fmnv$?u^bn5_8xo`Txrz9Wck%zy^b+34KxKV?$kVC5lD*Avoa#i*Ku?= z;>>sX-R%GAh4FkCeEe~^kO58wH+v0;ey!BiRyCUy6x{y)wGCT{E;pBEU@`bu(&xj- zi5+Ej2o2X)Qd<4dqvgXT3r%otj7-#)3yn&GkH`#rw|&ki;zeNkdqejybWa-If5!Gs zfwkU$gjc3}qsle}N~!SNj$h|?fPfD{P)<7rE&Rzryxt-7ae@!?$76{x0cAtBdce!O zXT~6a2-Xoah^9nnO=_4&v4?*dDiiG6(_?PB!=N9DYfmf7A+Bn+cQj8|vR|;5zOvSQ zP>Zgk^A0$gr*S?Uy^&Am{L;M5@AC$-Tw@}2J25G6(l|{q#R!(Qmsm<#cT;*Xr(^5B z(>~w5U1;_%=4081F|>6p$5DrXueTyQMnX0+Cr15>z9$S5BGh4)d2~JJWDrgsh%pTg zUkHTcK23m=_=rzB#QB~<_d_*qB7iz4Hr)LL5VR#h*gAgqf?X-igc z@0z;qttFAtgmFF!b>mT#lNz)l6qZAp z>Au_unzVdf`fYc&h&#l{of@ou45Ro4B34s zKK?j0A3M{6aTU@v6({3)klaHM&IKT`sf4!DGiBr4Cc(;qElDv|E+LZV~R1&{9mzV?DSQOaejXbbX^IA78@ zhhJ{4qhSHs&mrkjmWDx>Lj3MnQ&dSMcKpnOqgC~wY|8`?O3n~22VMFBM=mqlq(t-C zE%77o3ora*{0=4soxZUY-#1$&X>OvU3(_Q#31vt9aN8)omUf=$VkrX#L#s0kw9JRh zQV0}B#Vs!S{U+uLInW0;ltdQ;U*M3Q&J87P_|7PCGUXQprKhEJKL(zjvs7*)3!i9W zoy`h(P@0j{H|cVEz|d7Yi5@D52wor~(;dO-KHB3bB?)D@_f(&TZ;YHFv$!iEWH&*_ zn5?BTJP*_Od0)Th_KE6#n5@=0a0kIT#{<{(%-t(pch)m>t)=;RV-IQ~XlMDj34c}1 z_aQh1d%VCNqZ|NZK%Bo}Z{WkbJ@Z?3UnGG*^r}=m#dsM&L;0k(>C;e6?#P37Z@I(P z^rfj%0psfHO$M$k6BjLZ&X(vNIaWiwp+7KgnjA@1SoGr@?rDpg-X&a4Pu+C^zlc5k1-LnvOgUp+w<(>)<4P3 zER-t}hia<{{X`OjWQzz8y5Gyo9)$;#4C#sP7d%GED7$H2v|-I&3QgvqrEuz4U}Z=n z0g}gH1|*ltgMQUX10A)_EldPi*XUT>tvNHau4lA(YY4Ne#an9u;?IZqP}!4uz>&FE z^u`H7h~CXkHA13;3!JzhcUP8|rcV2=WnnWn!zQAb0Iv-O9}n)|vUZcks7!Oi!4q(I zXh|yS#pWIHQHuo5uCNtclI|k2zWTH}T9h2zzmTq0B>9sV&A_El3fADV!71Mq1-j<} z%p7-RQH&d^IC%l6*30ZWZS22~Rnq%(YH!UBySZ4npl`G13UFSte7%|7=7L3PW{suo z)%&wk9HSflhde*WVxI-00T7{exr}*b&=2e}s1nl^&{vKtmTs@ht`pt6+EO*DsI<#0 z_(i}H5wpq}b!xlz$DBk`$Fo+4A$E+H7&Mu zC7<)xQLKZ8vb!(Wj~#e`cTg&7$H4G{)U(hv^Nc*^k+bb`eb{Y0ODEcm5d(Z@k7nW1 zvXMS>MTWBku<}~*_VR(?Mo)QtSI>>4KYC_5zVdGBz+eVr1I&vd-f>^>vGniaHEU{o z@16RktR%#lSQ~m^V%IbZMluUHC`ifkp>A=YG(w()!4Oc>sdU;4Q!1o{VxnL^>V8)wpA)M*tJ)DWXB zuk;);&(qv6G#^{bL(#TV-!I$)<`&1SYjbo~4t@|6f*Iqz;~l>l^#Y5P)}_pyWb7pv zPA3waS}zXkUO%@tVgBtX9*%EKL0}RejLPTsh063D=TASrPR*icN!R{pzf{fgcacLz zYdvl3`ig`)j2`YljE~7jL8C7@rS$GE=(<8`&HcrvSgr!p)h@eM7K%QtPh!zx(Y?l4 z!1=}~o4aPam*~YTl=(GBrf2K`-n7W;Pj`H}%t--1P@i;}IGKt(zT1~aYySq;EV?A9WqNv;5@3}}V>berugYvC*j ztHXQ@I3|D+=d5SZry8&R#Dpri1jvLgZCCo)Y+jp83+T1kX5DA}AOrahd2w&v!_D9K znqoe_9ffwx!_L2A>v-sVL1Bh9z{h(f`}4Q2mt3kwPYz5w1U|%B+VIsH^ueU>bDEbe zHs;>ZR)g6dG74Hh48dzYln5TODhpY?-C$0pjL6`l0>N9=*N*Lr*ENXLU&rn z!M68y(N7h@{S&NlEazH;U45$ZfnSc_%IDPf>VIteQ?KHk3$UOT; z=tjPXrcA8$IirqU0gro8B96uz%{B{f-nlbKLQcOG^?nyCc$Fwx+p{emL|UtTCp0Kr z-^yInJ4PKr?J4*)CMPCH3;<>DasKmI+@EgzRCO1-vjnwRlWp!6YvGTz?{^mZi(b61k65py5j>! zCQAKSIKoygr%~6pyPRVt4Zc!VR{O{Mk|COV`uABA*>(wU@bT>!wU1nLb~{{@0Y3Hu zAIn$xd;IzLPwep_+C#~;HdGhDhY3Yb2}ZeFb&Qsui~{ITg)3ckN)l-)%gj^;GMmW7 zTxJ~efE-#+=aQpBAQOBLD9)Jcf|7&9irY8JGRhdR^YAai2%{A*#MuvkVQiZu$m%1Q zybCRGV~vugu4CCQi~=~$)6g0eogOEz7bQli!7A#@G;9}bv})Ah z9V#BsK+WVCC{LlLwzh83X-x2;PY^_;0Ro5>(Fj+Fomj6}F31BgX1|~7KKyd7g(F+b zZEF_x(R`-?$<#U^VZdyb`y=oNkC0{T+&G<+o4qQ|f2~kJP=g(k`KP(w0%s78q38me zey&1|P>9Mt@sT3(U0f&FfehPUkoJVE$-WDn8|7IPV(uuvarX5x>_=Dh_>xCQ6UqV= z-CI_BC7;fEFs%qNVNIDZiEj+RmsvY`t_2Jg$eV}7Z`l7n8Yg5AIqlqroK>L z4ou~FF|%L~S0)D;*8Ph|C+nrM6G}bt`Bpg7n2s|>C8BggZPptYX^@Igmt}k2FyW2| zd9B{$i0smF1|Zc%>b_g|G4-NA#i8T^J~Z}kJa*GfulI@t_}spQx-l=VJne!N7!ztP zEEi#8@IK3(u-h&XJ6t5{d$1tcn`&BmpvPZd$NpS%&GJ{ycn*hC@%CwL`lB)~tLIdK zZkP}JJxI9N%0_~=(Z&EPZ{pdUgW3V5Qk^v~zy~NMd(x#|@8QmOL&!_RKbVh>EVMje zwyrNohBzjbW3fwFz45A$2OEQ^c_K%kIaF*hIVlKNbx!2CuE>oM zAD}DLKR0z#oNY&58g4}AP@{r63j-beVlLWbn@Wu-Z_4wVz35;)r|>B-sKexpbbPl6 zL8)uKt)Es+3SNfHMI36YP{Ade*el(-o9{4);Vhp^zD+8VqaRWqN+Kga#x^`%DyCG) zG%;jsCQgPl+1!aOZAhN;0cJizPRQX zU)cm7thIy&Ko=f3i#DZM?JxfRPd|-Aijxfm*S^_J2@JlaTefr{uY}A3iJ=!-Vfx49 zyi+k$(hjY!xz}f2sNLJOv7EUL^GO+;d-%;8tJP>8t1$TJcF_9PfRC)_!nYaKFlA7j zO=9C3+<4R(^z|Oft%o^fBV%r==KA4eaUZa$g+LN~{P~x$hb#9aPBRcS_$Wq95_-)? zdReFmtCTW95Zd<1h$V~z36e~$+IX6Sb1Ao%^e9p6CVc)?B!uaw%hX;YZ1hNpWn7zJ7FuEjuFS@HjK6&R_WN%Y@9sWpIqdh!EJ6ahl$D&60zwOL zRJ=bTl_~V%tAO9&FZ`4>#x_O^vwIKqT=8>ALAB~vv+(zVI3j%$<&x^Z#dRhSEJPQH z0z#l>(lzwP7qs!G7MOG_gz5|Cnk@r5cug=}Ww*BO8Rn0<^c-ITeDEexLQIzu+))Xd zvhm6x6w{&IqSr3H#K>VPR)e1={hw%zq2hOp0=R%jJg{2fJc+iBg_+$-1{_l3BKzCG z*%M3y{N=YZHvT%Yf zDW^#zl;ES9CVKJg_z<024fJ6{{NNtz)*tGGRIIcrmHBd!ErN1hTO&L`En6ec!q>S0g4MYVJ?>PArT@uO=##CyEf!!BY2 zd{qCOdRRYDT|Rg;5anzSxVl7*T2(c^tMxrIBgj0Ys=y5b;}42P*T>>wtsp^161*lz zZ7f`CI%?&{hYsls?bUUGEbF*S&QnsR^hhl}TiTS`)o9EnSIV|c2V1NDd=6mbW;EI? z?kD2N&;sQYI(YE2xJ3LMng5b z^gJTxrJA*^zi{d8gD*I4+460o3}l$%?i)o*KuJ*_@($KS(KA*atHwEG8x!>BX!f|L zOu_ktPGSt;esXus{!G||t*pmZ;iRgM4RaVOpRuOa@|l8D@Ik-J1F`_k{e>ok41;80 z1N*6_6xV!LxP?@Ac1J(_bV{S8WXS9SRdBXSJ1`RqT)U~; zw~gBJmRf<`nk`G|5<&8e#iZs0_hNOgE7DKR5^d0q8;ZsS&uhCh!snoP;pB$_&y|*lXrH>9bIWR=n z+jM245_b8eq9!dr_AcQ~#Td(L8Z3WVHn_^+SL?{oM!nP#Cd=oIfLF zes;1WKq4(4xIiv}SC*YMj==62M0&so(n5d^s?QN&&=^@ef+{11BKxeE{=0BixipWs z6MS6Ug4fsa^+U#DRbzXUrB2UZsUApVs!PVTxhWYvjIDCUj2$o~iwp;Ljp**Vwn}Bv zE@z-iNCWp#Hop3HuuIU+PDL>a9LvP2H&OG{;!n*5+ckzjnfh+`36%!bs1YM~7?GU+ zDzu_@dM18E%e)`^<@IY}k6(ZNh6KJMj3Q05-X&1(uMOhK(d}R+{z2w8UjsyFJ*ud7 zCJi$B`ZB5K9Zg#eQ8xPRw`Xb~%G6V^JoM+_>zOhbs|b_?d%!$1fJu2lcUc|ITv_Ud zAPj#*R-5eR%r}Y-%1b_r43n%g3smJmfmuZjS4pQ{!4^W9SF`5BlQKv3SU0_rF8e+^ zYq9cs(j_#-55rrTA8M%BTfe2q}R5b7AT z%_j7yGx3y$kuT5$yxx1^CYI~0r&%U}8T#tLg{9stOu_-di1Vog@{~rVW)pgvEav*r zr?*i(hxMSQD-Pwgez+<7PwesA$DkFOcTA=9+!B!9`fU(d9ZmN<1`mW}tZ`!O4ZYc} z^nUV>mRnV&kF7?92;d{IA4^AdnCnQLV4Ar)e4$3_rM{4;@TcOc{V+g55Z(zrD)XFG z54tg0_RrD;ECqD7MsJ5odz^h*p&+BhFupz+!P%aJYB#XR3K@-xxGLlJ=ZBnsF)h=2e%5P5um|LKgvQGMbtL8 zh%4DuvmPb^Fi{iQ#0@0TRykXAhGVvy4kqc#mf27wl^G^? z=lm=QFY3%zU&2eQ-rX=3JbP!<LLhT)$kH9ym2%1wsOyad1-w`JoE#VONR@F1Sx^ zuM8zc02@VdG&)yW;1}~DkejWo_J*43>bs#Y-Bu&>th44L_gf7B+VSu{_P^~*8U$%V zE00X?l^elxF#uV(^7S@M#w??*=$dB^L4%^=ElJe%vDO1T=1WPG<^ zUqPO-!-)f}3Av09J#s$8N&fJL+ZKI#;LGO-TF$NbYQRwsa`1tKd#h;(Y#{CWG zlpnK&#rskKL}%JDxI=@Fj?l>S{*P!?8N=9ta?Vl3xxQ7ADsEtk_Q@v;zX$lxY?KVc zJLujXvJs zI34Km106s!DVFUTwvbb&+7?&F<5<8ZCe#GPQuh(u>+uR1;`a>X?v> zK&paxf?Q&&Yn+%WrkN6Gc*fR-St$XzX}AKFB{W1WP+QteI(-wpMHkn&lq8+eI7pH` zn^`Y-nlvAK98x&_7L(BARi6qvtZ6O;PfdF^oOQj2jJ~Mn{=)q5yzp zf91|~Sdn?^0$k~;i`LBTORoWJp)uAj1%USlt(Kw$GmV z<#5Wqj}5zt9Y)pc*0qe#eA_NYbdH+&5J*|2v^Z!*G7s_|WobKOdwH)Ty5q+L7Mu!hiygr-O2rEsJfI&so*tNG67xXeO>HE_ zz=0c?7y=r5Og!4z7Vc^E@ogjc8aF(0S{tTuXSSg$F$jUDWIE{fG_RuV;tyn}dFGw1 zVR{!1@sz;pNG-FAz-bjLathbk4qWSOB8kzw=mK@{Waun{5x8p>z!#e3FUas86ft0N zO2qGahDE3r1ztsTm^1dJbmiwDNJHq-9_)W3B6d2q*YYO_Lbb~%5h*aM-<&c^q7E(Z(mjdWn>1p8|`JwYr&{ zanT>QTNUE6}lm@v@M+yq}NAEnjY@$f)z<_QbLs7{by5}%v<8tMERz( zlQp{?IIv{Q!YtVKbp)R~*$5?0p>}I>le5${Gb_Ajdeoq)&n%tL4lqOL6)-2)BMXY2$5+Kt%~!poTcJn}P~k7S*c z*+S(kcrkGlk8zygr&BCP+_pbOOU$z|EoFkAoEc_gR8r*UHqPOVJzg)Pk3W`ffwPaH zu#NQadN4n5Kq1e2%#u1TK?b8d(=Oa+qcBBXEWA}*TVd1bptq)Nz2ELsi%=lT6`mg4 zH84c zCtL`qi1496a~RYrL>46X)MOrb!|7uwgfFKgvA&_dgNr37=o)=+M)q?g&issGy?~F= zzT5=F&dn17j>L*2gp;frZu?|835IoSMnJd^BJnF-U9UZQ8iJm47nBzIhA_j$voZSl z4p;DjNRzjt3e!*&CFV*OrC0RciN8M|pglVv3|Dx=&q=bOfj4XrtpD}(<>)j_@z3+I z?YD{$EKaLBcG+F~4ImjPS*4rRTVP9Lf^KT&Qrlq^(ki#4B$31dgGF38qRFV(Z>AX@ zr6Z>w_5b~~J^mk>bfE^^`OV!~;%bF>}CEC5>etpumc zX=;kN^9ww)@9*XyXZ-m5ki`^=LWLDQyH!OU!P3jXqD#*%hZ3XsSRoqKt*j{lS3w0w z=i;}Z!OJ6{R2H@T6n2D~FU!EA_HLs^5xz|!-KlC7{iG{c?aa;^Pc9*7LQ_-4#8S}P z6}ZO;-1gccx(+Gr5=pc667NK4N}TGKR};XG?{D<+ece_-z`!2Oc~ZReG90;laud+D zQiR7Y{@oqkoRCuJDJwgoEL0kdXz!y+=W`6}l4`~m?i?>=g>{WE_e)bQMB%9?(yo6f zQ$ziU4}qS++0z>$%PzZ2xHgqEIvtn*Jpmvk%6-i-R7E~Asv>}wO}A_-Q0)J$rJjJ& z<|HBYxOj7qLzu0GTO$xRX%`NdR1~J-m)Nr~htaYT1p<-*oD7%Kx0+LMJPy~JJi4PW zhATmfkYkqWeKh;MAJj=i z#H?c#N1`9dD3&ug$&L_A2ZPMUAPF-o6U+%+Rh;C$a10`{0LASTo08hm0Ccn-q?j+h z2g-D9fw*RC=iE|clGNTT_$_LO0Z|D}JJfC;^2Pl1wXX6Ot7kWbOV4Y6mUJ3TWmW9Y ze(>6WjISj(3~q4msqC_lOCV*PwoEQIc2=5Rn^-y>8J!}0;wWLPY8SrtFj??iGo}sC z-+-A;8@nQ7W$L3Qr>2}{t?7PIBcakOH<$pS7_4q$b~**8C;f4}-st1|>){LO)Emu? zhs2vbd=4T8KeH+uHfpvAe3mW+JI;6w<)|LBKGct$SZXP(qF3@%W!imxd7e9q`@C<< zP#E(XYuP%VjWjAHobzT@@5rO=Er*dA=DyWmy`I~lx!p7!+LrpV zXkBZ&FpJKuBByMS9Pmzm6PQBli>18{&rdyWsF7d;%n>p1pIkER(+Wp-%2xsZ#>7{<2AA6to9L1o&$XBJK*ETuOG+j z#nOyLw8Tw-4^9%TjyN|Av4SZ?)J^zMco}|uq+1YzX!RNW8ti_dpNc5}LqdTJX`Qru zPA(Z>&i zkCDO^d%D0(b`>_q7I9xK+(dj4D@N2c2z^Phq%VqObr^gAHjLCN^)LQVPh^fU^XO|6 zQX>wyOWk8}fCmeUHl7$+PB)867|j7zqBkn_5=d0FyCB%b3_?-J1I@ctQE9H4g}6H5 zll`NKleuON@FBfMvs?8l%>FAST4&t4j*D!?B~yzZmK15>HQB!0=f)$60XDm@+yqB< zvIllM@AsSt%rZ@@0D8`tGLFp32i#yNkRi$RTqJcesK3b_>!cv!{+ojZ8zN%6D$VGh zLv6ObO1ezNPfq8-NQ~^;tPfQclvNs8`|eKwr(}itSRifCt;{7E7TS-Qsy9(m|FYlM z3$Hj=WM@1WKXR^RakV`}%GUg%gkwm!o|Hkcnj?Nod%juu2c*(6x^gbI4Kzv=yW?GE zLo#%_SzJ9q4vZu7B?L&j|C1+Z4Jg#q7%4w2>#yr}EGrSl@pbI?PV&biW4SPcfr`@ALk7G_ z@{oZqixb6~B`5Su431n+J6ica`4h$>-O#6;F6*!9^nu^Z!;g;W>>{J#F%5M2xuJ0@ zS#*-cp%>G<$h{YiC*WTAqbV--8bB_*9AGC9Y1Ep1_QCJxfU8LnJq;49N}{E^(g-Y@ zX50)t>Gzx@zGuJQx(03oLsND?(T^W(qcGfbg9~~LyaZI{DpcRUTH1&%i|N3*(=a2t&Xq94(o>U4Ofzd;E2 z;X}udRgm5;z7CvKz?&{rPoF2$_PRMzo|KAAiZg)^@SPL<#%|NreQy0OUY!h72P{s@ zQdG{A*JjGbwgoxHseum|GeBesD@8}(Nu@Oijj4xBkzBxgFb}3uo$2yD?wv$JhAq(v5#QzPQ;qx1PBXb9sjJXU;Z1F~ zjX?ZWOFDmX^m_X?PhGY+cWw1sS;=YCZVIeRG)P_7ql>4X^*v}FOzeFP;Lc&SXWyZm zx%CB=PiVWy=s)40?Znc=Y)<>Q7*R^ZK{(>5mtUKdm-TNx-e`fsn^GamPJqj$BQ3Af{(!n zwqllL5+zC;;2QNNNwNu?SAPF}*Lt+8PxC2JfDf&J`QSA1XGWI3kg@ksr9yk3PC?{s z1NiedaU+Ff33fig42C!t?zS)sq$aC1qLk@vjLUJftk3s+CBfw?h3^}Dd@sGnno!Nj zMcvqGhv(S){x1dQ6fDMi%dv3Gxe28hU(p8!ll#44ICE{Y5X(U#-DLb8QaIHA@d*e} zg6`1I^edmK0f<;aDbjFz^l*rn+$Potp-}<*k8e*2PTQKs7>X)%@(#gEZ<$*noyK^( zjC=YVv!^7U9Ka;Zp#_Ip5zG!ME^p!siC2OSk3I@5-Km2C00lhAvP@#GlnL)4uOOtX zg8-}?Y`YZ<>O-u6GH<6>S9&o+ZKsN=f7!|0Z_5eG8bUt0nKth|msv9U&NQ+4`oKS@3mT;6*=I0uu2$I?BV zamh#UO!shdImB{@tW1xo*0ORdn0qk27LG!-%}LS!ENX$S6wZ>BL_rkx`h+-@;ubio z+ps)k5b6eIiM@k|lkfnXmwCnTKZpQ)^h6lGX{^IgYP|BYoIWz{Y3wGQ%g*R=PY~KZ z>k!Drj7j0+x9`VVJ@mt)*wr$$o$3>;@vsxrNSLrM&i?<*9k=L+^2dM{=1TnA?wnM3 zC?><>xQFdtYtf>)rRz=VLu&b1xVlvI{C>cuy)1;y5U3qKSM1tOrh`#zkvA z$%i-*(iQhTEjW$^E)@yBh+rsoY*)Fu@v zr-&;2WMWC}-~$p?Kd^6%KC6xEwHA>L=0;B#(j@cMSCGPtA&A z!lZv83rIi&0mO{i0EXR!*uT)FB5;zcqeGR0bW)up2RAm;0euf5)=T|8UN-E9b0Nsd zia@nH_WAsd9f=11a*AFKaV<@UChcg3Ht%U$gb=~9t_G?61ZJtlK+}&!XbNu9SHhsI z$U*wzs~H{uN3}F20MM-P7wb6+TR1c)R5sH$X8m$iyEx7RXy9XE;BL(g;q<#aWHute zr1alx=!bJXy*i7KOtU-@IrSjpqVN^w_ZLoKRK|8Q+Mbv(1Fsu5F}G<1{(|u(^{VV) z)r1@Xf|)eTJr*ghrQ7|LwtpBqvn0rE7>2fO#UHss?tjlz3__2Dol2BtdV2Mu1p-0v z&%YjDQw#5YmlK=}KGesbkPBXtOhlQ9)>R#^!&qG3y3OjDvleNSi0ce1n$ldxbC44_ zZq0sqWSGz!lt7`XsXkr{PN0qL5N_adE~OQqlov0^{A!Q@4b~c z@&r983Xtq)DqVMH_a4^xcn~dra`l8hpMS6IHB-(kOG15ChDU3aDS)oVZOpBxjEH=EtBDZBxDJef2&W-Wfus3s;TmJ-0AHKdRp zTibW{plKh(og&^dFSg1>$KV{{vHj`}BO*drjaFZd3fA`LPOI|Un#J7^PSA^hi~=9J zW3yl~>X5u#i^q%+FJ=Ujh`7RMvX8u4sX72*un z@)pP42eMci8?bN6p385Z$D1e<_~;2<*RqW&go|3;s2DSceB2EO)xosBm{{Sak$9m- z^2hTnf)>Usf;-#Cs)3J1Huf^Lo~0?ArW3O*Yg?Ty;G=1VZ9PUO_xvu_p;O387BKu0 z5=jGsjEd3n2zj{UgSN@n6S=(4-i|WKf1$TTQGAHwP3w1y=gc{-IVi|8_?MZ4T*^|K;Bv)07L6Y5J2$0q5h2SE`r7xVDOS)W&5x$R zcUpbg&5*aUK!oG0-@!+RM0J#~AE-ApTf0)650aDPqYY*8w3%Ms#euc7!AP}bi0OfC zJiNVQtUYty>Q(%>gq&OEME4{|vrUo&WGd#BT?k+9I;g8~5!*xeA;cf4wsXsT2ZRQu zm&nNXFZ^a86g5Sj`H-R`A_l_41RuG>L;yxW#@9uM?fo}sd3RjnsA8s^#5b`i<0sSP zv)w(I{}N3N9SxJfxHuHGX&We66%IuP)2WlUGv}Nxrmu2j0y~e-YS5Ie@>wERQS*$; z_C$aKpuWG(7}SP#BkaS%;Wmmx5?|QN2QY(46ygR~RMIeX+JadkKdP&(3*2=AjLxdju&goqzLKCB_!vcBahe9g*qd9ZQbxqV}U)El(ktp|BehU z-a-OG)<#{+n(iHEpi27L?KHQB20pq+YTrfWT9qanTsw7mSDb3UJ)4BekG!+4UsggIoKcO7%kSwtf%cNOcRn3REORO?Pa}hC7l>nu5NQ zi&uk?U5KUmnn(pc=Ej(~EDS58RS$F2gaY2B!@KGMT%_7^u{>gQJ=F_KH>Py<{88tA z15J(;Dsm6_?YQem`L%(QUOME5`(=aaqX=KuDFynCuy+4^m9-S!H7@%{c&@dhlwU~;Lg zHtc_jl;-OQ}8rZqT6h(*<$*hE0Z%m(tE6RWU++c9b4WU(Fty+h2W$h}H2O8bGp+kI^F&KYaMI@=)A7UK_7#tT zc<74WKHh!T4l+IM%G7J1Q;d`)G@}${|L!yw^q#|3ck{}6UF&-7Biw`1peXF_&YGhD zYIS*krhh7TRex^^JRG;W<`5Gdy0qtDa8#5Oh|r=i`hJo`!B*@9V_s5&NEk+Neb0Oy z1z2!gN=+8 ziv#Jt@6&hk+^5p@4kIcG9ZS9ZmS{LAggX!Htw{4Yq$HWQS#=SY1xD;}#<@{CGeY>d zaX=~9`Z4xi5PRysy>gL}MEPQ~29$ya(7)847YrP;ehi(MgvB)yQ@g$G-dG{!)|)8^ zd;MPa7RM-A7D;j~>4_5CBz2MOF)X##`W>MoE3A?xy4DDyBpu+RRf(n09C1cL8oh(~ z$CBc7T}H@jTY>{Vytq9rwI6w)N$*VtbtEaJhaA*#tMz>=H{vr7-FG-Gl6e=ggRIA; z7e_{03~LB4(^@RKQ3s`WYudXwmM(0yUX3hm0z07gEvDQqQtN2e37Sz7Yj?o>~P-GM)DzxS3Onpvc#JWSiL)J7ZTs(_(L z657ik&(2>RgfNzdtf!d+#VNy$?ikh)hkQW(G(EXbmILFvL`wC*AIoqgYB`;8$#`i+UJQTi1R>5FfqFG zkw57_nSa`3+pmKi2cuSC`ZI_N5MMrw>fd>p(9Ooj96~Sa*MUL{BQ1(6G(k~MQo=N{ z0Pe+%#qCJ=Rs33*lCpo~GG=E!;*`PZvF_e!$<`lG5X`za*M12x5{GygCRm`y`Z2b` ztYZ3`J1oqHIDsgfaBb{^Z(tRk1iu-uT?QYljdYiADh+o8p7b(^+MJ>3Vaz*E9#nG~ z4}%Y8cGNH^xFqVvthBY$s~~wDepYg>*0@9aa`Z12XqluRzPZ1r!iiT2Dtg zyoU@qAOW65k`x8yrZ^!ttdOK9nepwaJJgwUe5MHRCuZjQOYhr6r)XW^@vE_~ z30&O&Jh@OQ^zUVge_hp^f>Yn!f><=oZb_xz9T}}|u058T^gU>@-W4XtbzrDE0w-sY zdK&&wT`zKPu@v9~PG!_4V7r2DHdIHWN{N}VVUj_$Up?V&lIuZMY3IoXK6thkAxJCe z@FdpID&b^_N==tQq2uA?#_p=gLpR2vrd!ImV{jf6o6pJ?9oy_M550#&XN0{V5>@92$%3^CX7YrCGS!%ssFR1%d%%4LTC`4(JELc4Ri;C2&M=yfA7T{x9u=;=xZQcbw z^pk{LwjvMkaocxqzksuU#Gc`lNmPm*B;V2O@OIcs@n%SKQ%AoJK5G1zCjZO8=6Sxe z`==$)hjjpvfk~(&JryT04U(#cL_1Tvmh9`EKup`tGn)5M2k^gyW=VHb8pt;6Br> zGkaQ&h#JFHKdABCTiy8V$a<3FT)_b^b&Ed1$GlnxN6Y5raTr*&Hdig=A3rN7x92Wf z!oCR8O{pl%;HkQFUydFRjJ;gG%dc7@s31Qauk%@n=Z_rKj4O;Fc35UTewBnOY zJ4w_#K;v;8CWkP3+p2x+snL1T(v+2#XRTf`pfvOhDw)t}ED6);w6jy`1AFx_MJ8Df zQ&M0i>#XOhsAQO@!Ov4!m#kWv;ZjeDMD2;MP`E~_05866o6-Othh@G{97;mYQZipG zy`e3?cfz?*${-?#&_2Fkr1G=au*P5EA`f9m#_&BTz3nvgYKf&fj$YE5Nj2o_) zUlw>y$vw{Rn8nR`p^I*5ZL!czm8nuAZNf|@ zFASeoPf0KO|8A%vhZS*n9uiQ`MmV+05Rj&(Uov%z*nH8zqxA4_gNTJ1@MK6sh1;xO z@=6wsctKt`?jnKc=#dBxU;=1lq;a|X9fZwK%N3qvMk$IUwF-L)pBN4n-BdqNwhWX8}Iw;xxzB06*POm{1d%0B}!S({I_>SX|i0BN*pcV*xjY3?+rLPQdlJ zfMORtDfLgyYzJwp*AQYI3P0u30CR?YcCjv!xn)90wiUO*vJgW%r z;b1<^jhkW#Yw?4+*Pm(~{ZxZk^i4XQ`etY(d=MU)sL#W%m(G{g#6e9JFFCm6TbC&Svn5hGi-amj7B3xqnG%o?k(KrOeBhDD2 z-jStz`;Dr+WS}n-5K4|>`3^S^vf87`I#a`n$jG|%vx@{Y(!I*w=MQN>%I*X3@p8_* zH2Bzs2v(qs^b-M}oUEj7K^1U1<89>=@`|P}GOhD~DDv?9J#(qM23#*8d7L=`M|A^xh_mMs3HSoUvoPpVt!?}T6U^L3NYt(_p% z)*j(JF;h9k@Swm)MUd+*!`sbvv|Kr$-nk7zFkY*J4;DSoy+rHYaOtBMZ*m@I)oK}s zue($2?JMSn5Tp@6j{f5^m#PxNPsyGq1A>UdAa6t{X4m?$4tOs<%l7N#D9WbO$HC+^ znhvKBs?^_FwV-;A!{^BHdTgM~s~`H;>Q*kOM3H|m`; zsinHvjZta~MGdozfCy@)P4^hCb+w7F&X!S^p(m7)-F9Xj#KIj`(52H?xGP#nQ(m%c zxe9d|e9-@iU$#L-=&;>!TmBxGx13Rsw=Z)u{3!v>ffQo_meZ6>;6uHTq_DMy4~dp9 zn|%P@p$|7B0h2p5AG)OCV5*!uCfGm+J&_~Zdo$QuA{eC*Di1AK7#OB8LHH&iiVg#Q&r)m0mOZW7*l(G19y2UJ{kwQLz zOl+a%>|vBNvv#I)uoG;^Hf#x?MQ(V*&pnR92=plFBKiqi!4aHXr+Uf0nNGgc4fG7# zH^JM3Z|`WMYewhWV|31)o$4}5#G=5@Tn8wv8sLG8!QL12(M_Zzu=n;hJC-7; zuL4#6u^C*SRmt2SkYv~~$>9#YCj8i~7*8wL@@9A7-Mh9{7NdKYq43Da{8aR``jW8N2pR z{emouy?C-K}9?ZoxyFeCo?wP)al?(m^o8(2WBL za+r*nFRx|~#+St>`?cWa48(wdcXBN=DR=8>Bb1g&3}gVMQ??lEWGNVs?<-Cle;*LV z?*^3lDP%7x8+1Qf*U`a;CuVN#5NC4Ki92SDxPJnC&GZ8aman2V0S!R(S40D%XSmGA z65K(m8YGq)c;TxS`OJ%^nYZnVu#A;s8psP%@6pX~fxlA4gwZWaeahqc6mvYHEKlw5 z#$rAI^bLbEGiAjTuRt0zI-JUdXO}i#W%uS}a|nPMDWBL*$x&g^|5x89amW=j}9r>`YeXy&GwYS}TP%*C1v@ z2H2v&^Xj477riiR0D444Dh(^iO{&S3-D=G10qGM%W&+#=l!Gi|Mx`;Fv#kbV2BF>k zxIPz{DemvUn!PdC20@0IcgV5~Q}8^y3yAy}$-Zpp#(C0;0b!3ctUN;@)AZw#lWJxx%3&7VIx(u#@J1L(?r*Rrw?5r1}nWFC%| zN*VGT=t8qB#l^&#M&o{L_Pfss@$RMtqEy><5nj}(fd}R&+qFp#`Xm^;KMpG%He$^N z45RVz(2W7uhXl5z8^8cZK)Ao_e7I5knyI%vAoN6-DR-ILj;CnP_Mo#GQJC1ZI1<-6VA@ z;B!ng&)FZ#of&BE6C96h^Rfr#VLq;9LfYOnz{eW9wWUVbMT-mTS-Il`S(aB)Z~KK3 z!h23rQVO~b(;2vQ7u#&Uyd{Bd354dsbD)PAG;z(}L8!IkPjft(gf>%lF)9upE9G|1 zu*H4uG(F7nm(>p_Z;U2tFk^8i$Ix9nFu@0CuhE{^NK)bbNvPiCue;m^MrgQa5V4eg zz0XZ7lG`9050H@tN@R%~U_x4k;5)Y$PWy(OpgVZ2(^TQWoHa+j(8Y-Zk{sRHu~HT5 zH*je}5XEiLLDh9c>P_i)<%nhO6TX8Xg$Vq|j9A02SAbcCPy!D#+^|Gu!dTT6O3;jL zwJ&4e1Zs#qywBM~U{-b|Pi0Y0r`075WDx3l@DB1t-4&G8$`$YZq{p#Ggp=g7`bI9C zo{a#+d;C=h>sNEH0MV*RfKp)$s3&rDtqT%1?Af>ttfn!4M?&n_@M+rfs1WY=E1rEj zJ+&}TDUdX-R$(w?01N~Hg3e`)w6TLYK@qJkX64l>aRH&5AX?NkvGMNPqrqBT3jA>&UarD`4{oD6_AMocrfNG5T4Q7zaJf2m&46V} z_0K;)4xS<(6=L>(xIu34;Qn0P(4`k#b)GV-A}24~t7HG?R9ly4=)gZcJl{zdu_0O0 z2g^-AZi!Otu6vQ7$$VseMr!88&V(5N6d2euIE8ME*bPDb@nn8bR_YS*z+ zei+hglBe^K8CM$pUs|sC;k_eLUJsCSXN*fk$4tST2^FAL2uFw8lgd%c0t}<#Fi4M! z)dWJ!9~n`!Kxl=T>H}3P(krVd&7TtMQxcqkRF>pS#PsMKFia$-ktF9Bb7YjS)S^ z*-wL;l#X`217S1})nyf(_e?b)g)(Wm+v`WU+Zx@-4M~!3(SkJsqeeFjOLuh#cM5>` z`(Q%K=i`svg$UPIsA;iqvJ=K2BC0r$Sj1S-;eGpYdk0El|GDe34^Uo>C%xDwka?|O zC;WHV6LYcn9PJeYr|4@mxVdD~aO&?gR9~~tuaDh%#@~X47ca*fVsYFOnm$SNd4IY{ zI2{`B@y=?cxeiK1Q0ODs$i-8r8e}=BT=8P^GOd(f&L66d-1@kUr^y$7HpOrm(fr^jq){vdd?e(8JVX9!^vS8ho14766otv3Bk zUPoJ8!A@K$qUpX{F){#`UFiJ-n{X-+p1tpV6u?DBm^FCwR#wURwaE#87mxHV6CB`Z zi4Vi_7x2+rR-k;S!UYsX?YH`8$hX?5+$8CcRcm0Y<3dNKr62t+sOkY9aDnw1x`(tn z!*wPF3&s%pR2gFkPuGqG_3$)>UkpBQW74ih;mBzQMfdM^3EhLb08}PY8&4*i3H#?K z3foki+4}!?nk|gvj1?cU^JQ0D_M7mR$l>T1qXHzd=|7y!k)XceP8S6Zh24mbM5pw! zQNOP#)ppqNyGB z?O}gHs&)&>fRjz={=l*GK1r>mk8x2>>Y-@Z4k?-jp~dv{H7;xt=DTYF&U7w=49s*) zIzFSqgUkFam2`WbKew?Xx$+~cmCaEXmG2CbwQyYAL>#kpMoAs5zj;MEU2gb{kmN|k z2vQ)&S0ehAIrSrNwJTbD3ExDw8vx3caJa)#W=x$qnT&ZPO*o4f)$55xR-GwtH^bogen+>o2CeO@-qxV{n+^Bo{MPAvhu6*L)Ft!)M8B#B9 zBMP0~lX-!=&ji7PYGbw>8?U)7QP;kDA!?Sto~h1FLqo%;^c2{`^tjpfWI({nKI5z% zVOmB1(+{e6xJIdbrkR&r{Hl15Wok{d+K>6G0RPqv=#7_*CMR5f!Z*v{gZa5g7volk zvWA&zwTiz|Wf${dR^jcIR{JEeG7~>A|QRt5p|LjwicQYBRF!@No``7 zC}SdrQ)@mHb}614S{OXgO&uz3X^{JT*bkbv8OM=~)3kYb%54&of~CwWvS5~bo03hg803k$Bc4%sU~0vtF| z&dm}J{cTjx-V*9O+6zs8RJFxvu7m~`siAO)FdrKEUVPYyB*w<#~GDm1AIh!s@m#t`Ex6(W=W;#bG7K6bv z);r7X&9{P_TkF)6RRWh+t~C0$7DR`Z5-GGtHynE#qQ z0({_Gng>kETs=dlejxl0OI*|l#Vw*~MN?_QHV4_RtU!=8uMn_$<*VPcJ5TId^A<8n z&G;H(B_p+MmBl4^X*wLU0~6Y>yIZcc4S-ATMw?4@;hxpe2V-{?qO0#^`a(F8_Uhjj zLT5Jsz%|Gh1$Wadr;2yz^mBt?Za{&N#}JMs5XvzK5B7WcF<=vOUh2_d(sl-yS8sha zYjm}~!hI6Jos3*Mk!dooI$ z`;;NX?bHb~E^NoR0IAvAjLeV5Avkd%Ze9NsZUt}fmtu&@XC`Fgg$xm-wt#-CV-i{< zVnUE67Ff7(UfFynw}9r16>Ls+A31DlL8zg}Yl|2ClxBdnQSWASBmQEZzkFK|1TbcD z#mgLZ*0N-osY&NGEt-EG@f5SPk&S536p3`T4fli%oE+t%qukI-yF@(8>@`3EhN^-aUR8Dd ze#Cwxz4A5O#vyfZp3uZ7Ir7eKzci3%yNG7>XmGHE2O*7`nRLGKjK@XcrxecL+wBlko$ z&W)%E{aZ_sM@yZuu~Hdx`GL`}-WI8`Y}|FR=asz+<-?A8zu1#PI-p^w=Ft+CNHj$b zZg)AWzdtm2RMe$u%hceSw}s~3pq*GRzLlqpKK4K0724jXuJJuyioyPb2wIo)1`!MD zT=d12-uH)-8!;{%TzfPo6a8~3FjUu95mzEE#c*4MeIfZXN}H>eKS*%JZzsFG1@g5g z35E^YaBL|pw-(=IpGMKx&j!twjhY>6r#Ht-wUZ)dQ=wMp8=XzR>P>C)jKbkSv`bBF z+B7arZ6zCb%1!WfKajnLW zn=;MIPQlff9mi}&?;!U!?X#(C>h{XiI}M^>dUcOBRRo@BW(>{hws5GCUor(GO4^H; zQ!)5#u1M=>wG6sIvHSKd2O1+dVsla>!`E%x5nu@ox>%EGVL6sUUpayOtOj6<`Q(XL&Lock6)o z#VMhA9Io5F`;a z4_Z7ByTf({Q^*D?DWnVC(`xPvv!HYzZ$MmJOPw;`&RPdL@)(H&S|fuY*aD(&o=~f{ zbUGs8E6e#4FiXcvMy+)tfpp%n^bdEc+TYj{B3FNPz6>+cS9rlS+xPFTn(_ub{R9Vfz8XG zwP{AKs;n>5)Ad{4RfAowMXIluK}SB>gs5}R0T!M46{KtF=sraTwl``3nB^-8j2mnw zq%2BH!rmCHI`ThINhaVjnP)I&+$EyaMHH23i(o&r|BLyKh1Y!L3m ziLk9G@G(4LHlyPGK5$~h8c6C8IWS0pF*8nXSqUD!PHW~V4vb_?LYf^XRLnJ&xQPfx z3KX^Q>P7LJ08plG02HGP6Ybs}Z>?ANnkH^xWmB`!2q^1EsEfx%0p0iun?!3^!SW#S z*u)y6(*uO+Cb@+(pSVOZJ0r}^cBobjj_D&E6|bm_w}C$Z>iVjv`^cJgRCYp%`w**h zeCGGvEo+QYcr}cY)tup*R8yu8=Qf6Aj4aZw)}EzY)5CxkPeSgp?F&&(wkY=%GKOh3 z6Gitu+wo+4i$z1^ZwXW9gvurwrv4#lb`V!RON(Lnn-j$XXcG|ndCnP~xu7Wk3 zbJDgSDaAoY<&1;t!BPPDaApk7B&hrG+6G|JAL#(5P_{>sz=!4$uF8-Xb6mL;DZ}dVL_c%rhG~ zURMic!q?aG$M!I^kh=GZzZL?v?aRgnR%5Nr;-hI8Rc#N$=1&uTG>eC=GxuHqDd_dH z(0^F5r)gehxgogi$SBWty5ApOp*C@4E?|B;zY8g_%f(%v{UF+=?rWiJjZH4;`{2lRYy-C3A`$6LPN5 zR)iSzYIG=Vl?+gR-rtj9zSTiHiAq4dOdoUwY3T(o{<)5;)^@@omZDxypnAy~m6g90 z7I}@~`Z>p^qp?>Epnl)j>Mj?Z)ytmwaI;!n%TU!bZ{KL-@b^e=cITNXujI$$3OeG9 zJKr7Z%GmN{-fM}j=E*4g3l%TG1UiDrWgzGy+;F;;BWz<%Qm|`ggwuL>e%sEzy@GZ4 zGwh38#mtn@hZe!*KH!ir`T)7fh;fmHniIcXjHb%!?> z=fdO;WsGM0B|hqlQWSY063M3w)_4~hL>!iHEcuPNNBkl@Cm2W56^qa124#Z}uoE2& znD+8x0YCOPBxA8@rl?{Uauxj?2}k3`@OC5o)$BNqNNmyMr6`P$PJK8+elRuHr}Cbm zogJT_nw725v$hkXfshzHGI-t*t1KUPZ%T%jy@PP$fKKobvNRgtG+Y_P8gY08=C*nx z#Y$7GwF<@ZD`}pqb7={vz>DglUT^^)oyQ{%LxYax%K*!wK7>A&Hm-;=tT~tehX%c) zz@JI1KGlpmZ_ait?qCmK?7HjQ%*8@;gAZLfToVkcnhfJ?T3dLUPs#q}=F6AKZtXFI z-rfyPpUQ6T4?j$8srl=ie}-T_3!ss!8t?F-c=KWH#>?0_hU~ZiYfsjQ^qj;I@vH$G zuVYy)Tpi`A4tNyAHL{7u`fLtiJG|$b2~`7qF*t{p3)`B^V7g{-gJWHoy6$d?Bg>Um zv~`Anf74w^B!n9sRmelh>_PjlQkzQigtISQvtqRb8@$yYK{-q4!ls25wfIo8%(0pY zYnew?kTRDXI;Uo?Y&yuJ*J{mRK-Ml|u1*?Y8tcMLCJ1ZIpnFb}Bo+5~Y4*bq*hJwU z3S4saVJ{v3({A__z`RhuEYZNr3vTFl_e`-v818Q&vNb5uhgW5|G zuE$(cddKGt(Zbf&mr4udH&zL|6vw2vAJ{;q(#Cg@hBJC!u#>`1Wyp5wnwi&(21bBG z)=zrN_EcgMyOSw}O$e|Mc9?yfq@mfEk?9_mF47>|eK6W{POr0WPckMYPyhWr_=>SQ zS&x_!#>`IFW1we>Yb@~FygJKQx?B!8k+l}4o$V(|BAnjZgwG@#>2V&zm&0bUXC3tDl9+2hb-&OD6XZ?6>w>`_jNH590Giar5?|{8)aEE(RT#&HSYsUXKCB<5ibd7~b(V@Kg+L~SOWi+I6sW4v z32fd$2IzrKZZ*_028UF<>no-FZOTPxV8+Ga8i27jGNt&XI#dAzcL)@F-S~Ytr8X!P zVclos&mDEbp2VHS_I+;fJd_KQxF=NSysuXKODi>)_ymG|j@|)A^yf zim{zYrSQ)^;s^RL#=vIfNlGeQ2suG-1TkPs+pY1FZ}P?mhh7X-9K<99;k+8J_n(Wf zk2S;aatk8)$33jmm-bb4|DQSiB@fk6I@-Id<%&a8D0vVzShE2>d}j;3TveK{Qf-f# zS{6a6JBiwt;9yOAby^Q){m8i2q{kOdHhv`5O0S{u5+0xnPOIg|-550nQPU&=yNWK} z3w^gT7XFJ@`WHH*I}HqIRk78UaU(F}1ZvD3)TDY@YCtoq(S1L8tVP4$Z|PrFO1RuK zC9tSe#a3OBv{wgwNP;t+XLr2#R{<5@EchtBvHb0O8Z>y)wEJ0Y2(VR&xXh_iIMIVB zS6Wn|3;Gt`vHclmeNQw-zbEOtg8|+G+AfJ|*pR!g(*uMLGrTJxY&!WwVBpOZZpzJ$8b&~8_0@qO{Ne*XP7_t5nl;gZw#hz`&8*Oe4_ zaXDnuzY^?%OQaNZCqDli+QAJNC&)h?w(?UEghFwdnz2wro_s#gw%%wL!f-pU$3LYYsJ#0UF&-1}c##ThKZ|4o~p-MD> z9j1O!XZn7l;Y$^}1$<~nu(0LMC81d_jPH6-Q5Dw{o0p}$feuy^WLrSWd%9|Gm z3ERk*^;gz_S9W@kE*Q_cLrF*T40%BWh~lDH%e05 zP9BIvfh=AN1Re^$;zpVJy?56qNX^)Ie^4k4%H;Y>NkODCZYwtkyL>gIc^UR?^f0`} zpkr(1=XGQG(iL;%EDZmnX2Rhio_a=Z74vp@#WqL|^!R~8bVZaF<;2z>f-XJ5UGr0W z%aj4$XOsBwES$rdaq}imX~znAJXWA11Fi<~IW8y*CWnA5yTc?bpBYZi!IXyUDZb|y zaMMtE7vp#Z1dPyyv@0J0^g(fp8!}+Wtb?T=F0d!2nQRbLToV-Jpj&?u`?o8d!?$z# zu_W_%ReEtKmptv4pgvr$&M7kOVYatJbwU_?xbeCU3G+dinZ{tNVERm^09#f-?J+b4cC89OOY#=jiHm~&z4K#@0uHbs+pvbs7p(Hhgs-6%QdXM@cAw7Winj$Yc7U+TDF^AXHhe@#e-hXnX1GGPV~hQVYG?oYwQC<|6=5WKE`G z2g!08nCr~b;q@@Z4@?)r0@D@|3vS+n2j*)_n8W5h`DH{ zOud_UClipPpRTMD8D@o#1T{DUKjGREVCsXaC=+NoF;@JXKQw7`VcaR6-kJ!$vBh9X zQJ=N%ADvi-$~K%IA_|e1BhYtToSHd=@A(>}uHjnkQj|4_a^O~=T&cXEIo>^2ijEZ*P)~UA58>d;5-J(9Rk58Wm}J^_^df)B=_` zuizKDZC){(+^)5`4x|{;cY6A)XJO(74u@n(*?akcRgH=6V%KfK2kx92gax*@Bd3aX zmH*}R?>J2|TFCmrU&ECQ{=%!Rx-r$&91)fgn*jX&2iccSE)LRr)$^V>K=%k7FfS5&h^7~c<<#bB~-11o3>YP zERd_ETD#qntXgxhLT}H5;1o*EB9*U;_G_U}3Ir2UiC{?eVn8WgYFB;ZNedaqylNU{uu)vY`!j|o^JhdC%&s;H@uq**HtI!VWVOO^OC=Q=UF>O}~ zg{F4U1%ij9AlqJJ<1H9E=aJ@@vCrpdbpzO}^iRi9oJoz-wXZ;+zel6;LlAhG(7|tV zE%~!OwLbXYb&3>~?sB_H=kYTpvxpwyN0DFh^0KwCD}8R6<>ET;iq#-?BRPMT%yJ{g zx+V)Y3mu>^TCUzP0mEeq#7EM4V`p;EqYz(?4-%|rMNCajHl%# z{$;wxmI}nGCKa0n2n%>Xm#B5;({Bi{8Iaa~ALb+CXF4`l#?wmDP4GEHTUN_6M3~u` z_e&PnNr{=j=UFWr%~#H>cePmD(@SU7#JOM-YDsOuw#h{x>;|#C4O&^w)4O4fcwJOo zAp|6WL(*iEkJFn6ekIEX*Ew*5f^@Vdg9ikAO(2`{!4mR%#AFB)Da_Am;}s){{%ynr z2j`QCp_C28=8qcuG!_K#_$YyOiv{D#AuMPUil%MLig_4R)w8&0&tLW+;J(Hi?h0uI zNj>%%y;|v=To5-IK>pv_9S*jU=;#Xyt6?|tR3?poJ$--%d9h@S#44W88aIT|nVjo5 z4_C&ZJ{yNJfgFJk__D0|jd&P3nW|Zn&&Zky@TK}ZjXHLy#ErBKoQ6NNKntuVwT7aF zF99a6`nIG(kP)6U>Bd-Ct^<1du;4o0#qT$2iQfsIEt7rbca2)ZMN#bs@FJeiHG1Ie z2fs)f2c_Hz4S|v0nMYPe{mh0hExzxv$ER(xl=@bWR!`u}O~e)FM6_lm_=i~OulP?| zbZ;R-y1){o#-9TM>kfUAfCTU$fc8mYo{sZ9IDr^SbE$Z!(%Rcb)*nY)$P}EK`8ZAN zQbe^2qdK1fyTvgFb^V7uz ze=-&?n5H(=i1n3gPDD6P*f;Y zj+4$5cxTx}%$yea(zI+xZ13i5h zk7iLsl;>*xY4N1VwTgrE+eu}v{5X$Q?#;wa;Fa+&d#~YZ_SElZo@ImHBFJ9pI@EeT z6MXFAZcZny8H?Qno6Dht7$W0OCwoHx#4jZK!K3ocI01?>ffFCUV>&U)d#iaNs^$D0 z1s^8N0cqA(IpW2z1PqK8bhIZ3knSZjQBah0o3TMH)^U ziW$%pC)*z3mk25rmuM*xg+kEy*Yo+%o?zUk%#=dGnRbRdLx$ zJoy;@EnEa8c)(XRygQ9hIvQpr+GndNMl!4gBYi5Y3u8a;fo{^(r@_=Oh-QSg1M?N? zUj4+z%%(vaGHGd`VgzoFwqGUDVRJN!baHzL(Tx>Y-wq^ysfF`5anrvJ)HL<>7jUSa zPt!1FB$xTVk(-B?u}t_O{2SrbpTUKNs~v+8re+2=hN_OEZ}5R{w7I8oi&DIB4~Yj0 zHpG>JFf-{h&`0-yian^*%V7uFyYw@Gl`kn&j@!&QK*H-_;ZZF)B_siZ7o zYp&{$3*+@x%U#?c*%VP4b!>AWvLUPIVEr-$nhSgcS+I@M9YeXMKo5g|Yy!#uw{H1; zG)AgUrG1U--ptK&G%4e&WDUmDj%iiQhc;IK9bK8u_z3`Zbx1#op7AD088GD;Bov`+ z*yEaT8weE>eEhI`MYWU6cQ2UfPr`9uNx%xLW{Fc7Js zoKni_ZUm(bbP|;i#->0yaccAdMDf}h{Rmo#b0q_4*D}5g5@1E$QE{n=$%r*_GHp?$8btl3U>C${ibI%b8rK zP1r%~gN8``2^_m$pbg&T932Z2l+=A-`7ta{pSp|8SN{2|;@W#P;!&N?y6PnRzS5)3 z4w`g|XxrEn|5^(U#ZMm^A@S-DbFN>}{7F3V_bmHqbCwmlB>S3>S|}r~$aQr?b>mZs z&c^!aU12>PkI+0I_;<4cvSvyumuu3F1aUJA)w2YH8h&?DVQSysz5UyZZ_h zNKvJ7Mm6ghB?>HBIz34q+mK9yFjF4#{fVG7Y&7c<6ktXuKZIS(eEj&{hYT!zn{QH_ zsUK}VmgV$!eWnTBn^U9HvieqlC8eCy?W7#coWie8*rjZ`m-bXF8E>E#^mX~Hnfmld zmymJqCaIG<1F&jLX~DUBgn9c606@VtL}Sk&&k@$!=0Gpb3_l0YX26qcNPlsiGYT2R zE%p`HXbwY>X&I`P`GP1+#^=u3*Ro3WrCZ1XJym=SzXC+c7r985FRHd=e;3xnb_0rM z5SK%Wb^LnwLjN8l32RwF1tyNG6p|g8B4!YJ4=!@XFEUePMBOuS8AgiyzbsrZv+Tq% z(N8FeZbm^}m3@q!$t;HyUY*<)AZ$VH4KWB`>)4=fh6Vec^mh14$=0I#dXJMg<@Wwp z*P#W*Yd8jXbQ-4Tq;~m4JD72vjBaN|)u0VAi4(DED#dh2II{1@ltb7?aAi2Ut;7^} z!l&;VmjUNv!9NKY`Y7n*`OKw{B#My*UeI~v4_K1E>awC&^1}*N14KVGIUCk8rV@N8 z;IIhp^Xnl%Wg(VOeWEJ>U5&8H{Xznd$P&J;aH#XGc+#+gMBJKk@Oz)&)_1p52gASo zKX}+bBCvG`mKLvQN1v&=-8P1}#wo{j1R5(9_v*V-c(iJ_KycRF;x&tQF*S7Ud^~L+ z;>dQ1dN|@ut)TCzTL8f_X%K; z^<46o#hE0^43ETKQu~=XF_rc?d<6lrGVT<~Vt;Cn|DpzwqwNX@4la6Cn`zfveil6B z4R0_CBGpVU%1=SRokhl6hec;RF*G?77v!=|omkG47O_%=Mb{plT;A+TL^6G#Q6QO+ z`&B7zoKM+{&c2daZ7{z^sAzX7wmJ&aI;a_(sJ>!rjaA`uO^PL&z*1LFfC8g*zRAY= zlhe8ehwWt@=JpAqAy3!j^0-pFe0P1>>6r7p60Zcb&c#NHe7FMfdXQ)$?Yp3P1Lk zI_4Y5K7P^&)q7oWSpT_>!43)3@9log#`+kHUmh>u!`;;d(6t$csGx2(h9yov5e#Ia zhUV_|0Y~+#Fhu$0x{J*xXgu2FhcT1y<*9w=S=C=!AJoGoV$sOF!cIp`Uu$swX(`Ik ze4O%dKl33Pd`N^t7AOh|v{HLbSQa#DPeWy}pi;ASoDNAoJ$V z5z)u)Q*)mAkg(R)S@-6ggJlI&|G{z9?qcX8724GrCo}Y&89Z#*I{_kG{Mg7CciAZO z-W4*VHVplPt-eBq=rGU;%r;B*er)+-5UC|8S=@i#uMx_M_XT^FG-a87XmQW1pY5eh z02%SA?ZBYwYjy{Gw3Qe!Lv*=swVRBPcgl#LYt1`@vorizj2=7<%B~vW#AMrF$2+)t ziRkE&NPU^TI)Yb9`zIMPP|iyQl#3tvYedz~rE)Jdzk2mWVF(#E$*0L-!r!N&ztttw zV880eioI5OpjM%#?J<@G^os-NIQ;>PX2~jLa=ZQb{O&zwJfzMK!s2%l<0FG_*T_~&FWqX@A0$R0bqXmN)9;e_viSig?~E1SAEjVn)m zv*kb>raq-ffa<8;J^RQs{|nA9taeo!sGS7Hcb7c%Q0Z?nqy-ZQ7o*=`n!&_?tI#Jj zlw2W%Akd~+X#&Afdh|yl$M-c39(}bEGce|1Rz~nY6BU=*Z6J}fZ%EtQdkTEE2dqz& zesp@9qzRQb5qzn6`KxD@R>9m)MkD-m8Xn`EwrhinOgu*`6>0boyW7TTx;fM|3>2KS$)w%>VA&RZ|xrN5UdvWdHJlQC*H7zifVmq%Gzz<%B zwY+ItAap`|%>HU~XF4e^cVZ7Y4e6YHLYBf$xea-KCKk{+)#yTsKkC9ofnn2Or`Y*v zw*-kppE@VO#~8E?|0>%RmY|3CDo+R&WRk{GYzxQPpf3sE7&D}sOml94%e6B2CRo)G z$vbG!Y+>IjDUkKDGMgO(Ax@6j1~tZ2I%ZXSPSC~~-S{FEL|gaWaJ5ct3%ZESXr z!xqwfFm?$y1IoZ(J3Bx8Y37+Cp$hovR*(25;cjIr7{L)DVEU1*&JFmvA~}#Kr?K;OT^tK6}<903pG;qAaX9 z^wjML`aE|<6|U#H{Yb}B!EB1-oOW3-@yaXy;1b?w2?0qqa!kSQ-sQT-Uj3Lvt6jVF zXD3}=b~|JXE*39bw&=4Jd;QGFy(w9yan`|#$E1RusXUra&O{b?{p?IQ=^*E{AdU;# zf$#@82SSW0X(o~rbnR7$%~H@>k)O1qEJSxpBGJ8OG3Xv=zFSlh+F@4i1z~Gw6a6F; zVJ&;0LJq>r=B~$*gBN23ATaPn>}?}c)*0I%t%9TLq`@YoZDF;nk>i~arX1EPpm*vj zxwHuHlT=YjFWIkh`I+Y|-_d zWy^DcDhW<03gH5X1ck!dt|(#BLGf}L^_V-w-3fTCTmoGrFR~-@M3NE51A zyjN3-mlcBrV1YhS`J>e>e3FRR2&3wS!8a2_)c_&ADSm|>q`yOF+NVwCIn)Sq?F1j< z3|p>X_+^mWxu~Quk?IXbnM>eYW-u(NPIbIUmP?qpXs1$Y-3l~GRwd$nVknO#PS>q} zy=8a+Z=JCU(mv9Z^fiA*sP2eUP!ZW!isiVj0Gf&tDR9`8co-4AK|Z<;YvYl@ub-P6 zdZX2ASapzI+RqngU2+?Rkg|{u(!>7%K1}cMlV#;VQf<|{tpI@H&@5J*?yPD>8ZSHw zg_9!jUc`ycW^%T`~2(vqV1+35&mv&Csnc z>W4TSb%~?W7_04*wHy{vgfQ{yk1!!^kN#g3KKNoJ9l7IyN7a0PgVkdC#KhfMVA3R2 z|6qevr-3M7RuQ1AZW<$-rp)Q*c&Zi1??5e9^n~v92o{Jh8kbI^M(3Mt6%^;+c>p$A zIK|5p_^2`XqN{5iE3!OS&V~(@QJ_!egQ3-=vumU0x3P#kr7# zNzBdh9cE$QmXvnzw}%aw!VyNqrdve>3zk@#AA@b!Wh9Q%8N9vghH zzhZrN(VY@wbp{xp-~rdwnIG>Jke(Px?`ZcLc!5@@GMu!CX5h78=UgOkL*B@9QIPKa z4rqj?qYxYdF!~~Opi^sUBVAARAnkPRbqtbz=}S0%Y_%Y%TeAqL0q{|K*Zk*GHp$g( z5a$yK(={H7pKAPNfGBgcG2pZ!iBI4alleG`3Wx{P+chK6;}Wes4;jExp8LI0UK)Im zc>6pxUzWI@T!}{Lgsy?N#Y@d}jdXT+{O8&&15-$W)MKN-G|998^RX$rAMC%UEEbof zFXRf7u+_NWIm_CMTYVF%hYun=w@|O1khP{Y`9zHg5oPb`!K1ZzSga8nDv=0hw|lC$ ztdhOyr03$son7|SRVPJd;pJ=7zVmBj2)#Y z>bvEEx_U1RTKk$v65`tkkI1e?{$9h7P!45E#hAJMQnO{3c&s3*q$G#v)C~7XAJN77 zSpt%o|C+LQ=tDiyvV5f_ysgmvHY z@6(8cuYAN3jD@cH1_s;Ic-8%AdcR77>)bGM(6Rejqd=u%dG`@N(+7idx)D}Yppn{e z7;p5X_tIvrt{dK0->mCG2SkyIwfZ?Y`BYo7YpYUDd2X&2u0d&o|!6tVB&OhrTl{9rOg=-1qZPBL$fSNgB$;Z?9ad_2Z?zL^2j8ss7Yey9n>M(eHG3PTEIUL#f(+sB!(i=O1HpYITI zn`IJpckpH=;yX(Ff)9l&xOFpEd>I{_?@X@%m$UqQ4RK~I7T0{n!}vo%B5N-yc~_^c zQw|xF!TGE>{$>}{xGT#CIgRDrmgR0HmH6q}V{s0{i*_!yGf+0&gO8rmgCFg1^E7z^ zQwz&Q!=i!r8v=5?4FyoKhX$enqhp%<52TPp_%o(vSi&SKY1D zISBpf=+$u%bCcLgrpeq((*#Zk<*!_f?=0HdQFTHdi^cg`^03Iundv{{bB>Wiy!(r5 z@@wnGf(TYWQzi7$Jpy#FSh-!a{St+VxDX9UzQK;nTmahqVoXAQZUV*T`W5E61+ zQAc6P`VSMKuz?o-dY#>%_ww5h>Qr2FIg!{;;p2){u}h{+DMV1hockLOK) z&S7C*Ei9La9uXBp%wFN88Xc^Tz>1nJAvwj3EWN;4!}71y`xM?31}UTbBk)0Hl8Ad1 zdAV@xUnQ7z>HZ2<6V#Smw(xGmW03z*ur(4eLy>1nNY};3sbsrUqU2p_WfQVc{_Zr& zd|9}wUB@`xdD@4T5vUQcHGVI@^_3$dd=uF&HobJlD7P!zwh)gJIMmF-&F9{2ZidBP zM}Vrp!?3ssuOn$|x%R8GhLjHam^cuameBMf^2m^^>Cz6~9+ofWVs4O3i2d1T+h zta`EN*k%#4Mh*=I@tz|E}_vOrx!f`&?3puX9M?31Y zo_V>PP>_2~&rWAyM1#88zK1!HPuNtDbl)MmJGo_Hj(ZPB5?Um0$2MN_zgOI%FIZHJ zfwOg*bCY)r9?o3u7+PMzoonx)D)b98MTIK*YZ!AkU8cSr_5PowVj^^+PcYkb;GBt{ zJPppHBGz8X)Ute2myE=wephh)n5!YH)>d6j(Y}#Zd1Xm3S&}PvUcd)B7@k_B?$FsL z17sWwk7y|?uSU^+M>-u2Pt@8P>*TFGmZi|fX-PA$)^E9<;5L&@`)B}2K)1gDM^>c^ zAxLMkPw-)`UUm9jYmnCN2z8!G3ccQ5%#(q@YftrNO%xaVdPYS) zhxwK%^?{ZreV2U_hM+s-0#C;kb6yRX=&*d^Oqk|l;gn6KQUe)5zSMRBI-hVUJrhKY zYC5>Q3T+!r@!%`fx3Lq|qSW9;xOz?G9jol!-$)nGyE{?kPe+Zc~ev=(A3 zd|&H1GdfoRhMueoIBbFRKsSE{drpMv9mBK|N-?Jwdq85rejthgNf>o!U433Svq;oV zwUzd-G#~DZ2k=3fZH0`NK8wp~R&1~BUjMV}A1~=1_xket__Rj6@3^MHKa^Nz2_(=* zM}8p(WSIEm!p~kkhjYbM3m;`DDVXYrXy-Ai@u%O+l!vY-_{u^gX;ACHB4Z?um{!?*lc>x5;x>9%N3s7-BthXp4PZnq)!r@nQ+L;?_u#< z7)a%-1P7`MB5(1uXp+Y1=df-Ya&RqnbOR>oabc0n<5_98URZqkGlxZB>0J1ZxZhYi z<7e#ekwVY`c7_f!L)4m~WA1@;9CZJZtVtM6TWwh$fIf;0@NUSNLl}bLXfCYJFhf?1 z%&=!JLjHbLxChkLTjiyYX`E8c&^U{6`bM7KRe7akPXr~xF@NMH)}XO;-9h`JvFY z9d|@ji1rhuHP{6@xBP_ zM%l$i7*ge_ zQ(N?WBr3!g0v`(8;6l38G>Cm1j5|{8#Csv)f?BJFF8HDM%3;5_ zOz`|zhV*C*955Bd-vwul%;St%<4eGCVSdK_fX&h2q6*{^IS$^kmA#G&k)hC@ki9`; zO+V*EvDf2NFU5Fx^QL(cHf!Hjj;7HNL$rniq-QYGqn++5ObKx$a*wS+t-u9vtBS?v z^iCS*lI@L24^(4;t6uSl`UxM@ahkmzQf%*dx91_#qjI8N8-?iAQelV_7-k#l!7hY1 zlWz?tjL_Z}{1SqRmK}Ij&H5Ba%GYY7oMrKkI!56m9Tf0!U79xOtu$&`)Y;z-a7_`r z#R`$t`p|Rku5gVzo{+=`j(DWiSB=%-PSag<)F7%m)g@SGDoWa&dqS(ig--33uC(Zn zCraF~cfKekOA(ZbR3Dp}3WA+)ttaEYhCys8OC1f+LJCfz>|u4wm-l!tU>A^8=wguA zg(xMFhe@?H#Ch}Hb+Uw=QqAEL)hI%x2a4FmV!h)lAWnVcM?8-r_baQQ2}Y%|wNl#b z;ulYseh}YmSpJ%ar=&|}+D6#r7|>_m+{ z=S>n(X}cdiYnF*F{`|61cFV8135Vt8wROfQk1M$2HKrI<%WMNQbV|WJ<40J_=(1bQ z06pkAQP1aU-M}DSEr@4b(Ukuw6;x}URvGQ(B1;&{j|#BZYx6Y|VW}RVe<45TCm}X< z0Xx;zz1bW87{rQpIbT5GPUpCPEg{f7tm(KOE9f=Tvi;j_L)OK04Vx~`u%1v!qdYa3 z!AJ2pZ5t_9GQmf0{*Jr4g4g=&`I2c?K47{c0yUk~4>2ti#OBS*&igJ#p9M{r74?Vp z!a4=Na0(}2uPZ653r}@;`5#uW+kpX=+d$;GY$b-*>HchD!#kY*(ibh`aWU6~}o+Fz0pQqJ06v^e(R|zYT)L{YZ#kcB9@K>{zEp$vy^8{6fE#&xc z__svCGd(`wWz^T&-;G_qr;Df)1Z5aXN4*-RJNhv52}7NZ!h~ZUNwb@i-^P* zVz%4hE8?gJS7X-r;28ett8BU{124P;kE)JxbGNlg={o ziy8%uqyQhDj4zGI4tdC_fk{~4<2WW^HC-(?9&_l@7=RKS=(*SW|4gRV`u_eG%4yZ9 zw?&?i>(G9(PV3a*>8F>Ei?!zVlJcdhKs2*_b>M9bkLM@(f`*?)9(rIhUKw7xPehyH zMQ&_DWrEU@GmLl3c~>j2&Hw~V04*Q=Pi(+Sn}NNmwLApo&*s+Pd#b6@4xr>S<( zw;Da3&{2|7h=VoSPJoqDMI2s=E5~w{ORH14!X?{@MJ#y#c^^IN}R{O9|>QZ6h%F&HN($)e!j z)h}2*W^m~=K-92T!-r*jsa(|+sK;(pAMhu>mv2(feX~nqXx;w&9jZ&(X2|(Jit*jyt;hHnapZNzAfqUe#;^0 zWtt0#>vzPdl3`g}UtVafNL}9}Tlz^NUBzM+pJ^)8voW@u?jL|!ybxd?E~Ag_BSSFJ zym^gzKdHw-xDpVbt0b5hEZoizsE~zn(`~9(QfGk=iLuMN-YrEgPt)8Fl%V7<}}d zmM1h$% z?a)V}gZ@y=0|uu^2H#x&Fw(wyyImV$$C@=j&b^ApS{{2DG~0WaGx`)v8g5n6(-*@` znD4SQ$Xr&h{j&|1)Rudpn=_kt3Mlh^fe(y?)Eu)WYB6|h>TH%)+}rLFFuEs%`OpF% zmZx3@Rxt3b`amV_oHq#C$eIZ7A*5d2S~#(>h8`T?<1FxD?d%J_3Ind#^l|k7!-?ON zQ?qS0&aY93sZ5PL28TSc-ksU~jtSLQD1i~+1IBS;mxEgYhJgcoxCUjRUMWQ?Ss_MQLzXdBfdG1%*fgP>iZlj3u{BPlCQ%h4Cw{j{A!}2S1VQ@y>5+Q(w zJ`M1yhn`5Wun`PeL>h4=JiJ5N?1>NY7;DjkHM(@Diso@0E~qXJfslm$)O2FYQuOD` z>G0B6+{CazhRC47*uH|`CtQOlwnZS&OKYWi-EC&AV2Id6zz29;0^xo>x&_v_(7r48 z!|;=&Yg}Fs1nTE@2}2~z8ZS!HfSzi2Hz6|9aKIxB1Nb;6g zrSO8cqf9P6rrL;z@`~EZPyI>TRbtk!hbBPTwlVDXDJR`KX_|M~=PY4|0E!w;7Skc; zuGBfAd3an)S%cM^pS;x#S!=%iU#fpq%+T9?kgKy zIR6Lu5Xh(`;|A{K+gB^+Fo8Rz--A! zA$Bo=9(H?cdXpXQ5;Kj3Ni5f!lCbs^iPW^_&Br`sKPmQbQSEnCo}mxCw+G?cYbEPZ zG>UdJwuX%DI8p%%kt!T~c&BN`zX&@QZRvR$hPIuYzW*b$sJy+M@B?K5=bKBXO>lxue~#2VPB~qiq|Rr&Ixo8S2YkG5LllBNdDN@JFT3+3o0Md1 zno`=6pwF9?uj{7ep|KJ>P5~eMlExB(k1G`D@I4lbv-+yYDg+PoftrHF8)9fyyxulr z>CSjj-J=^Q=6=1?5^wE z4||9DArDT|#P_}d?iol=oR7-u@4>tX0!JpKH+W^b zB>f?^Y+@`jTEWLz*}9=ClL-tH#s=T}>hx}&t+tIwPN@mU)-6p>@z?f`W-HtK4eZQE zvEasV1QI9saOS`e2`WE`PR@s$G>edNkc+bUtO_kT(bQX8#MY35V1ubY%ewRnZDaCZ zyvBUhBO22rpf&gazJEkcB9?mK2rJcpkq0`!M<_J!P8)FzgEM8&8o-UWyIygzhVBaO zLPxU5xh669YI`6}%4E%|Nccb6?To|nhNRpbADzh)v)ZP^*H~N{!Cw?F4tkWFqbdyo z&~Wcf#8Aap!ly{7Xw$woc3wwD+l7`oqGDfUM5MiH3N~*xpddFBk4qGer*=qx3yxZI zHP6%u5R-Zf3Fc^VIQL;CnkKC1czNoA52`yLCjfl3zlGwl>L1e<0~IVyI8%3tnfMU( z4`V$hSSR?9)jX_~)7`BFWhWcrWHoiP>z0SppL%OO-@pg{3`0;`MX^qE8|iBvWxoSh zXLg7E?HzUoAapi#Tpk`eyBtQHP#@^vH7;7YEluF?jLupeOiPOZ%<2_k&JdUr)q89k~t@5|*Ot`dv1o z;3I8e-K_(h!j&l-?aBz1>0V>A+8*_k!-r)ZutAUOFF`DBc803C+{W%wvxTFvw%SHU zP>JMYYwf5PZWcvHP19NAW@4^iad*bo{y+G*R>_vwW>{kY@X?hiNXc?aK1!eJS<@`A zsnxUS^$bP z?W{Jv0H*}(Q63J1CUgTAjQI5Xx+ac(aJw9kqedGKLQBAj)$-dVGVz-~ObuNzSmvgZ zKw_hES!&=@VRICyJB;hMOmFK5m-?wzyYSjKJL~kU*@I1vm|4QF{nWiX3`C1)<-Y(Q z8xx-y3A;Lv)eY+}*o(G`VSB0GLjO;N&sM`kssTDp?%wBnBIH_JBq*h`fVd{;FF@PW zA(Ld%+cuu~YPaGjBG=8L;#Q2ikRfu_z?)mA?mdV2FjBYECrNn8W88A>Xc%wdhv>tV z6GTP-9-NE-Dy+i>Px8&JHmtG^Rb6_{Z4s~s`?=JgD<%Z4xB8bdoSQ!XgbGO{U<&y= zj2$h*eIwCNe?6@!fsxu4Gx3_!W?+(lby}Dzv|D17%6>A|XT+Gyz+^L3i{bvz)Mm*Y zki73_H$&6=@Z@W=0ju(df)55?n?=O8*xH%D$=r0ZbZ(ibCWe2x54D9R%;cOXMK07M z6+M%o<`XW~4tEc^sRkcmtw-_v6R<4*=8gXeK8iS6;cV`k@VkfUK1aUog^j_Nz0oMh zZ!(*g+KPd;rRet0vD73mXU9$xx0b+UES2(%EB>I<%Xst*jWT$KtcQS*WxNXXt8T$@ zjE%xTq_E$L9RxrW4l26tMsc=W^0V}XH7kc8CI^#C}|uLwRmUVO-`1%tEJ(}zn6 zArg5QzcmGkXRM6DUN_CVX=F|=LMMGN@=I<6zQ^Lk(?9iG^V_7WMs@IpwmWrkM0FYO zES4`b`_`=?Bj6}mTxcT?=N2wXH&r`thbXr+J5WjDADjVjmY)NB=r5%TSlv?kh$x#% zVjQ!vTnl*>AJ?AZmCcYmOIL3c15jMc8x28RLlH?|Q87TIT8iGO$`#DPd-UZCK5qTg zWelU#%&axnt}GML-2n(nLI41Xxstn~E@KRLyYMTOO1zHB%%XZT-|j)2mn-N1w-JA- z&Ic-?{9|<%aWTE9J?Xx3uTteF_@IH1sW$j{p6_w5pw4X9MWv@mautX) z5?rghlGELO5}M)1HrLF}*(uFwCwa}S`!!_edr;`D(^sCj;A5-v`raG(_-+{jZ@TSp zKt%@}=c-@oe6?|hIbKY!S#gdMh=sx3Yu3K16VhzlA_!r9VGN8?q=c*b41{7L#Ldgj z7vXKLHn9#9j*jHqA>(jEHi7^G1KJhZt5Xn_gu#Kn!#jRd`UFP4mRQo*0Wd{SMXOE@ zc@e{+sJIlz=zrOwXmt=iM$;821hd(wlUvMlEACrS2xlM^ z1h*ED218o|Nlc+hz)965yEZ$(V(mze!V4$1mAQ2?xx={`@5B3U=~MyKAj{A(C#T3f zlI~nzrH*_OZd&a78wpK!HXOJsloyEpiUWK+MYI6F&@+-VlQlAbGVGtu2u4!DL8vt8x}+{{vuNK2Z`hTOgv@#OVfyQj5v zu1x!?qeb&|EqMt9z_1%c&RtBQ{`YM{6U1%M8LSW&i26KY3JlZF9&09OG%EUdOy(6UHZ7%%vrGtoC)exMJS!gx5M#!-C+jaDK)!N=XJd3q}6 z?I~1MxE&kCrRCO8QD<0@3_BA7PY-PIv|%M5a~N9 ziN#7e=~~EYM}SyY)*0M1X1Q6I26nKh?cgIOVKBT6ufoy9J!&Q1sgO#a&2l1GdMw+x ztc!~M2gaV7AbHI^w)PcYey_QD*D-3LflV{gsZoZ1aq+q*_{gM?;6slAl6Hm2=?JyP zKY30$7zpr;@({SJxM`Y|{_2Fw=Q@`_V%xfn=uyTYdwB5hjE`Ypj7_O_0jXdFKeLwlST#jAR-#nHb4 z5tB7c&BqlaawjO3@IW1c4{83f##$JvgHIy_qx68b;OXpcKbJiW`p4WBtFpS9d(@lh z<9YBW_|TYI^=gJ>%I$LoxVdk_gQ~@Su_3`X;bRFhuY>y|VBBV;EwY!@73wbJd9I1> zK$2-f`4h#oR{3<|-t6G8l-bwkW~e&t&~EAg;g!ci#$d6t)#siYQB1EXqZnKG(++-b zRmEGgokM0m+7+yB#tQY2{%7kmwPswu?*Je4mhXh-Ma%Q+wQEMll_BfxMx7}5U;#7> zeM^y`cMrj*R1_L$YLlj=0C&vWbt!SRKdK0%1>)kHn>+(m_DxaEVKco5+uYk5XT&I+ z0$$QvLJIream8Q-mC@$qz_pWnkauWb{NC(|ELYo(t2JaF#JE=6xmqwCwk@iLT)Ht( zLzTl;-=^{vgG3X2a6X4gX%IhJ-s-v)bf*##ZlFO6GT&^h+FL~Mu@40l4^<3^0(Cq! z_~_v(M;&hvl|h;3-i{YJK@)Pahzi6D7`@hNbn9Fg)C2@~d92nMYLs1Uqr!}O;+%#V z#i~hHln?iOId~NriW$bUuMcI(;WDKdEYorEI+yc~_Eh224)B3x)c1^->C$cEIjJPq zXji%?3IbY?v{A9=9tYM>%G(~{@M$mwAZE8F(ha}>F49$%zn#TL@7Vhp;n72$7|#@@ z7sVHONY}ERDHs7CXg=cGKs@gdYeqOX3~_41mOn(5pn+Lm7(QaUB%vgF4y z(4oNDXt_;H-78JSM735)vaUTQjfui&PwbM+kR%kEQCQignx_wer5U9|7Z8rC+JVb} z0E+&dqCQ2T3O*1AgS=*7Pr`c*|q6dnE`m!C!aKyk0$w_b06%tL5;7bxqgO(rFbD{m0eJBy;q7^b5H zYDkeSY^7O<5S4M{zN+Q9;g`gBA{k7eDiirdm$KdZ78I%uQz2X^MLE|JZ_O21EIi7z_$+yqobhWVXAVP5Y{t#2E;iGfkyNmPtSt9tJe*%vBi{{|P>pFsQb%y_tGDCXm46c&ZgdIukU z$Y3p=Dq)sQnE8^pH0my0Y~lBO3RY8P{2ScPn+RZDEq&iuev~uZx7iJB)UxqvEfpi` zsmCvXCyTQ#8AwVz9W;Y~nA7{3?irO%>XAP1u7V`bE1gXIi4D%D`K+1|tal*{WeX!`ib|@B2S#Mb%%;9d>J&kq z73V{w4h@WACO({&+BQJLl2)y6Jkq*Q7)N7nf-{e_dIKDlmz-OwS1y?@ot|vV(_L`0 z=AWqWwTOFab&wjs+XjOVjv(ATb_LhhUUhVrd5?<)7_V-2S11?{RG69z`yn-=3~I3D zY7yz7`Ix!`=x>Uwy88|`S+=nhabE_B0_~qt%*gmGSO{DnEW+ol%YT(B-t|^^3AIe* zQ}FQ}X6S2Y17iq{IBXj_AHFr_#$n*ffAP@1SYTHF{wO8*X?|{QwmZSJ8QZ!yVLgT` z6C?dZ%sRk_)TLh1mbZS%RC3O_{B*5hdnR8V66==x0iJQv%n?;$rB26(mBx6S-E2v# z@K(^GDVI;(+njBbx4oGCn09wvAE=L<5Tt0|6Z%moP@lPKaBLz0AK|!&YZ^asFM?c) zi=+2m?$c|33gKhmuC&TG2hZ7a*}AH!b&6t>diNgkkymSFNqz`=&FcAXHuY9#XmI== zA&8LUU_R~)g_UH-v_*)e@8wG=uVYohzTqpv0H9Fl#;1l+{Bzi*13qX>=Uf`l&2c;a zcAh|&<>wswIk$ugsW#ZtRS>5;bVN}O7g%#(n+oFJ``xPKk|1wTdK$f9y zQi&xk!AA)tXF(%S0gW1hO!%TR|L1*k@|#u*}PKaDuCU~^Zq85vtVd3tu2PI zE{5P^S5!9%{J+455}&lqz#xzSA_jb9U8UekZZ-`<^nc4~ z(Nm4$AcBwTA4wyktCETb8%~@llql#t)AC@f99%zAv4Vkp&lCaCVvNyg^fH%x=<9x(SPM>G*vwwh!5ZP9u!n$i_c=f)=+zes@=h$fxnZoKg%LS#c z>n`3Vu#tu))1?JRz!j?627Ca@oDWzk3PJ(Kzy4AsQKf{_mzi?g_HGI1$SZ`#qjRua zZrfGyQC2WYxPI>um8ZCG*8I&5C*6QBkuBW$M-y6Z`auvkKw zUwZq-5^#53DN7(sr!qW^3B-QLsBqb|T|s*f2K=@?1r{Vqv&5Ys^?)M97PXpd!(d)wM2{U9aJrr3f#6AV)4C zP6`$OL^VN~(3yh;8nK3dDtIldMvEmE0bdD*SNy$5Q3EK8NKA!}67WVsFy%y@|9dSn znOgkN!?r`;0WyD8(6}l9{m}va+oabbekG(EmE89A-VQw!T^Lfej)VWYi@&7i-S`@; z)y{UOM>IE79ftA@rQ(lvx*Ci;xD9;d>E+YF9Qi`T(e&s`UgTESy6~B^a&Ueu&)fnR zk=mlP8O8uW*Xz>s;l1nkBT=g~<^mt;W(b55_FOVg?p-sd%5<}mU&YRm8=1DAVs@^- z9d;}JG0=l3#4#e`C7zROKETHSAfgXG*)8$LBJxCkE;pR2Y*CXNYjkW-Q@-TVe-%v@Y?z*DZjp`Bm4Sy*%jw_&xVkf9 zHElNQT21{{2>i{Z#@`GYEtrf5mO{&?n)FZgrtVanlbTi>NbUBcq2W&(6!|LEL%O}F zlreN-a9nv^;y1IT3wNbIjvcszxFn#88it;cWRkm6f_^Z_-KB47Ex|`jBNZ z!okr5V1~GAL`A|rGrQ2h9OhdL&zksxoR$ejI)(O8Cda5;c>J2+^BPgP+z^Td=&!6d z196-4J$c*ebKeEOsk$*a4a36fYy3Dl_X6NTD53t&&d~eP@2}^hGDp)I7 zOy5?D$OhQqft>_xWKt_K7psD+La$inDa4DkzB~t-xYah)`c?281lpfdPKi3Tmt- zB7v(=jWJV5BdpLmFIThQLOp4Nwa{y5+q|v*?S_KVF!$3*j9SU8N`o1lP@*066RYES zOy=Tzi(|faP$IG)UE2l5=dNfb`C8LONv-5n%Q@gfi8SCN$W7b5P4-y5%%ndKl}Ytw z7G*PB3TU{h77h1id|U_kcn0`LEv_n{n2#UegI%$q6o#b=@zdDUCC|vIq0jdo_p_P> z%!hP~rooGTu#o0zKME~{xLc)5y^+@M#(Z{6$9~f~9A0jwKgE}t@dm*_L=?GR54D@P z=NPb_nd;?-`)cT(Ejflk{Xv(Se3*ns4F;YIUlV))P11S+sItxs=Y*_#m}S<|oX2je zIfW2bwbfNr&TyB>7m)KD1+&qsp?%a133#UgfyZ>=O+Lu!%0wl8BIJ5^+?C*LOdsuB z?!#OO%eF975%cL<^2^ScEfa%f@pYi?R(PjP^> zfM~RL()tpt@&cr`AH_Ww7Q{RNyZ`;z>(9dH7kKf=Pjeh>NP!P9>jpjwj!{v3h7oZi zfrO(TRXPb9W9v##hXX0|tYy^#cToEYK4JkUoJV5nl}!^=9U#MuNmO*@A~5s2i^;>Khp z+7f|yK5Zx)EG25VHgyYvdiB^*&O_>9nExhltMs+a+$wus2uh`%nLcV!vGtRmz~(HV8AIu~>jzugjy-F{FC z&)_MG5(;p$sDpB?(l?A>5}Ct|z{j(%Agr-EkX{$Oa(@g-P#qCb!AHG;Bbx2q>S|F2 zz~G=o{zfi)kc(zX6}M#}Aq>y+vWhmjn)$Q3KWKT$4CkbB;~O!=3pteWH)Ai#&iBeb zl%#lqjeh`yEsWzY9ZzWnLX;&#k}%;gRd6EKqI`@f&_j@Xf`^ctpcLZ{O3uTYL5i1k zBlr!$th$ekgl<+!NU@DU7ev@ck`B{kYJobRm!+TMGnqdvB_)#D6EPA4SE_6@^W7O& zic62UZ@2sb)Ni{{Vw73In80&`fDhumgvkaGbtC7bS^M5uUZaJ!SsM3{^zWftUZy8# zsI?jidF5O_R!?r&((?M-;)EuWP?#E}-#|4T^R3pGT+4k~oalKA1A;cp>|@0CoX^(Z z4-I@>l29L1AchJA=iIe~@`r^Z^C+Z^XIJqE`tBZzkdM{HLA|bW7QWh@U)~*81?!=( z^^rr%bj@@GdbOT^8BO01^3pqLqIGSOC)1 z;6v7-le!jp;e{p+xO9RK=M$?TTsPe_YrDm(oT@BT0G*PfDOePih;Yk}b$APoF2{Lu zZeSMk9die|@+mwXrRWXFvCfj~4aJo(GAFceWtek6tUgsAn3bq-c}1B^$D`pHiC$2B z2-3RaC-{hWdoVb=3>J_30RsmpyCG>bA#kDD#=gMvNe~WbKiW14@G+fY8(b|S{S60* zE_Gt=R~p+xNFrpbTUT8@!G{({rZ4kpfX4S}zPbMX)+*J3oxj~5O%27j{v#DiIY&K zdr#_dYo>_01f2qY^~RRMeq;seQPwLDgtv#C1hRs{cjo?5(gZy@*n%G*iLCJ*hrMX# z-)&0yCM=1G3qDw-y4SXt`5>~L{L&7twhcb6YRoEe@LP&Fa_vy1c1!VpZb4hO?D<)A zWCHAzh80ae$UFV0c)cq3tOI;-Q$#(L9bap4W#VcBF1ma8)SYO0kHWS4>RsRi)sJVi zfguTw`W?L}UPM;lo6-q~jf0Yq1|KMqO3zN{)y-z&0`3E+gqU8%7+_{%jIDM!Zv9B8 zaQau^Y9@Afkj*&*w-O*xwoTNBE`IBnNfk;|n`~n}F6?j+<2j#ve^s=(x!=5wuukE` zX;N`h-HrX!ZeXX;poxOECHIJRGp<6^U0O4=HOEjt3w;19Z{B*ZNjBzLXHTtS>P!qQDM4R_^xtQ z|CYKFd>pkz>Xz;ue6XgxT~vW0sawqfW_0@&>;C%ft^vrIsbT)fF<*-%MK*jR@tNSm z*+c;jd3c@eCnR_2-L`X;R7@AlyQeNec9d?GT73~Yv=~P4foYS0T|zK9@Jb$~ISV{- zu%rOrwN1~)Q2h}eODu{w)G@}YmtJhC5V;ck;8y`3L{y_Tt@a5gT~Lmeb0&pOz;cV$ z*(^)Bu<#3Js(Pz+6c4bihcr5tMCDaK^^TfepBti@E`7AR6W~LNST)vDMJ<-#qd+uB zcY+TWXE9}`M^KsZqeA{1Q807>FRiIXADd4#b_(y*!2uSdpr7eQvzsK0p>l~z+MKiI z^857a9dUb>6b~!w);nU`R?N?y8yXp6@1hjd;!#fUao1Uc*3a)$Ml$ zYJzX~x+w5M@fS*JaOc0p9NE{D&pC$<^PJu(yT6Aie~sxI#~-{QM^cOMuk{?0heq=t>%c?5^bPm$ z@~#z+pqG$LvlO&Zg{Bx$yQKykM;f`SK)HjKLe|5m0c2~3rys;iQx+1TC~5u|8am+~ z_i@;;1_-(oSzpY+!-`vJrbjiW&`2j0P9|otqks>Ri@AgmfhWZ(*_aAw*pbp4#>EvW zT$g~(?at1jLb^ZoU!MLn`(JIoIJ=cBc3Rk{xs2L$AjciqT>jJx|}fT%7W0tro$(ytHNE16E$O+whj_)`6iX;mPuOV!N2pmNy0LLh zU=S<~c(as(a~;pl|M`iA#RF;pJ`$a1cpzNuvIV;oj)lKtz5{5$oiMFjJi%+Zd-@E3zBJ zsJamu7h?m1U9fx}&1OJjc!G^YPGx^>_Pno~Y!OPAgtWHHRaYuun85L903)aJ8P1|o1#{&S+vtK74wPaXZCO(1;YCm2sV2GT=jMj_vN2LYXdIp;9Qval*Mk=*(57JF1!k z!5FMONoF!uLGUCx7RAXLOWZ7jJO+MV}Keik7kP;#+W7SK`YQZ`);U4iJ7a+%*-1;Pb?#= zVc02B$y2D~(p1u$FXn-L0 z^9xpqMDtIIk)lY9QL9pvg2W`Pn=5*OUpv9bQH%-{G@~yDemrPFQO`I2M`-buHxa2d z(*-RR%FZlMp<2<}0Uu<$e1^DpHU29g?pe@ag z4fb(A{;s)eTXqsPyUA_2OsBy&QaTP zlXTE?nxWTK{3jYn1E!Dj*nIjOshCBi&jfP4UFnti+tGe(Q>*WjVIlUw{!|v(pttLs z;A0DxVffe*o(ZD-C51^Db?9848&(YP-}ox)&2>=)FvnH1OWBsSPw$S$u*I;jl&N z%TmXu10uO%gimGW4W4@>G_KoAUu7>+7(=z+jD zybGB;3Am3d%g z){7iMwfC&VBm?f=u(htkw9<~H$0uCDR;4)08{h-xm6L`EH!;OG+?dm&JzDs|$MTc1 ziTvA+y%D__-+%=$R3PfkLNvjLMfz-0V_)tji91xH94;kOn(DYHcII>B5cGTCu zPPmsM2GNLO#4amJhyk2pug%hZT|0`fZ6Lv$yjfpDKkD~pM6xSPB+ zuXXLg0z%-sRSBj>0q}Rau#Z##SwN=087r3+4V4?j*Thej__wIob;sDB#8-0Qeb!L5 zF-8-7ysyF%SAICNSYfiGb7?PO!J1SQ1iXtF&ZdxR1aGK`a&nzi_GSL-`q*?B%?L{H z-Q>M6oul^rabhWdphVwUM5HYC|Ws~~0}IfihlbOfnS$mYEv zSq5dK>IJquf5C?a5L}t9$syxWcC?n(w;o*WKXT-K3M?jgT!X<3ByeL$p$zWKV}_9o zoszoZVdc_m*bm4&mc0ls2%FRKn3HuGlh$@3rY;$7XB~_NeMFPQ;MfgKHSG3{Gwf2e z32_;$s}Uj!K6D-feDG#xyFbCxcr02jEAC8PhGnZ08AM^UF5EdPfhjj4lzFTB$*;^p z7}F`oRrE!XVW5_6ko2Re2eIQxX{FF00v1ii>P5<@gz7YG0Rz|IBf>NHnQJRYZ9=cd z03X90eg!U2trBmu^c@OJOpMZ3Z^u4>AwVFFYWC?p=S|$8yWe}#7MrtN(Y_#lq@*w4 zV=t^}rPeU1M_anzCS9!-hlV*b6=BjknfB77HWeHZ7abNQ@h$4EriPO3My;}VQG!_T zfvS=J>gc$szuDCjEW4vc560{)>pRvHU7MtsvI zjx8SNNX$g=QG;s@@IksfPG?gZ$CC)XG?sx4e3&0rk=kEt%{W1x3ocV+erjKn15`Uj ztz@_pg$I-g@C_Mhu)=1h5u6M9>k8TN0G7k39B(kBH>o?k!SP zIb#no-gH10{>%6L`j!}Feo9Bdh{tpmIx}~^CSlSnJd2vC!xMa5cs`f~CHQcTduqLT ztae=cGG>z(*-+P^^R*jl~s|ey8m22hRpL` zrC;3T2F1s7_5U4wtZO|_p|9fcSNXGi*SlEw?+cc)){tzfiJIvy85%CTA-8&h4-SQQ zjNr;8N}Lt`d@323%wt1q2M?#NK-euVAzN?_YRSS2nwB-s@mIL|Pw)X_0yeRz&>n9$ zi+pvi379z@Q5k&AzvnYSpiXX}5A{rVoc4fQ*5p_}Pl2RX8smigdOU!)tpVNCDVa20 z3W^S4t>9 zu3qC@I-5qc;2B*9NRKaPTB-)>3eP2ji2z>y%p~G4m4@_Z5hj(>qje7XDqy|`NL0yLHYkni_z84GU?0P-bm}Rg# zP?-d%jmpLVCt)@XTr&RBAZTF_H&*r2Fz)F)o^J}sQ9~q4`}&y9pJ-9ZXKdOsf1DP zIBiWP(lZsvp;rN%jHz&U7w%C^oGz)Z38;Fr;Q)?9wws zeXlqwtw(r(4+AQ7P|m|>`Dv>Ot;*8{dom6rpw0{N zLggc4Uh{~Y|J3tq?`CN8JY8A4c+TO> z@`&h36ie$4q$0tt&gJh~QkuiM95t13wVxS3dBD{h7=@&9fZCy%z%i|Sr7bfXmWTt6 zv3ETcSzNqM>{K!tX)40D%Kln#J!y!LoOr7J;)ZJAUPD;x$o;e4BkzVT4hA*sf{Uh) z%Ot&ceIGg!~8N!qN*MLm4uqu1#v?$sIPAiI)qnr0oP$)ZE=-f(7F5ERFs zLsd^eU|D!a=%jnelzpz5;p3^*+trlRvx=Y!?jdmQnPoY$w_$IbLz;?r3>Efmc9`r`^66z{DaEunHfR;RgM6A;3EYWM_j6L5Bw_nB*#0))6#|)Q$ZMVet^K_lY5K!bPDwJ^{W!2 z)42f|-jJy^Gc!_$1vzYCk94h5;tzVnj*DL0w)Gscy4`39m6+H!YiJ%D`5QT_Z^ZN2I3*Q#_mn42_2fseCJfXDIgtM&qs z$n4+)NGEs7KQ_qCh5)Qe23jxnOLwwSGSD7xvSH4>*SM(K13l%#b??Es5C3S#3n=em z96DG#pAFKTXkmGjCv6M5qaiEKE8W4*f-k5aWNl;z@+S^x_X?jT8Y-A5%f2HI+*rqK zoauKHM7hwok)qX`?2LK;6sns5eK=(YzMj>A>QovK+zUgaT35&IcP{2@TYoerP4~P& z3ag2zkhk_oKC@>C&%{%@CsibJDCbdAv4M{pCEp-Y3RWldN|E4NB$iOb3!UKORA{Iz z6~40c&VuoOMW{%qx13G%J+PY5;Hc*A{KZ6C&*HEM?F^e-zR16(e@Q5QeljnRO>(ys z?58tGk=+*lbH+Rl-m8Aj@1TmT?;K6=bYg%obAP*D#e@(zmaTp(!WL~ z(}Z+4uX1`K6z%oKw}vBQn?eXavT5jPPX_P-T{7|)I~`;64|SS}{}G3*#K+$tT)Z2L zOld!NO+K{i=PhQ42|ft*8g|)N??q0`H!pF6&e?6x+AWCkfQw`(f!IB?lD^65>G%AM z(m9>wF&?oAHrm|n(rULRLZH?JCIc%_g6%R@=32}`>TtBA-`hMt53KR3=L5I$ijwL@ zw#(YVM?lg8X1{JYsTD*;s39Huv**oRjyhh?8l(J2HZJ(tN;#P_D_j4OP_<+_g2zlN zp0lhw5JugC4|NXen@v>dN!Ps^+tDmlHLKs9L8c{pf;NSe7@}NDPAEv2d*%Q~I_*xy zq&PvM1P-UO;OeNhUgk-A$@jUlNpz!RqJWQL(6HNQfZqtKy0&fE(q$jm38j3jriE~N zbv?+mEZMWRwEhHr3Vd9AfjNc}k`2!p^|^Gic1(*fe{Qyt92hth7+V$&t$lm=c%v^X z3u3(@_%KbJu)Uj#&P{hd_X_7!eOCv#4aw13s8eWQRlc(5_GTzJ{^$|rXcK(+PR$@v zk1d8HYSwmYk{nFFK9j!N>MPJ<1dL%j1ZE~&P8U5TGt7ltHC>$W^C&zD9Ya)$%!-jjJkT}-=^lbHd`P7fepdn!*jzkV^Tih z_Nh6-#QEt zag*KiJ_PpF`Pv>mqE)ON(}yk33udZFSD)YmmkU6|z1p*DrWJ)`@iuE@-iY8C4}v5wO5Q7~76X;Vg=1S1p7w3LX0Ch#C{+gR_Y35P>tUA+OTmwx|(p zV#&GSEI5%UQxR`Trlq7eJ9Hw-U5(HU@D0x4AWn6}E~=N-B|P2Z01)jS-r~;eaMwK* z!bcpOe+*uEZk#auH;|t;g9-%0!}7^Uy7Ea3drSL7zCjA?XkV|CvNmVHDW5d173Ps1 zJ&DHEnIej#3OM<*hLAeJq4ML1T?8b)nh@a^#H4g3>$)x5o2`WF^w8jc~2{t)$=QdX&>|?dlB6H7Y2(OVqRgHr65#9AN!?Dm4V!QkO@DnAa%Lyxa4U{3!tN=;4ty{K!PP z2_c~p!AdgwLAIN)pn5!!QZ&_ZfRD{zG+M0P=ObVM$M;16_p6tbg>#Yq>bu6~_3xGZ zcnb)R{@MeVDNGxT8CWSm*phC*M|T=UAnCcLE1-7t0ng)mA5Mz0>(;Fmd_0{zYYj*g zS{|LC2_n(L=$%{5VH$p=`E~Wo!AE^`nVx2Fn^b0w4lCK!oiFxUf;7f#5ayXP&l6N3 z@zS`-vlCP^qF~m!e6-J>)p%Z@B7>7+R2i5d&4kGo946DV!lB}zQH{dG_91fF=1Gsq zh+sSt{^)=H5quaN8&(axvk1BCdvZ|OeU(qm1V7Q)xt!Yg<_9@wG@;y~8>{&9$NMM| zbid?}_$lKk@iWRpia_`YmQrM8S6$5RzQ%4;VY1#@Mm=-6THf~^{DZfkYfzD%3jMj^94Slsk-K9g~s&&_D$1WHDVNZsHH%#{PZndeBU)YP#Gmqnvtekr}gzV`tbz_SUL z>=4xBd)(3xQcwcWk6P_9!P9*H#n+i=OKyWe)OKt9|DT+bhRX$}6J?$Eda-3KrJ^WK zm&Y|lfZnBm_qyvY>rgY;MFlVkh#88SKHBLL#wlbNua$0!_IJbu2IL15FVxmk#z}!s zs6pwr_sTOxR^86N_hmHw=mj5Ii^MQNa;IY>&m)dsoA9W@(#iFFm1}(Za>1MT=V=;V zvto(4>&(_p>kwvG8f?_e-F9lJ zKe>GKVBitlOnARpZjKFpVFbgWr9Su5GZ8VmxK+JW_4sCS9q9=lLTd!$nI@@dXnyK^ zK6BJeBx)HMZ?N_!$^|;rv%-p2ar=3Km93MwCt=VKzRa=`NBqfk@*06evtG4=B`j1= zq{X@Z^eHb(&kmB5b9`wkNqczhI_%Vj#K!u;lI(L9d`z!g_nhoptV`W+o2yLlA#H0u zHO-D$L`fBDGys0kVNTSXt=m#l?!#ctF1z=j7=d5&tg#pChE3I*`>g;dHa!s*gVVP| z%vI%Qi-k>3}KtKv{7`^HEz4wUCr2I&dDHSS!cj5g!9+&r2Ea z3Enl`2w51LKU1ItV(y@z*}@o(MobRnR|MqM&~eB$>KgV?i)vSn6{2%2z{kXUkROQ{ zYIU*TBe^=;eN|BLjOth{0P?u47|ww;w=qDs;ty^%0L?; zat33AMo2A46@5>T2GdQuj9zDBf)A&o*JOl+mJcIKiczG*P@x;OOP5=mybQmc;V6S= z(5)^s_s7eHj5mw>1&H%&X`od@=#r%HYuhz|UwBR^3B8k&HDGPV`=v@OK}pZXwbO^Uj%B%loa)&2eyC zF1sL=fyBQGr0*&_vuwdnEl_tp4Y0_`SH#bAS#gT$+OJa*f+YhoPd9p-(Y*3cWf698 zmmk!0{)e^m7mer@kjV9=`R*o7+MUaKP#ByXN@16U7F$JB`t`c<5S?3|{i)Q)XV3v)?}4}qto4KqLf!=#t- zg|iQ?K0jhW_8@q&qV+?@<66I>zWVD zCTSYS^#t?Vc!SMq5ZUtTxLhXC3gL9#@OI;OD_;oTJG1hoMa1?v!wZ#3YCX;%FR)p+ zFQmeUnrlhKv4Vv~*(hMvT;zFb8Go0{DWgFau*0QJj=sHI<-;R5%dOu&9lpaz5gR=A zI#hDR5ByrDWFRGt+ErsT@F5w?kB_h1`9AK%vt;?K1)6}3TIv~oKf{wkwP+LLlwU2( z#7KqKRRM!1CxQv+f?v=`PbRL%!P7!5)6(kZV%MxAT27BO+qladFZ#DwSdLZqHh)8z zM}KJ9TOapiTkVbh0=O#1FrSayv*}y3$>WsRZ}8z;Sov)JK+ND6Y2^u5d!L>@`_v&4 zqOmt5Qb>Wkx#5m++y$dqqcs9jr? zA3CQE>wRlYM93lr3KESBlXq&B3IZd|Q7K+b*F!l(UD1|lN3*aYOR|0zLE90S36t;J z+f#5#^bwOi*qD4~K3Q8UmAs<&_NMcKuZ688;^C>UnIll+e++5QmaYz)c|a!89$Dx8 z9<5iSC}LIqq1;FmrFXOCCUaWc`9)XAJ?! z6;$XF>;@w;uyufm#~r!CR^j&p^D| z%k^HGj{Q#TA<$M_$(hLJN}Q4>t3Z@<*>am8g}PRkn9$^k7AoqsA@)`4hX>Gku}~}I ze^!#YDJJ+qLR%TXrdf!+SbiiueHqE-IF%dFxC&CXrEGCStB0#zIC^$KD`wFVPk zd7@`%;kviXe){FMf6(duSS^_8G)`ZU)tze|5qZ0B|NlEKE;H(Bcb%!b=* zEdbk?jJv*l{8FOO`73od!3XQJb1!G{7FpBbDZldoaglO1A{<;gUnmzxA*{Q{k?>Ml z!kD*5S9D<0@OC#())pM4SpO)6?B(-snj#E`shwOl8HdvK;fD1Xb)g^ImcNeu+|67Y z`I^|UveY#(uI3Eqss2un)N;VWf=g| zUP+?y+;lu%VmsUw{7P}X{JF=NqUwQ@4!AN8cJT}c;Jag2ag1Rjz4`b9arj( z1pDe#1?b*P8s4QWL^E9Y`5-u=h1nu?f}&1!df1Rt(V;eGA_Xc#Hll>C=-F7x&mp8P(f-)9P>LyNEg38ZZ zevEafucU*i*LJyp-Eo0=8|?NaSwOo?F6!An6_aUH5f)YSVZT|f&hKY-5a^+Q++0-7 zXz`?k1`=I9_BxugYa%P>HspR~Nv5YwrK@ONcC+L8ZBWM6Q|Wk4Y@9c&yQug%-6;Md zC0jJWuB_e~_umGMb9x5caL{wP5NF4!<_eSMJI+WovtR2hYvE)MX2&X8Z3)s;p<5G< z(*&h*6;BOw>U^zw4sP_#jxb0hRn?a^&;~DOX(+Vq9+iO!;)VK z$3N49eru+8OwdSPPQ??aKt`$p!bBsf(D8k8`=%MvcL+eD%xefSh9PTw7MHQWN1Jpz zfH3htOpb!nE>q!BsTQqV(T`}%!?agFP+ThGZPr3*Z#%|zE9>3PCeo*YqNOeh(RLP1 zJ(wp-S0)!z0Z;Id_y9YY7qXlRe_8G}<0 z+~YVBNQ(6MbUJPk#HP%i%{EWwV_CYNI%v=sV?)u`kVOUaoP5mPN>(uvz%-*X_(je6 zPrvO;ua^mWj8vks@rQtk)l?er|3bx9#MV%tO86kt1%qw?87-d$M6v98!=VNfD+m9y zQk7?K&-%qxxTgW{-iTDeZIVG<^p8)k^@0i&J4p+flFR5Q-h6&kp0n28m+AkYYj*)y zc&3KV`4h=FfYl@K(6xI$CqFmocnraT6bMSc@e>6LRje>0@+)xYH zQNFPDwgtCFA77&tP&ti3 z22GQ(>ng+6FXsH<9M>21(hBvo0>!pWl&)PA+K)6pxAm9wMZ@<;|H2|n$g3GOqzxw5 z2u`oftG?hHh-6_;I>Ydb?e&)O@62;y2c}{|pEL7wNIC3hvNP46to^FEpgF*skhp&9Pp=Ubf_e5bS*Z#lz)L< z#i$w*7&R>9y>EP-A~bATj_cHSvi91yJyduA-8@0BQ1M5dK6OX}1!bb{bA!MsJ$4W4 zo)JpyB-XP>v#XWBNeK}`05Bk7;L9g`JkU*V41IXMC#H=A<0!c&=)7*1GiXK9J>w zSkZv$R_2nvOftLtM(=^8PxBmObOMuc8sLL*UB?Bc5gidED9wdOs|8QUe5D72NknF4 z&?7LlEs|LH!SXX{6cjtFnfKSMPnLjGzm#uN=dA7~O#qhOL!+Z7fkDAfZ=q33E5PpM z4`OY&Yi&9NgS*^5CfK!x+^97FQM$rNZs0>~jn}+VaQ48C7=2KLc~#j6K9-h=zIUw5 z{GvrWK5w4=M(CA$9Q`Ne=@PNYB*{yb11^LQwQwGeITjSpdYq6yb8Me>8RZ0(gAL_S zRgbf4j?hN%fzBycbH?DHGo9GY6(8=7}!2jO6`i)Vu#+fVPq>Zs}aW-^-U_sD4^=p6kvR+;_hd5G&6u4 zL(YDRAA0)lJ(nsMY0K~5N%$4_{?fSp;gGb`TW8UvZA~~fbwC)1)p&&;M^Rk%nBXO# z`Uta=0lZo{WJb&c@WFn;`2_!Vb^oK9P~vjEI?m5bAA5ANwUOcqUsON$r5@Qz&cdso z4r&4egGpvCG#AvPG``gnoZ*uO3p`=Q=O*e7SQf+g#o~rRpuNm-fm) zw=}X-M26oP=xX5oiLUldTCJqe$7Lb(UAT%~oBK24(R^-f2h{6|w#H&TEE}Zn*Xl4j zcr1qgVX0$t{?URCu~Fsyp)E*it6bMtzTJg{^=? z`~3U2MU+!mfYwi)R(eo)4Hv~SSa;IYKDLmGfoK##%yad=BvADn51t#LVkl75J7npg zhw?GF{!FV#7S9}WburCtMBST80eZgg2Ig_i61Br4*Woy~MkXTLeZ+Dx!z}2hrsG6B zwdg5XB_3LFdPxIV!qfmnboirJg|4kRo41qi22gq$3Oi5*r7)Kgqwr0lLn0wt;~M_z=B8 zeCdD$kKRjlrn%tF;0AycDhyQOiF!P6Rs8uz_f?*2MaPvNgzmfJcB+)D_Vnh1_YdYs zCaE~QJt+IBuTgu*qpm2)ou5g^CiuwRUM*sDVYFWfj?-E&ees-3Cm-2UP^Xj--A==O z66(cY$n~wsXCw>XxzFK$X${hX({oqGn(Ig|(Z?a3YzIbFRz<@u&+?<6pWx#&qVP1ldI297;DgPs_Port4R_shNVSc5 z5HZtOUz|!~Is34ctiIOF8a|1ij^d^VBgyxrqv>pMW`ra# zLB2hZLH0fLM=%)RZN4qy27fL}13Yl%BC6YO(hEd?Vm$=HL@D~6c|m+8!(%WXW(M#+ z)YeGYv-~6H#g!Gf(lC_)xLF2|{4+hZ`+4`Wm*u*fmngM^)rAqe{9M?l=o3^IL4OUk ze$&tx;YlM1;1S3uE*;vz@kvz(EBdqG<-RIzA9w9{vqE!E1Mx^}0~Y8{wU5LX(rOt2 zui(QNW6{vJ+uu1%?K`ZWcT9(Hp#fqZtzh4wU<1_f?L`!m!fh#OfCqwB0>740&GWPA z-EnLgNvnsc{Do?HbDb@teEgQ=?pmZ8an03Y#tZ@z?`ON84|`$hdSb1MDN|6~AyL#_ zjn}FkZXN{jp9wy;%kWsx?~&z5&o^JU+DA^vA%f|o!j6_Re1ykQgz;L6&lFcTyn#3N zA5z)D^2;wWZx_*kLH+sDEQQ) zubZKje9(Xos2Ijiq#-(R?@tFGvCuvD^S<`!u!VI;+jqxfM0t`jzPNy{&~b-d)d$X6 z>(61!8k$Y@CMAn)IAfZl0xRHr@^u1K|&sMA&? z^H91u5$m2!7KHM$WHihgIple|MYH-N@ZTYuXW3>$kEuKHV2J3wo9DfQ?HY*=q@NJ1 z83uEyfs(2)(q_}bm&r8&5bbnD#4RmtfvNPRG2OP>2S#=U*PL)70%`aaH{oqu=r1P& z*8aYBHy!*YOezk34-e^;8?*~9n0J%U*Rp(^EG=7ENnv^3l zl}6gHyOt_dOSmF)12xM?K_gqtb_g%DmfF%CKWH=G*3Jd&@FQ@3;_?^~9x(&IT&a5!%pq?0tDB*087 zay|F0se%VY52AxHl7Idx%-qF0b#;oI(`N%pFcCohCF84NH6?`wP=%1ZS(4C#JLcv#fZ&nP#xCisL$YG9&Ib)!}>rs%Ecq zoM?XvM{Z(k%d~?!gN7z#s0=L??A%f}>16yQ5_L!GD1Fp7c7yR*&1jWl<86GqD^7Kz z;Dakt)VII~)6LK0)UN20v_{dVTaKQU;NWT=DJsiunO&+VgJhj-TU=;pL(gg58ZLXWRe5ae;3L%~3Qjc{>)^vwTf;7~ zp3&utqazQc?B$FbdC^*fWQpbJy>_>~K{^`0r>+xEB)wSHP0CeYq2#!1hHCCNRor8N z>@EptFW^*4dG%^0qz~$4ky1t)e_*|(m#}sCc5&;a1QNHp3q>C+#lWfaQ8<$>li8}VpTqgM{Y;~^)7LMfR z{;=ub+1tOIZ&M6CU7zYSGx6a2#AO<~nL`VJy$0}7I5*RS1~73qPJKZPZ|V-m{^uVH zY#tZ2lfz+Um#FxG~Z?MNTW*r^-1QV|2D}^!H2Cn-|YjTdBA1I(>&nV{c>Y4 z){gs5*lh`@T*lf9p6<_#NOZOuhj3fHs_kW5eFK>Lr> z;&0{u0Z6E&u&slCJnVB~Fq|f;I4jtp?n7rL%H!m7(ZHYg@8{yuDwy)17rPp7sb8Rl zRF5u{`=U$2UK*_Ue!psJP`1}Qx8eGtw8VD0KEOO)U%zDrUg_ipM#=RB?oBI|v5@(p zcF$O5TUC*HntK{#>*G-HaX#fNN5VJ!Rm}`inrnr6MRyK*iF-(&ni@_(18Nmw?1^zd zdEAkyY!-s&yb0O3Qz>{?XMJR5b9%QppMTy2lGA-WK{=C^>(s|=JArt|w3bs)StbB> zv1qUE?f!h}glP?rPPZ{oPd6Y@D#Dqs$7zks7$@i&=_rq|`e!m0%?>1^A_hZ@t-Wi# zZkCGEo1pO#v|*&uXb}5LqHn}4(rkf8$&bC8E~#*Yc>-1z)*{fo5YLfxjvhRxFrDax zXMV05?E{d<#H78&$f}nN5h35OI7S#vgc0c7qa&{HqE?uPeg4VUx)}>r?IE3iJWv_O zsYqQJb>IqxA{V0(nn%ade0;2X+PqI)J86Oq+dV|g@*2@Pe>o#|L+$;jul@}_3}Q1k z(C@!+^-djHX9O!K{LDIX#<-b9^(we6uNu~z$--zH765%tbpYX{kb=i(S=&3BiOXG$D&2!o<{S? z7xB{9gcJHZqOz@W?KaPxBVK6mjCNXhRkqjxY!RDm9WMER27cqPjJGj+ycRa_X1|iA zRwV)jeCKXgUV+Tc;xm72&pe6l0@Qm(N#IDG}+@l#1`8-p`lR( z1`6K=q33fow&tCMU!|Fh<7P=K@Yw_-zeka~-M(|)+}1=i1&#=(0i460VpD)RpHW>9 zjQPw`c0Ut*z?>*}QN+%@{Sg$;$ZB!zt4v&4!jF1iyyu)EM;(VY3(I9yYXqmA zK9$?jjc8US@=u=r2N;|Jq%P(v%f?X0J?c#P{XRI}Z!a;+G9>5sl$Tg$0SFWX(xc7f z+Fac%;mH5&2a1!^#4M&jp{l5r@fp_LRT&N4#b^Uj=HUMF9smCIeXbd~>^x$;Y*Q0!C|ISnMAJK3^=)An>rXTtUIu)!my93Al&3zP1*2O9`G{bv0G5yO%0?9D`R%;w#qB%P_MPrW`hgUuf84x{s^#@WC} zToHZ}=L`?F_`uXG&E-YIqs4sD8=Bhiznzr(cYIZ$l`w`xP3$m=*wu{o`*cWaj4WA> z?+X88p{&bI9}uF7=@Yg-6iM?G!M%ExSr6|j`Kj31&?q4{4f)Y-7A9QgI1yK)*YB@L z7+1S)O~iFGHMvRFDIROInVvdXle7G^gqGwyI4=SaGJgm5F!@Z;r#|%lVY!LceFf&3 zb{+$+ix9KTxw<4cN_2~g^c`b!`ZM14t8o4dBikeq>7 z2@Ij+^)Nl`YT&1N1>lTs>@dPA1bTf8%m!m98ofNMONKn5GMG5jZx|;iE|ksV9w@cE zA8?}}Y4t>#vT5O()MLx6ZQ>r*K%QrGx;cBd8KHm={K8?N!Yso<`>>)5J{}i)RG-zr ze_%K#HI0v;;PAG7c6{(_uO+l5on3x!ik>r48BH|x?Q9>t%7yg}=x8R9;3M2k0|3b; z0Y2`J`)+740@r-qNu#%dF??B;PT7W}d~ww+DQH1Z6Y{SlPQ8deVIWK; zJ;N5FKrv~Hn_KLZ@U>|MWcM}hZMqp`9n+ni$j@rwNxJ92 zqtJ)r(XtnkJe|+p`h<78s(Ys4ruLH`<3x^}=F1F-x9MgPF&#o|Fj3-m`yc?97u97& zBm8d)lbi^M!pB0~fVViINCh^dSySGzYt$bsNI_*QIeHaC4&b7<_l3PrYa&JRz$8T3 z-j^YpIgdU^81naq7i99O=RxSc#dQvKuYL%Q2KZo~Jpw`S7uZ4;BXU8A?}&YD+jfaA z9oa4h%*{|$-eo1|A4cM1yh;u;(htOJDkk} z3Zvb6`TP$P12V7RgPeNzcd5H<_aAsg(k6;;yfA`_2pa)uWO+mzKVNb16*4DNCkOaA zS8(swS#k7XpFNEPg%UcO(06B4E;J+7=!K!owf)(&B;S5Q{J_=3o|B#v1I0nYH4oKS zU)FD7P_-lVJF$hm1cN>j^JFzvpe9E%oy3V&dr$kojcBA5R9g66bX;0z^XQSyyW6&@ zzU5cLIA~XqE0gUBms|E&I?>q5@rbEqmdqjC2#_uFM+Ekua=aED^@SCTvxYU?c zPX0;C5SFp^$5%!PXBK>+VXc$S$|L9L908zE)hFi?sI+O^!Ow2|VG<4ERAOuJe4P|k z)lH1OP7J?GBIu2=++9vdcgbS&kbn9N$QWQePCh)0RV`w>zkaGeWmHGn0_gB=D40)8 z`L=#>zsNnB!&{+xltTu=GBdw6dEJjjOv=Y*NdJ8m;|`a3G(;YhSCc8UfG$7Ry^5MK zEKSLLT<4;i*Ee5}Z#0{=XFNIQTX{&b?s=N!0(>eNNI|>s5c7MSw_na>N?ON?gryyH zZS6(%*d?IBRF-`uj}nSRnWF=3)1s4-fR0`YOd zEMf8ZNeF$%K)W&i&8=AAn?;d7X^4ML%!hkL1SC?Mu!}-cg12WzBPg&sSxK8wC_7f8 z$aP}z*(}>alkzHsivo#pcH&%y_nCW+^zt!Jj=E%QykN~QL&j^PEJ3+{+UcMbeC@$%-FH|~0Ty?K()k|J%BOCM>) zV0a3h`8X6m&si6bhp+>}<||XlZ+Z+WbxTnLY{tJb0}qtWJ@G7d#&oY$&4SdKmvx9% z_L9`ns$aJX{@$h2)S}2a9HH9{K4d?%B)y-fQd%)Zjrr2eKexBWHumZ%=G<^Nn{nyH zm*mq|*^qn`UCxv8LSQ@6>i*7^*(D6-;Hv?vCZ zbunRh--IAhe(O!Xbw5fy>#~hl9g)u3d?JdR!v8pB6LyKgz{ot{l?sQSlFfV~PvcxM zOL7E}gKM@~{GCbw*AHYS*DP0_pR?0!TeWYGZ_G6(HUwvj`m(ba=#jcxl z+khAAMjpI#a2eGbHKQ#E)S2$-Nw(uUOtdnX2nN0B6*Y>?GtnM56L5pJXru27B#RP@ zEp8%6!wPQF(wUs5oxTsE4I^bVbwjkSLz!V1g5ok^K0pI+YilOlVNW1dmHB|#D4HYh zE1Z7#n(gQ3ytb2Nq7XFVS#LgC&&><1$25;h@NxB+lzNdKZrhytmT(T5c$aysCBt%W zJ0*0hP+toNR+)_`gx3#^lUVn|`hZ*UUju(Ickmh!xv|n+ix1$?`4fDcdq5o-%g#QI zFkyFdTlLghBH#5ik*8vXAMZ}J0%0PNld6iPJ zn(Sa{pE(-0^@4v&s;LKk#Lm}lA|_rgbE_j;(mNUwy?+!Nj*l2~q0@WHB;-#3|}0 zBS>Y97?T3~*UoG1D|O$g=B~-LyO}xB={ZX!`j!H#e&fnjuUG{J|6|AF;!ujuc(3gm zKNyKcem7^$91;RTb%m4nPw{^mqxQ?<1B{s zc^xCr`);{HdfJG%s*MB$4N^exTePsL{j9XHT4T{CV>nOFu~`2AA77-HB7Rtbv!jr*kH{CETeRui;-XwJ03ycc(;f%Dma4U4fX=^!Q-ujQpAw5T{RiF7$;fJ-`(x z@|?7^$x>$(_^h$Ud49&&;aC{pleGkV6`Eju9^gZrQ`@w7p&e;TqXv^QMlRPHpu!z3 z)3Amlwi1l2-<>;j zRy#_T5WXJ^dh|2*;}7R%3vA^^vvNQ`aK=U(6j#CewUOS>wo)He&?*PBQ?uewfE8!W z66CqmhoeWBsv0>De*i>4yT2Fy?~<}^J8K8GD>1I=+*31iUnMch6W=*{Ab2m)**D3C z(c*^KGfi`Gwspm95y{GF&;he~3nH^?%QyQ`qDnaS#LU!mxab|m+ChpfBs}Fcn`&3*mG+C%%ElWqYXD*I~hGZA};VG0G?6pY%go9pjlAmDbWalB-_O zLM^pP6zm@)rW%a>KdkwI2~0O6AW(MG80IDP$T6mlz~L2i#PNCzny@+46O;HOg7(87ou9eZ|e-*4@LmIK+Yo;M43nu4N|Vt9WrT?i#S;AnOM*-d)?XYW@Tt zY;x4cTPjvYShxC>iZlQxe9kuL0~mtPdm!QD0afL2%`(P^j8KQcL~gS2#Rs;y6dZWH zYlvN5g1zU@>^+NT!j(%P`x}k_$~; z%%L2~1}r_Eo z;{Mhic44}083@`o^WjUkSGjgqtGcC;1YW(PaQ|sdn}m+RQtv^{69)u4tGQh`R+)*@ zH>We1PBcmX6;b`zuLgJmtPj`7t_b{@Z3Ez*LjRpbqy^Y~>u)bM2uU?3!|8fhHSf?o z({qhvVE|;5uOL!H=ya?#Nr^fZ6X?H->)O6GD3havC{O1q|Ad5ZI!HzG*4) zM%vVHLG!;Ot9%U0eU$(OUTevToq#b1-ZK1i`7j}pcBZj?f)DkB-yg{?Xq}3tv*S85 z*}cPYI^8b3WZ6~~kwotwG?iqwq9@yMHW~uD zopZX?#BE#e!F_R=)7(qj#p*|9_TKB?=(5_<{Y=+cE2uh3-)usq%GaHFqEqYknta;X z-Kq!lgfdDJVR2PDoZDR#L?kT4X$9~>TYqH92_sK}alhoj!%`aEt`%FmmeQ`XS$f^( zt5lQeP^b{ZCXRDl#p@-CfqXSC#T7%qnxCCfQUZKnQ%LNL;9y-hsx zuoqWoj$Yu~*jprrXp5NT-nCjt-7t6Q7%%hR6b<^Lt5I-2gw$x=jSw1sT{hm?ky_Ym zv*Dh~;3%gnDW{miE(W`K*NUfU9)@5J)rW~NC^*{9Dr~#n^e6(sc%MRVI@rNe>Y(AcxqQyZPO8cJRM9Q1WsDgffidfZb}^f6Ix> ztbHSHyL1Jl-WB(kwLlnrJU8f_ssTr-J5Pwcpd8L)1}9;JDALbN^FZxFWVpDwSH5@r z^^B^6?ms~cW1Mc8PS30hEUU~j)T>Z>`;aHfgoPuGp2 zcK6xlN*q@HSkXD1!2^C`2{=+lAd%{cf*)(`jMRCAfIQ0bui<($LUdl3D_YDZ%h#=n z>`t1<@H+u^vZ4;j|0VqlWUP<<84^w;kMioxhZ{9M;MNWvaIKeXIQHm2H1tG6iM!U=pyX zi*qs5T;R}tx~>J&E}QX$ZrtA%fwnJz?bR6yl^XEbg5he5iq8fgqK4bfk}j@zFX*83;vjoT)q z>9Cl!$|YSSCo^CeLyF^|TJk|z$tP^r;ogULSB4Lx93IXHdyP>j#l#RLv1H5Ni+3|C z>0FDnStL0tFg$?~Y4OS5siKLks2C1Oj-ua;seb9-ldC3di;-T$mIfCbDpWM0J6 zw3z}7sD_R)$NTgrejRF;r0ZFe={s-~$anDZLh*VGR*LDkbG-3G=^24WC=7$BvxaSk zUE&9bI9X$F!AIstoPDN7^AXaJV|~t3>V2Emn60sc?~2K{MH>`7(1h+QZngJE|31>B zvvuI-nSw5VvzU1#JX%}U*YdgMjk$Ab*rLdkP1Al@#`I^~SJdc*b+$mDW2iqX{~QVZ zK3rFMn;o!YAln2`c(Sr|$-pd|&rRy4-dCp8d$U&fzh0A@bqT_U1usxVZ;&)F3s+F8y!3cGakL{&x;!(WY zaV~ZibeJnjy~v0^xfQ^hRSMy$C`T_o`Q9PB(j@K;}rGm?l&(tYC_=MZY!U)BYgz(K0akDA3R5n>y`COwc7`h|hbget&oFn? zT@mt@j=I%`2_HFv8BE+ITULggbg^_usKi`zL;$vaObZ3mOwIOhqZp@hBkNbS>~%7E zc>8vkXWY4XxL;e|Kvfuhz~wj9P||Of4>pwlP;b$47H)9Yr^P_oQ=}OC&9eA=*(^QC zQ1K~_56Ilh2{zc6hF`*0H~~4vN5l+!K31)hG2S{kBVatW;z-JPaEeV&!w4Cvud>^T zq@m($Rv^pitzEdrs3!NjO)A52|1E726)?@Ha-|s+d!#~!wf1G}em~A?E^f^Gk@%Qm zj%b#>5czhEVoE{~NMn<}C-aL3Ug3_Ayy12&{;rWZjn^hvG`W*-8`qmY^%Zdxpbrf2!<+YTF^!bUcAsk{isYN_bGw3Q714tv2$-ycHeD zg?|HHA+Fh@Yl4s1U^oqSl|h1zKf~tBAcHC!9%UW8RJAZWwdD{_SwVAUaYbpScr!}R zvlM)Aq##dvLnIHb8+?T6DW4}79nd3DvznkXDN>FkUU;p&{u$t7GWe}PrKh`{L`7z4 zt+p7MxJif|OSeHHqWodg?7NHeh0O|LRvUM$Zl1=vfd=j1BWi_Bb*Nv;;wVpa9XcQm zjC#kEq;wVdI~D0|990^>U%?NY+iN?Pn&-^3OL~}{-*?-9A2Bw#htr01Fc5}yoS1RT zsQY2$A_mo{w!pT6508M!&IS0O4iQ)fccAs?+?3yh%#71TyWVQ28^qhxoD8DPUrKBT zud%;ZVejT`i-{n=iwjiLjl2$`0-^@r=AjCY2_xokwKs^&acV~*R#i4PmG7#q#w*t? z?E<#|Vghu`uW4lvd*U(zq$0yR?J?Gsr`mg(f7emz)kJjTZ;Fs>NtH{G;gYUB zs$KuKI*05<+!tnhp|}1)c2%i;*K7SkbI#QWuQ7>jeddVuiPW^wn??8SwW zbZx0SMNi4&tj+4xO%vfO(BTa?MDtTFRScF5wv`&C*Hky0#amdaqrKh({mR$P<$P5` zbPMFC1k)S%Xc@G8keE#z7nGI0JpqF?0$POcyB?dR*;Ya4^#fy|7D4p$-qLP^c`*X# zjgCh;u5DiKEVNFDu|&8GV}l}e%}cvoq9=|kEwaUd0jVdv4}VdEJh?n$6U1<=VPuwJ z!H3$t+Zdbj$U_qz*+2GtTa%1~8dBFa3GTyDXx8!ho>(U!=SW08+6HlK4cx)_INgLV z>B0gZ{!*y^y-rv$G5cS^hf|BrdWpM^<1Wzv#WLGB>(m6I^L9eBVZv>9%cN)FKbHA^lLQ0nJJdL18YRO&zuPNIrx}{NT6mh z0@Pn&_lrO*!N=iPq^Okl+CnEfEU%XAr0SIl6ZbHj_Vnb*ZAnv)pi2yMiHhdxe)S?0qixa{db zDPqd2V|bgH58-AlHD0ljWLUhjQ0u0eb>s9bxG5xt26=rhpTxDNBBU^>K!kjT7mK0u zp1)v#TOP|+FJ8VuUajzNLnLRZjV(qb)WDn@m%nkb9dz?eU6^yF3dnNi3qLizWJ8JF zsmtG~*xa(=KmC%_eF;9c*y;s){QmLG6NGsF227#uwij)_OVg^FKc>+{NPWj4++rYuR0IO_HyZN01sIh7UyE20-H}fwb zfaU9$L%qwFehIcg^imQu@TiR}KZ_EZ4!~st;DEwCr?|3|FM(g=Uz^zdh+V_te8wiEQx9*NRE@Idyrnw8^Pd1YbB+Lq)5~S#D3xxyoYmG z!0XJdEbwuJ7agRLZG5+L8L?1EI4hpK1AoBw?0tnJ?Znu!WD`Wt6m^2N+??}*KG$=9 z;tyzVzR0HS^HU`$08n8A57(4n zm+Eb2&AC`zgtM*3V`$~52I=IGi}kF&`pJZp!BEx*4*P(eIIct_`(H7~qE+w8D-i@r z8C=oPXK=RkTpcDvYm=e^&KSA((7$ooxG27y@cFEN`}P^WHRD5;;6{F|o$7G(ur_tf zbvTi8+O;4>3Hy^Mbaam3BVYpRyV898^Cv(Zz5FfKNuBNXVf1uAGFhO5&TaFfs}q23 zvsUFFxk8I-1Mpb;$pEgd*OuDwA-Hi~pDRXwc@3pp#MK-V@OBv!bt;*Hn#ucj{B>$` z5RWUP;ZzIR?}+T0(=taM2n# zFq|wl^Tj^q!5e3!C`K-XW(c}ET<6L^sfjrVPDA;`y(2*V7P>22@^z@U_J&>1h%{#;Ecb(*}pnLIxl|{!mS*-L+2aRSb4F?t6`dX&pFpz5FyiwB4 zZB;KtOuo7yj3T?fT9|9sXr}%U=LyS2iEhFR9 zX7(d1?x5-^Jb&fZrL#2fqaR&YkoYcna3P{HuGcWK*bWLBdG6-7vFh=_nkOCAo>^gb z9uOmYy5`%gyRzy;>!Yy7>Zr+t%I)%scPv&D>T<~A{?b>vr@b&)+`PwO0h-VR=UVmF z`GSc+4yI^%4$D1Gk@x#hxG~%hu8>)NIW|HwX~<%x##iuRMpREk*{mZ3wm*0|iwayO znX}`}76@Q8ti)~fD8R@9I%eP~eKizB1yolF5+Z-AGjT1lisFnJP9mup55D4bag}ip zy;59Fq_H4WE!;XJz{{J%s+E!7U*2{KND>YJeBWeCQ^M5#5(nd+KXAR z={CcQRZiG+c=^GsS7394jSiAJSVaNxY-zgdOmY&x(0DD()1A+$90dqH zttK%_rFT=(uG7;PRYQ1p40(0@rWP&Hr>iU@P^rZz4NL235;jhJHHy|IEeaud9r*dX z6s@xbLhewGAP3GeQCXAAz4qKr`$1>BV7mR(_Mu2))vw!Sc{IPcjZJLzKm?-E^6Yyk zEC>{4sj7%OU!EF^nwAMYGa)O7DGNbUrtC*|4t4e!KrPKS5KWTmCF`h*=+Xb@*~qm< zEX*VB@?;N2S{2P0hmTQnx9J)RtMuc;BpJZRUN54?aV8a6{M5NJ-OYoihaig9hv}M@6+^$f`7CgTWr(xI@hz%9r_ewsd zi|2NEM)m*7j#e(7dKi9^@E*+0ja4Gn2&KVh!+ zrzZ!Ojl$cL`7Q=Kli?S_fiiV)@$iNNGE6R)U;q#;42k+ypm!X`Y%v3ZMZ~hv&Qsy> zIXazeug)JtB?Xo4%|-v#Qsd2P;X|8&R4IKYS%Q(Pg+!gL$Wb%U%4vW=Bp;A>LY(AE zbG|4Dj6q> z_U-X8vfb2U`;wvdAo|miqd!SLSs{o9c~da$dGJJ;(#ZlSuwI7}xbfB)5@w)E zTS5L9m-%MhPs3ABPZ;V6XtXBjVlpda70EGhWfe$7WBX$RHa)O)`LvqMm@?MO>@AB$ zQDvpPxx@Ik8W0@xbQb>7!lJFR1k))Ald)UPNBMlzn(KUbHZgpSKX+hkqJIcE@5fPf z6X~~xsO^*ZsI!wMrjekY9bm z#9cKI4K#(z(W!@wE-XC;j9xY_EU>lkb>6n6_*vG+SRC1Xwdm1=8y$iA!L)Wx8Q|gW z+mag|ibqBakY^Bow2>dQli;l7a^33c@)d%Q%9EtnZD3W-;I@W5qFGL*lT9!u_u@e> zSP!~_6Cnw<)R@9QlwEuz2`q;_dUrXH)2K}FYr_D-kj0R1I_hOtw0z{JdeIgDdZu}~ z=w#=_PRz-x4E>1D%_rrySfo77NJDj*vs(l7-Yj?Pw%)v%uBQ~^yX0KTA$fTAuR$IM zU~-5A+;X?NzSunA{FoV6jBbknF(u_W41qA;oU*Acp=`l6C$+05X(NPZv(*V3PMKTI zA9KX0DhiY7l??%Wpu-!)1YjGnVOA~8HWIBJ#K1bi2LVL*iAEyJAG`3!#X2iL@9xt) zU6A|exsxhwo8W^{$mJ@(L~?_~EZ%3u#Z~&?emndlvsq^kFvr;%54O zJ1O$j4_5`x8x0mehA0z($#du`#!!mE8NV?gll*cCorE93Ql|+WjNK1DDL4osgt-y3 zEnY{gdvOyApeY0Ij{RpA*&Aibl4Hn*Z&^wT4}SGa+4GO&Ux#8ntIhILuJ!^4EpH@7 zp4$mIV21g(=Sxh#bl9A$mm}ZMn+!Kub_|&|ZMeFBe!}3DdtpY=6xR%3y&%=jQOYRX zPPLuhu69AsGA`FUdtS&Tu9R!yahfj!dO~~5p*}xsR*RBMJ%EpsX5YjApt-z<9whQ@ zOA^a%E*4?J4Eec0vEm=jWVFO3a1DkW94EE_OQAfD`6 z{8U#k4y%pIq;yg`YjaeNHI#u1_*imB^5UNn;HRz9Vv+&G(7iESaex|f7_(10wk}%{ zw>>kJW=AXep|RMCe+`SeA`P1Mfkh*{6?HIiWMI|30!k@|GFU*J5sfJB_fy5OO)61rJ9^k_)^66Ox zS9aGzX64MpJDyvaL@IK#^>lSS$N~Z|__l_O{ z_aWni8(Yqvs3(9x=})4D(jljgQuce=AbkcOvG*lRcGYZ{y#?;mcCl+frrUz$(9(n~ zu!dt`_zdUKZdNF$ZD>1+KP(Z;ASgvD7piv-ca$ zsGX!J*F^XS)esUNximeS-6;2ZuG2)c_cTCmO`M>{ZS1rg9PiGo2qo|5mbAHrnlHa-!Ml&1i~(C6@rf*St>ic`0Si!rb*DqtwMsQ z`JDu|&JNENwH}pdlN+4Ng1HQ=brxvRbi)EYTnizeQ8ylG^hF`_QMO!R`}77b3go8f zt*McWbo^@TbL@+kJY-NoMXm;O?JMiKqPmbXEn|l`crFq{i`eD(MAS7POOl zNFV0n8}2AZZ%pQ%=9PDTKaX|+3=^~!FkvxD*=J%w;CC_~u16<}mCjV|t)Js-9o;ba z)c@`d)&z{=8^$z4hk7}pN_q5o75gErN6{3Y8sCg^sM{4eR#5!V4}HL)kYRB}R*V&G zZ0jQi!(3$eSV|s^G0&UTn<1_lP&Ft%r%-OPgT$NC3Q##SKRSZcK#hApR+A<3b-Uq4 z8gq2RkHCx5G;HB8xC5K29xUF+;zIH@Wu@M}c4$5b%SDzLnh#!LBp~sEL1j1Y#@!VT zdueGO5s~j4=VU07M>lL6J(T&Za6TW6rE~DZ&#G)E_}n(C_N}8lF7y+RWt69#$k~|9 z_(n3ur;CBd2p0sF&2!n166L@lkCeUri@t!`M@hR8bJ=yZfd5;e{#Gp2Ux*E8l31!7 zS-bn&+^-ap`xdQJg_q>0N(|KCzVTQZW_~2CHSl319JldYxnquS@Ks*}+q~(ICJMKW zJR57zkd+U8&P)01X&pJzUXU~%>@33i3r!}SXT>C!qwU-4D+ zs6wu{po*NYe9Y3Ce#qD=G-lmL^A!G^UVC9;6|c`Fomn-5ZJFvX`p~ia(EJuXs&^34 zhHK0Ky8-~#cMwsGg7^U!Yoyg#wuUq7JDcjpJA#j=brf{7_=c-qQ^lL>*>aOVHk;Ma zG*YldoCACu>zvAVFo;KAG6l`fViWoPEBGimzXQ)48lMo3kI!dYj!MK9+z)7p9O>Qu z#Jb=6r#)WV4bP?cXoH8GIUtm$pfNt#x_u)5Vw_V4_vyVk>_!OhE%Jw;c_MZIW*E_|q|Epe`sP>%e8gcu@R7UD1RvH5fa);1($IU? z@Tu|J<;{=y!T>GR{E`tCSMtWkda~J&e&JE8 zB^2dIuGH}BoI_SU_?AjBqoRAZ$#~yW1>7H(a+`5ol|ytaMC)B_X-3@;iSk@Pc{>Gy ztXbVf{PZemLsVxZfpwnMY;rrmX=QKJFZ)k3KaqJrc;6LoAQ9nL{^!+!t=8myfa(5K zO2y4~*;!!WdiNt>BC|Da*#>HLkD@lHvI|q+BgW4hb?Rt#~Ze{n?>BEC>*gMz`B*Cl z=>T^p-KU1{AhoUSGpa_ltgR-_3P7vcv6c!md=BtcrtGnnwOi7aQtK-7Qx5KHl~N z+wmN0>tSxc2sKS}wZwGLnrdd##^*GKz*D2eB=Xb2j!ZyWmXQa6$E)PPQ@;6K(Y3qZS67Q9IhxmfVPgDmJ`nL9* zOJtJ7#q#8^e|9JYDk*G3K{?M+K0oUW@~{+4X*vgFInA6vj`OtL?HlB$SHW)!V2E3Jy{K(EL4iHkdbl26GDiCmLArpU?BMY-dDt;< zWDEql7H4Ok0A&1bgx`4|YGr38=Qg4tvficx@yysx#g4ISUkY(y>R0(m>jp8S*|&c`*J#0V+>;(C@~t z;+B=g55wMdR90;4P2#HJUb3Unm|f_qg$Vo?B9Q#YNgc&Ky|RQL%5%N8%_FSg$@MT| z$iU{rMlC>=Ss}gmWJ!G?x1*q&B+_I*x02PsbHBKrJUfm&b8p-5+~-SjpC;a3kTnuH zR8|`F0{k$5b7D1`R5$hI#}LA!3i_@KudxB#Dth1rZ|j^h;e~;525z zWS!!eoz@(HaKBAN$daD|uebW$q(k83nFz$8z}N5}$Z<58_qiDxTlRB`s=|nFvN%@y zg#z&!opuuEym#bRT@7dqK<#7FVLZtgVL!G+fBK8m&_O=nreNsY+K92;t+Jmb$n}2I z>oBZOc5G$0Zqj8)*~sqrQ8^9qdUEM10c_(pja@TnjJW$}C2ZYfRjeZ=f!kQe(olM2 z`ZyKu_iC-8up}(QDgYBHL_vphJ*Nb@lJEOS_6Jqp(e6QXvNuSq=D#zDZ1j+a zM+SF{F8Uhlt@{ab07=ECl~Vrha>(wmi45Zj5L8%j_2d{&KMG5#lH~8KQg#p7DA#Te zt;q7~%T_IquI5#|pJ-TgOHor*qS=q!8a?sr$csd`4zimET(76+sPl2~xNL6F=uGg; zOpm8m+w$Q$y>px$u7$9_g{nEhwN&MDu%`Fr^SFf?@@aQ3QQp@j8WnnqR!>MSoI+-G zZIgO|ap&*n^;fP&4$CX<2Mj;&H%-YS9SAF8w zG9XsuzbA!mNkZ2%36qXf5N`Gm?RVIu3qI_y4L&NQn@>M_1M~shZ3|R9!|A+cz$XrR z{2d~fP38xWVjH~gSP3}bn{K*GIi65Ug8jGI+vew;8>^Lb8KX!Ja~Ll9UX2iTW#S|N zZMa$wls`{zr&FE#Ai5KSt79&fJ-w5>b9cD8aQcT0+g**lo<@Lj>{UCyP2@KnE$A4n zHWuw{_tAe8sZ&}DJ#RZ0$jf{a z^_L75T%XS=Fc+OZj!0kTUMjs*hEn=&nx+^7}0k-J;QdQyR}RhXPvJXaXt8h7b$ znQ2&ZaK3G~<1){roKEcLculv45Z%r;q!;ggpB}8X>obn_Do(mUm_X^|(U!^BmiOMW z7FRiO!>?4F{MSilrK$7x0{3dWzNwXWp3mOpW-`003d7_R#Y;YU=dGJ>F;oH!pD|yO zU=nF%(I7+KZn_?RZrRL(tnMmM3%Y7!6!7un6Hgj~{TV>?r}v^u%y35a&iOQ7CHQbM z2@;}n;-6O6-erQ0+N+!g4U6Sk$-?Ch;%gypN6KOXh%ROd>qHboK zTYD=B>7a7pBVXxv!N>C7f=>2(yRBztF5o+u{(Ns>*ZzD!p}>0Us;%c7uP;&Vmp1{{ewq?o0oS$@&_u4zKzR z!g0PnwtG%}(Wd)ZWVF)8)+~_F{&)#(6oz=L-pM+b&GgLe1EbFpTb5{qr{f%Wk-O33 zn=;%&hiSkm>Q&1}`p#ZPJ>gGte$(-G^n6zB9WztqDEsmV>PxRfb`T*kiU@`vQ-EX~ zvviBb=9=KLG@0h&I9C_eCTq#j&%XX*>2o@OVXUsOAnaTGd{eu6sqrLJeCH6D^faHC zB4=vcwOTIBqQCyiBGGi~lm}%-n3|98t>)uv#b@gJ{s=aLZa!hju3)Iamlv$ZwOe^l z_|`>4t}HG|azwh?GwD{ALbWK4`{*dw2eD-gD4zJ5DE1@;Sw)UMo*MY0Jm0uUx3D!8 zk^}as1DP2=GfI0$zw?OhqZsXK5F3bon#P%7qmAtJJ@yw_$`2@*3IQWF3j{g3Zgu1f zkmtB1i94`IWC<6Ns<3oS;y_#pRg<^o^aV_gHDCl)5LueD7MY1r(iw9;M*J!>b5{Tp z!DPJE2r#>(PP)%<#6_0cGmEZb+ zIP0YhSy>jHLCQf;%x{940t*||GeNF}i5<->B9!DNzpHc7-;>N(CoHfC1zTSyI1)}( zH33QtJ@}reS(`J~LZ=diJmRM~ZY&&9zgCV?JM7Zeb|6&DC(=((K0)7ph`;k)KN6YT zy&~I_Mi3&T;3)+i>>p}6$*y9|HH#6790Fy2Y17zE#w5#Z>JKK*F0w|@7#T^PtgPC~ zFNz6ZkY_C!SZBReo^$nMQX0P(9}oZMwc_qZ=>Hjk?mfj!F6?KqS+JcExcIK42`DWU zlI=p_Pb{=d-svvMUbS*#7+Nxpi37x48sH^a!9AjrYFty^MR1QTW9=yUtwKdiO1-4; zF39UoaY(#DMpKY547tXt4OIo=VH4q{Q;#Sj&EHsqYNvI>VL{`|sp@#kt{6FRxwI#*Fu#O9?y1ffo-?|fJL zlfIL(z8%_$%ZY`u|MVihyWkvDfLWPpdHV5!ku(fjAqWF}Tp#wBpqVjA-oA6Y8sL89 zkVCj*Dy7u%tLkeiO-IqcRF+J4xfAe*1_AR?^7mmHLfgC?L3l_(_XQt4npG0-rj)7W zLO2E`^|<;j?I@aqmK+=VolD*MVi#W!PX?npTWN2JI~$8jr8$|gGVw?~v)?L#mh&Yi zAXoI8f+8}kuh=%GTBryT;!j*`P(cfPaOqOHqP{NXyZN)(CBjtykQvbnW$tWATCB&5 z`RJ7TTe79iS&~su;Ze*2(SR!=tx2x6wi6{W!M82JLwk=o^jF8-36r+S;7BhH(ZXzp z;3;f%ZogB6*VI$=0?(6hTj2yARmnzY&6%IBRzb@r1K9qN4Li?90?Y zf;A$-hu+I=8St^e9pHnAEVh{c4?cG05Vf&=L2OGthFy$p1T`FZvz4T?*Hr#w9U@p? z_t0^HI*Yr-_n(wT;SiCraOI0#q*4=Cgc&li=KfHB(t7@H=@1_V?@N7w`2^Cm(5R_MMr^1q^g8EE6vsfmmcIT@Nue8T}=$ba;jI=8>^qSN}E$czSZPp*Nqs3_O2J@ zN;7U|IP&mFcijkk|Geo(xR*klwA?iOYKNFfZEpI8OqTsYVUR}ka45_M^T^_x&Ab|; zJA1d9^#p}E(i62^a%J?N`+HquUm&bGqG($H4^s*Pq@l4r6>1uTLYs#M%~BUyF5DQX zMK6)k612B@D7c7_A=4aKy+KDx7VDbqSyvYi+)5fuzX5(<1NoaPv?toEASiQli@%kU z4|p!#WbJ!f{QOHGeL(L9th4mPEDpUy_ArC?Rx$NMv;f-MhqJjHB(rS6)O`tX(nUPl14L(i>wyQ)= zpplxtJ-K*{UhRqrtwGoGAS?#LpHTTJ%ecsnK9tuWKnIsDbNc~Gi+RDK7ih~hJl>n@)U#8C@DoUu1_@KJ#`O=C|s2JFhr zOGHoUx1(C~@O6&tG0eW|jD4h;~81A`hbr7WlwPeRwc49}KEATX1M@s-S9tutoV-rN2)B z2*%h@J&{(9Q#K8SG6`!}PaEb)uX)aMJ>`FdZ!6>RKB-W!U%;UZqu+m+1wc;;rFfQT z#ef0skKI&0C7qbWn;NY@_NkgG_Pxb&H_1SZ?|W~1H3R2D=ih{i75RVxaykE=GB|t9 zI1iol0n=t|GSwfykvidLlxYHg)b#mTr@A68aLd_y8$Yv7adelZ4Ger*!LD*QD9_80 z(dL@U+X2R@Wt0QelDn45z;v}<%1*L2GJ;}!B2))(^r0R@yO(y>^t(KxJlH*-Ow8PQ zuYEY6_`JemnTG5!!?T9r9e*gpoC`}az*|oC;`YxNProZpST1sFIp{sE$j3RP#*XiG zQy~%wR$zLK^H&aB=x1Y~29FS-^_(Y0@z%<_-cf~<(6v5qcB3W9OA7aC3}*x61KAj;RJ>xO8cl;EEhekaVDzT=}KbasEP200kFd( zszNnVF$f4AqTFsJklwkOej#NI=y-5fEKD>gz(-jVQ93*pbPC&Z_fc~c+r`{LmEgJ3 zZg*9+VaUho(2tfRgJ={P=YS{TMaG2N^bdDwHnvJ{gb@PZ142gbBJQTucF6#b3c~YJ zu59iS$*p{U>9*h9e4h4&^6H&%YC@Au)~uh=0vPd9gjLw``n`H=n0o4|ccwwXM82SG ztCh@ju#rZCba}VEMi^ZQ4@2*x7w$UT7-ae+J5~ri$ql)ZBH>Rzl-F~YsQxp%P9WYd zcZwSU$1h@kwkA7S*ZmP+bByG5crJ)Wk=Q6(V?BlDcorJynLeq;bNo3xIizssec`iU z$Q;3Gr1g_Q6cVS`^focCs(XHFvzp;bDnUsr*Zz8Z=SvNVGaA+xAvtZ1dzN0x@UE^n+l@++AmF{LHH^;IF%G>*_rl>L+Rb7GDq0QK80Czk9hapz{!*p5EC!dz z5*Gx0ptXDV`nM&L@>sp~K{p$?4>>NPgkil6@b_&+jPt@Qefc%M)DWDr7S4G<9C(tgz zmpe^`q6c}rVL*2l{heoQMyYX2)Fu5Y%a2rQWI2!(N_aqogVc}XHSX`d zM15&YTue}CR1)OKkoUP792Rp%(M&DNOo9#TE=kOXhe?b_N_j+#+F`TW@ad$Piwyt+ zbH{pzaWtZO!XJv~=-6SG6)H+Ian6n~>t3VSb&&vEt8_T8ildzQLI1t2)#T%fl;!$F z<$IqS(&-?elT3?q(S*;65O;oS$O}y>5GJI{u;PI28}+)$@G1e?5+&_S!${OXeQ}a% zPCQ~7&cxnv^{PGh}aWm2opQv4!B{)ZClvI z!Mkmhx`aL|{+2V`&z&S=K-^62X;a_*`Wv1KyYxuFDRJIWqdVPpM|9}3E13zwNSyM| zgOt`U?Op?~=e;Hgo4T(D{W=#Xd-$Z;rcxRz*i%S;%u-gej)#sy^>B z6jImgx#}VR{NQ=v@b_cd*LOXcF3^(0N4_pHaLWo$yLsK)*LT5J_?Zx#1%ooHHvD|~ ze$Ldh$nDhmyCO!q zpYK*>NN%=|gdL^A;tFtdP67ctu0ao&JjyyRWkG#R1Cz*fc=Br~GaOtE0%Zgvr<+dI zegX-WF&LJ7%GpUaDE?sn3lB6~-qzcpRoAx_*!Fg5PV0>?{qkA1aFa~RQkh{OVT__e zI1{~430`wv%G&*TsJ0mT&SPA#ffpQvB&Z-b&JeCeq@nbk7$OHVbUV`WvxuR^B&tgP zto1|*q%=MdzOrhhn2r{?10;{>i5S#WcXNn!7y^=%Y}|)tHfRk7`@k@3@mbEm#*8F= zZk(Wf4nsFI883-r|e6a=gH)pa7s|KShd~AX3EIo z%V77Ph)Rm; z@ZB10oNJFuUC1lz07N*DND-1BY8m+0A*!SekSwQ-U1z3X4-1;_z(RXQGi5N=qDXzz zXd^XfUs}3Uy(OK{5LOQ@GWj;+^@Dq!;j7gnEY0YBcAWm(_{d+1V@P5#?%-Lu7Ug!#aOEvA#Ojt|e2tGfg*!VICNZ`V*K_tdv&4L1xju(=vL-vb!60Ol9*(jPcPny z7B1i=IWh8>Hq76BpixKfW5(g2{7!3gMqneCSomo$zf21k8|5JU%@Fpw?s+ z?gs2R2%{U4Gv3X`sv_bXIbm}*H)gr&b;N+W2a|nR9!@;9pb=cjaNYzg_+FN52;_z20c94**Y6`GkkzL76;vyVmJ%|-soF$-t*rIqe50u1KC+=DxVb z_A1OsX%t_)0k6a@my7RSo$c^{Rmeh_WnBI$*b42!6AA%1Yra+*k5ig%Qm`VZSEjP- zF60S2-;{yT%^^qUFY7Kwa9qbX5h`4Xa86NRb((@ZThOMoSyk26lrKLGZ^oPn3_ZIs z{6xmKaH*IJ#+xsFIP1Debb@P!Ese0G4v^9Wr#!Nr>a<2SpwCEttnSZ~e~i)R+w(2{ z3gy#I#%Sm!6R1F*B;9O=BqTEROa13(o~}@+V{hMlKFF#yk*M859%bw?7Eq7m37i^C zLYQpMC@mmLW-7UZ=ulw^TyM~U$IWCCrK(qVO7`(axR11+B=NTPzjs23dOlnX-g^Zo znr9sdu?4&&OG}q%@4N|niMpyZ!b*i(6B76?G`3lhYETbEzOB{TMv-tMo7=I{U>>w_ zhbW5p{LdRqJr)@t3d2OEmiSV~5h^WxNo}d=Ix>B!ZJg~Mk>FX;7P?xdBBwZJKFNyq zTA><}$FDMrErBrOzbfTpT31Lt6M2$rkKF;O;A7-MySQLu%>oktuK&u$i-((e zPMes6e#8D?5=Cdw2^s^7&nhf|C^(}N9!9qa3R^1o*;vjsgtJocZOp}d`D!1i=ZbXT|K!4ZalnfV31Wd<@OA{@Vag~f}EZBYl zy&y&%+XJi>4!}BVhS+2%^794_H_i=XuZJ=;BqJp#`PhXR4^r8?E5Z_4&tpM$UvWGE zKr=7Hl=^^hoYI&9lej=o)>_(cwQ9x*>9dGGXLHY%y)rViNTDik-c-F;l@<*`R{9Lj z4vQZBPxx?8H%<)ob)&m?-1eOx2y~%TGl#eg^g83thU5| zL@_tzA-!QFpA!W`r(klcp61&8XK^kldmtJkn|#@>9A>flb;G1v9cK!$Hggki z>-HorN+wfNRVl}>uhO@sls((yF{m2G2a4mg3Xye$7Dn`;>HKSZTuG7u|FJ&M%LSC} z=h%^O=z_D@qrNo~XP3YSFWgm%?3c}atuZ-M%T1&Wb?<1Ra;*KfcOA3>57~viAsr&? zpgdILc8=<^#=>x>YvrU#4crnZBcD<+Ai^lgh-=aZAbetXFOsNixYvp*x+Lw>6UL_b z)XkrK9v`s3AsijQMyc9JDb8%oRF@k$J!p!~Q1C_mLP$FPyG2vitK}8Xo-%kvGn>Uv za*|FWZlG}>X*Sy&JZ(5Bbx2VrvyStKb>IJLI~!d$VHgU-)b;%zc~Z&gXMb~nRd+|5 zZpp9hI3XD0EK=VAG9@%E=t0JnXWe+(Q*I204iAS~;9U`d(&>I2h96B?_Ctnc%RSH< zRlY{QIF^VXBTCc{gQ5UV>u%(9`apE1h6#kC1@-m>lEQ=3D2mJ zB~Dl++(kaAem)bHkswk_!&2LkvLp7`XBXqgzvE|J#vkwJ_4lG*W>eVMy*`EgHc0&DduVIQr9r3DKqFou$!3{A~P7mu+963vreFdc2>4b9; zqM7nj=$2F7GVrn>(>c8%DL{xcpF&a&Dt{4d+~<{dIT--L+2zVqtElo`jXv==R)5A&d4%6^j&9F5-Gi zPcC^9L3K9I*>XG97f!iBj~I?v!LvM3yp(w7ZY6qbkNC|#4A%SS06|sZBzVL)(+JqY z74dPLEjPhDO*j?-TroUteBh<}IcPY4Jy~RZ5=PGc$zuEhQthL=)Tvafo8yG2?(fs+ zl7R$p!QW?NSxQ7w*GYyGY)xSnVgue%zBy*nS9OO)*L0Z2i=+Ih-M7`q) zxfLr0XB;niFO*4D8|C*}=C~(j15*jRvzAgQ8%pdCGk5H z88cMRUVi_WVkrVoA!2#7$X*;Ajtud6TX)&Ij9Dc-`Jh096qZxIukKWrA!WDV^fm1+65|f zp*+G^?xr^Vdj>hq@bN`MTe0U?pDpx^2PdGf(Nd2(x@(Pt+GPW%Y6;$u+G)|PViiXZ z2SM8vmI)19^oovwDSrFn!oyV3$?zQbrr zni*_Dl;p&_I+^$Z##Q4|Z}o-7-NoU*T5ljmoq!j!0wJGkW6vNDxOw=ZsV21KNC>nb z_U^5`ohcgr9;W?TCAPA-|AL$Pxhs=*hSGsNe2ZKu95GvYaE~|MpKN>^Rgqh+eXqrmZ zTf@FtvIH^9K1><($~t8M3DhSm3^VuPfjL_S+shx60zIAGgquBANB^|q!3UR52Xw(P zRW(pg5=0m+8GgJ*t2|B{hz(%Dx=(%MZ)TO-#$px_!uAR-hz@H&?O#jKO;B%_8=nEm zY``LQ0SO?EYu(H#w;+MXs@#C{Jb0YSC+WfAeEQ3tVTC*{3OQ28?et^gMA? z$q2TS?Cl0C!Wn(5#>iLSdX80ZaO7$9uTq)s?^nC*y89Z%Xc6KC6jul{03zDRS1f+u z2Z4UM9sxJy3zFdL`-x`x_lTx;u&OL<2Wr9kMs`lw(gx5IJ}g`V1G~xhh~Ea? zAoKh$_QzS2B$}QJMrpan7}EC8 z^Dw3klA0l*o`R!CwqD(%FJ^|pwOarss3OhN4*@aW!j*7_3}`mSc`~U(x&>2Pao;qh kGv8WX#~!A{@#W<2Kg+ZTDx~afVE_OC07*qoM6N<$f&q~-3jhEB literal 0 HcmV?d00001 From 6b39b344d8c9a5b9202dc99a15b57af5eee20f26 Mon Sep 17 00:00:00 2001 From: DaydreamCoding Date: Mon, 25 May 2026 14:26:11 +0800 Subject: [PATCH 08/38] =?UTF-8?q?feat(quota):=20=E7=94=A8=E6=88=B7=20?= =?UTF-8?q?=C3=97=20=E5=B9=B3=E5=8F=B0=20USD=20=E9=85=8D=E9=A2=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为用户在 anthropic/openai/gemini/antigravity 四个平台上提供日/周/月 三个窗口的 USD 配额管控。配额语义:未设置=不限制,0=禁用,>0=美元上限。 两层模型: - 配置层:系统默认配额,以及 email/linuxdo/oidc/wechat/github/google/ dingtalk 七个鉴权来源的默认配额,存于 settings,以嵌套 JSON 整体读写 (系统 1 个 key + 每个来源 1 个 key),整体替换语义。 - 运行时层:user_platform_quota 表按用户记录实际配额,与配置层解耦。 后端:新增 ent schema 与 140_user_platform_quotas.sql 迁移、repository 与 service 端口、计费链路集成、管理端与用户端读写接口。 前端:管理端设置页配额编辑、用户配额管理 Modal、用户 Dashboard 展示、 中英文案。 Co-Authored-By: Claude Opus 4.7 (1M context) --- backend/cmd/jwtgen/main.go | 2 +- backend/cmd/server/wire_gen.go | 14 +- backend/cmd/server/wire_gen_test.go | 2 +- backend/ent/client.go | 185 +- backend/ent/ent.go | 2 + backend/ent/hook/hook.go | 12 + backend/ent/intercept/intercept.go | 30 + backend/ent/migrate/schema.go | 52 + backend/ent/mutation.go | 1513 ++++++++++++++++- backend/ent/predicate/predicate.go | 3 + backend/ent/runtime/runtime.go | 51 + backend/ent/schema/user.go | 1 + backend/ent/schema/user_platform_quota.go | 113 ++ backend/ent/tx.go | 3 + backend/ent/user.go | 20 +- backend/ent/user/user.go | 30 + backend/ent/user/where.go | 23 + backend/ent/user_create.go | 32 + backend/ent/user_query.go | 76 +- backend/ent/user_update.go | 163 ++ backend/ent/userplatformquota.go | 301 ++++ .../userplatformquota/userplatformquota.go | 202 +++ backend/ent/userplatformquota/where.go | 799 +++++++++ backend/ent/userplatformquota_create.go | 1513 +++++++++++++++++ backend/ent/userplatformquota_delete.go | 88 + backend/ent/userplatformquota_query.go | 643 +++++++ backend/ent/userplatformquota_update.go | 985 +++++++++++ backend/go.mod | 4 +- backend/go.sum | 6 +- backend/internal/config/config.go | 7 + .../admin/admin_basic_handlers_test.go | 2 +- .../handler/admin/admin_service_stub_test.go | 4 + .../internal/handler/admin/setting_handler.go | 109 ++ .../setting_handler_platform_quota_test.go | 188 ++ .../internal/handler/admin/user_handler.go | 315 +++- .../admin/user_handler_activity_test.go | 4 +- .../admin/user_platform_quota_admin_test.go | 301 ++++ .../user_platform_quotas_handler_test.go | 124 ++ .../handler/auth_oauth_pending_flow_test.go | 1 + .../handler/auth_session_revocation_test.go | 2 +- .../handler/auth_wechat_oauth_test.go | 1 + backend/internal/handler/dto/settings.go | 5 + backend/internal/handler/gateway_handler.go | 49 +- .../gateway_handler_billing_error_test.go | 74 + .../gateway_handler_chat_completions.go | 4 +- .../handler/gateway_handler_responses.go | 4 +- ...eway_handler_warmup_intercept_unit_test.go | 3 +- .../internal/handler/gateway_models_test.go | 2 +- .../internal/handler/gemini_v1beta_handler.go | 4 +- .../handler/image_concurrency_limiter_test.go | 2 +- .../handler/openai_chat_completions.go | 2 +- .../handler/openai_gateway_handler.go | 6 +- .../handler/openai_gateway_handler_test.go | 3 +- backend/internal/handler/openai_images.go | 2 +- backend/internal/handler/quotaview/helpers.go | 104 ++ .../handler/quotaview/helpers_test.go | 133 ++ backend/internal/handler/user_handler.go | 51 +- backend/internal/handler/user_handler_test.go | 58 +- .../user_platform_quotas_handler_test.go | 212 +++ .../internal/pkg/timezone/timezone_test.go | 26 + backend/internal/repository/billing_cache.go | 171 ++ .../billing_cache_user_platform_quota_test.go | 134 ++ .../user_platform_quota_adapter_test.go | 91 + .../repository/user_platform_quota_repo.go | 416 +++++ ...er_platform_quota_repo_integration_test.go | 269 +++ .../user_platform_quota_repo_test.go | 103 ++ .../user_platform_quota_service_adapter.go | 206 +++ .../user_platform_quota_upsert_test.go | 148 ++ backend/internal/repository/wire.go | 2 + backend/internal/server/api_contract_test.go | 16 + .../server/middleware/admin_auth_test.go | 2 +- .../server/middleware/jwt_auth_test.go | 4 +- backend/internal/server/routes/admin.go | 3 + backend/internal/server/routes/user.go | 1 + .../service/admin_service_delete_test.go | 16 + .../internal/service/auth_email_oauth_auto.go | 2 + .../service/auth_email_oauth_auto_test.go | 88 + .../internal/service/auth_oauth_email_flow.go | 2 + .../service/auth_oauth_email_flow_test.go | 59 + backend/internal/service/auth_service.go | 115 +- .../service/auth_service_email_bind_test.go | 16 +- .../auth_service_identity_sync_test.go | 2 +- .../auth_service_platform_quota_test.go | 157 ++ .../service/auth_service_register_test.go | 132 +- .../auth_service_turnstile_register_test.go | 1 + .../internal/service/billing_cache_service.go | 305 +++- .../service/billing_cache_service_rpm_test.go | 2 +- ...billing_cache_service_singleflight_test.go | 18 +- .../service/billing_cache_service_test.go | 20 +- ..._cache_service_user_platform_quota_test.go | 595 +++++++ backend/internal/service/billing_service.go | 34 + backend/internal/service/domain_constants.go | 36 +- .../internal/service/domain_constants_test.go | 23 + .../service/gateway_record_usage_test.go | 1 + backend/internal/service/gateway_service.go | 191 ++- .../openai_gateway_record_usage_test.go | 1 + .../service/openai_gateway_service.go | 17 +- .../openai_ws_protocol_forward_test.go | 1 + .../service/post_billing_platform_test.go | 81 + backend/internal/service/setting_service.go | 175 ++ .../setting_service_platform_quota_test.go | 344 ++++ backend/internal/service/settings_view.go | 3 + .../service/user_platform_quota_port.go | 50 + backend/internal/service/user_service_test.go | 18 +- backend/internal/service/wire.go | 3 +- .../migrations/142_user_platform_quotas.sql | 36 + deploy/config.example.yaml | 3 + .../settings.authSourceDefaults.spec.ts | 165 ++ frontend/src/api/admin/settings.ts | 63 + frontend/src/api/admin/users.ts | 77 +- frontend/src/api/user.ts | 14 +- .../admin/user/UserPlatformQuotaModal.vue | 283 +++ .../__tests__/UserPlatformQuotaModal.spec.ts | 245 +++ .../components/user/UserPlatformQuotaCell.vue | 61 + .../__tests__/UserPlatformQuotaCell.spec.ts | 74 + .../user/dashboard/UserDashboardStats.vue | 151 +- frontend/src/i18n/locales/en.ts | 61 +- frontend/src/i18n/locales/zh.ts | 61 +- frontend/src/types/index.ts | 8 + frontend/src/views/admin/SettingsView.vue | 136 ++ frontend/src/views/admin/UsersView.vue | 90 +- .../admin/__tests__/SettingsView.spec.ts | 171 ++ frontend/src/views/user/DashboardView.vue | 9 +- 123 files changed, 14220 insertions(+), 232 deletions(-) create mode 100644 backend/ent/schema/user_platform_quota.go create mode 100644 backend/ent/userplatformquota.go create mode 100644 backend/ent/userplatformquota/userplatformquota.go create mode 100644 backend/ent/userplatformquota/where.go create mode 100644 backend/ent/userplatformquota_create.go create mode 100644 backend/ent/userplatformquota_delete.go create mode 100644 backend/ent/userplatformquota_query.go create mode 100644 backend/ent/userplatformquota_update.go create mode 100644 backend/internal/handler/admin/setting_handler_platform_quota_test.go create mode 100644 backend/internal/handler/admin/user_platform_quota_admin_test.go create mode 100644 backend/internal/handler/admin/user_platform_quotas_handler_test.go create mode 100644 backend/internal/handler/quotaview/helpers.go create mode 100644 backend/internal/handler/quotaview/helpers_test.go create mode 100644 backend/internal/handler/user_platform_quotas_handler_test.go create mode 100644 backend/internal/repository/billing_cache_user_platform_quota_test.go create mode 100644 backend/internal/repository/user_platform_quota_adapter_test.go create mode 100644 backend/internal/repository/user_platform_quota_repo.go create mode 100644 backend/internal/repository/user_platform_quota_repo_integration_test.go create mode 100644 backend/internal/repository/user_platform_quota_repo_test.go create mode 100644 backend/internal/repository/user_platform_quota_service_adapter.go create mode 100644 backend/internal/repository/user_platform_quota_upsert_test.go create mode 100644 backend/internal/service/auth_email_oauth_auto_test.go create mode 100644 backend/internal/service/auth_service_platform_quota_test.go create mode 100644 backend/internal/service/billing_cache_service_user_platform_quota_test.go create mode 100644 backend/internal/service/domain_constants_test.go create mode 100644 backend/internal/service/post_billing_platform_test.go create mode 100644 backend/internal/service/setting_service_platform_quota_test.go create mode 100644 backend/internal/service/user_platform_quota_port.go create mode 100644 backend/migrations/142_user_platform_quotas.sql create mode 100644 frontend/src/components/admin/user/UserPlatformQuotaModal.vue create mode 100644 frontend/src/components/admin/user/__tests__/UserPlatformQuotaModal.spec.ts create mode 100644 frontend/src/components/user/UserPlatformQuotaCell.vue create mode 100644 frontend/src/components/user/__tests__/UserPlatformQuotaCell.spec.ts diff --git a/backend/cmd/jwtgen/main.go b/backend/cmd/jwtgen/main.go index 9386678d..fc8a00c4 100644 --- a/backend/cmd/jwtgen/main.go +++ b/backend/cmd/jwtgen/main.go @@ -33,7 +33,7 @@ func main() { }() userRepo := repository.NewUserRepository(client, sqlDB) - authService := service.NewAuthService(client, userRepo, nil, nil, cfg, nil, nil, nil, nil, nil, nil, nil) + authService := service.NewAuthService(client, userRepo, nil, nil, cfg, nil, nil, nil, nil, nil, nil, nil, nil) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() diff --git a/backend/cmd/server/wire_gen.go b/backend/cmd/server/wire_gen.go index e39a645a..465f5e25 100644 --- a/backend/cmd/server/wire_gen.go +++ b/backend/cmd/server/wire_gen.go @@ -63,7 +63,9 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { apiKeyRepository := repository.NewAPIKeyRepository(client, db) userRPMCache := repository.NewUserRPMCache(redisClient) userGroupRateRepository := repository.NewUserGroupRateRepository(db) - billingCacheService := service.ProvideBillingCacheService(billingCache, userRepository, userSubscriptionRepository, apiKeyRepository, userRPMCache, userGroupRateRepository, configConfig) + userPlatformQuotaRepository := repository.NewUserPlatformQuotaRepository(client) + serviceUserPlatformQuotaRepository := repository.NewUserPlatformQuotaServiceAdapter(userPlatformQuotaRepository) + billingCacheService := service.ProvideBillingCacheService(billingCache, userRepository, userSubscriptionRepository, apiKeyRepository, userRPMCache, userGroupRateRepository, configConfig, serviceUserPlatformQuotaRepository) apiKeyCache := repository.NewAPIKeyCache(redisClient) apiKeyService := service.ProvideAPIKeyService(apiKeyRepository, userRepository, groupRepository, userSubscriptionRepository, userGroupRateRepository, apiKeyCache, configConfig, billingCacheService) apiKeyAuthCacheInvalidator := service.ProvideAPIKeyAuthCacheInvalidator(apiKeyService) @@ -71,7 +73,7 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { subscriptionService := service.NewSubscriptionService(groupRepository, userSubscriptionRepository, billingCacheService, client, configConfig) affiliateRepository := repository.NewAffiliateRepository(client, db) affiliateService := service.NewAffiliateService(affiliateRepository, settingService, apiKeyAuthCacheInvalidator, billingCacheService) - authService := service.NewAuthService(client, userRepository, redeemCodeRepository, refreshTokenCache, configConfig, settingService, emailService, turnstileService, emailQueueService, promoService, subscriptionService, affiliateService) + authService := service.NewAuthService(client, userRepository, redeemCodeRepository, refreshTokenCache, configConfig, settingService, emailService, turnstileService, emailQueueService, promoService, subscriptionService, affiliateService, serviceUserPlatformQuotaRepository) userService := service.NewUserService(userRepository, settingRepository, apiKeyAuthCacheInvalidator, billingCache) redeemCache := repository.NewRedeemCache(redisClient) redeemService := service.NewRedeemService(redeemCodeRepository, userRepository, subscriptionService, redeemCache, billingCacheService, client, apiKeyAuthCacheInvalidator, affiliateService) @@ -85,7 +87,7 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { userAttributeValueRepository := repository.NewUserAttributeValueRepository(client) userAttributeService := service.NewUserAttributeService(userAttributeDefinitionRepository, userAttributeValueRepository) authHandler := handler.NewAuthHandler(configConfig, authService, userService, settingService, promoService, redeemService, totpService, userAttributeService) - userHandler := handler.NewUserHandler(userService, authService, emailService, emailCache, affiliateService) + userHandler := handler.NewUserHandler(userService, authService, emailService, emailCache, affiliateService, serviceUserPlatformQuotaRepository) apiKeyHandler := handler.NewAPIKeyHandler(apiKeyService) usageLogRepository := repository.NewUsageLogRepository(client, db) usageService := service.NewUsageService(usageLogRepository, userRepository, client, apiKeyAuthCacheInvalidator) @@ -143,9 +145,9 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { modelPricingResolver := service.NewModelPricingResolver(channelService, billingService) notificationEmailService := service.NewNotificationEmailService(settingRepository, emailService) balanceNotifyService := service.ProvideBalanceNotifyService(emailService, settingRepository, accountRepository, notificationEmailService) - openAIGatewayService := service.NewOpenAIGatewayService(accountRepository, usageLogRepository, usageBillingRepository, userRepository, userSubscriptionRepository, userGroupRateRepository, gatewayCache, configConfig, schedulerSnapshotService, concurrencyService, billingService, rateLimitService, billingCacheService, httpUpstream, deferredService, openAITokenProvider, modelPricingResolver, channelService, balanceNotifyService, settingService) + openAIGatewayService := service.NewOpenAIGatewayService(accountRepository, usageLogRepository, usageBillingRepository, userRepository, userSubscriptionRepository, userGroupRateRepository, gatewayCache, configConfig, schedulerSnapshotService, concurrencyService, billingService, rateLimitService, billingCacheService, httpUpstream, deferredService, openAITokenProvider, modelPricingResolver, channelService, balanceNotifyService, settingService, serviceUserPlatformQuotaRepository) adminService := service.NewAdminService(userRepository, groupRepository, accountRepository, proxyRepository, apiKeyRepository, redeemCodeRepository, userGroupRateRepository, userRPMCache, billingCacheService, proxyExitInfoProber, proxyLatencyCache, apiKeyAuthCacheInvalidator, client, settingService, subscriptionService, userSubscriptionRepository, privacyClientFactory, openAIGatewayService) - adminUserHandler := admin.NewUserHandler(adminService, concurrencyService) + adminUserHandler := admin.NewUserHandler(adminService, concurrencyService, serviceUserPlatformQuotaRepository, billingCache) sessionLimitCache := repository.ProvideSessionLimitCache(redisClient, configConfig) rpmCache := repository.NewRPMCache(redisClient) groupCapacityService := service.NewGroupCapacityService(accountRepository, groupRepository, concurrencyService, sessionLimitCache, rpmCache) @@ -190,7 +192,7 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { opsRepository := repository.NewOpsRepository(db) identityService := service.NewIdentityService(identityCache) digestSessionStore := service.NewDigestSessionStore() - gatewayService := service.NewGatewayService(accountRepository, groupRepository, usageLogRepository, usageBillingRepository, userRepository, userSubscriptionRepository, userGroupRateRepository, gatewayCache, configConfig, schedulerSnapshotService, concurrencyService, billingService, rateLimitService, billingCacheService, identityService, httpUpstream, deferredService, claudeTokenProvider, sessionLimitCache, rpmCache, digestSessionStore, settingService, tlsFingerprintProfileService, channelService, modelPricingResolver, balanceNotifyService) + gatewayService := service.NewGatewayService(accountRepository, groupRepository, usageLogRepository, usageBillingRepository, userRepository, userSubscriptionRepository, userGroupRateRepository, gatewayCache, configConfig, schedulerSnapshotService, concurrencyService, billingService, rateLimitService, billingCacheService, identityService, httpUpstream, deferredService, claudeTokenProvider, sessionLimitCache, rpmCache, digestSessionStore, settingService, tlsFingerprintProfileService, channelService, modelPricingResolver, balanceNotifyService, serviceUserPlatformQuotaRepository) geminiMessagesCompatService := service.NewGeminiMessagesCompatService(accountRepository, groupRepository, gatewayCache, schedulerSnapshotService, geminiTokenProvider, rateLimitService, httpUpstream, antigravityGatewayService, configConfig) opsSystemLogSink := service.ProvideOpsSystemLogSink(opsRepository) opsService := service.NewOpsService(opsRepository, settingRepository, configConfig, accountRepository, userRepository, concurrencyService, gatewayService, openAIGatewayService, geminiMessagesCompatService, antigravityGatewayService, opsSystemLogSink) diff --git a/backend/cmd/server/wire_gen_test.go b/backend/cmd/server/wire_gen_test.go index 5ccd67fb..a44b2d5c 100644 --- a/backend/cmd/server/wire_gen_test.go +++ b/backend/cmd/server/wire_gen_test.go @@ -43,7 +43,7 @@ func TestProvideCleanup_WithMinimalDependencies_NoPanic(t *testing.T) { subscriptionExpirySvc := service.NewSubscriptionExpiryService(nil, time.Second) pricingSvc := service.NewPricingService(cfg, nil) emailQueueSvc := service.NewEmailQueueService(nil, 1) - billingCacheSvc := service.NewBillingCacheService(nil, nil, nil, nil, nil, nil, cfg) + billingCacheSvc := service.NewBillingCacheService(nil, nil, nil, nil, nil, nil, cfg, nil) idempotencyCleanupSvc := service.NewIdempotencyCleanupService(nil, cfg) schedulerSnapshotSvc := service.NewSchedulerSnapshotService(nil, nil, nil, nil, cfg) opsSystemLogSinkSvc := service.NewOpsSystemLogSink(nil) diff --git a/backend/ent/client.go b/backend/ent/client.go index df20ddfa..06b53c78 100644 --- a/backend/ent/client.go +++ b/backend/ent/client.go @@ -48,6 +48,7 @@ import ( "github.com/Wei-Shaw/sub2api/ent/userallowedgroup" "github.com/Wei-Shaw/sub2api/ent/userattributedefinition" "github.com/Wei-Shaw/sub2api/ent/userattributevalue" + "github.com/Wei-Shaw/sub2api/ent/userplatformquota" "github.com/Wei-Shaw/sub2api/ent/usersubscription" stdsql "database/sql" @@ -124,6 +125,8 @@ type Client struct { UserAttributeDefinition *UserAttributeDefinitionClient // UserAttributeValue is the client for interacting with the UserAttributeValue builders. UserAttributeValue *UserAttributeValueClient + // UserPlatformQuota is the client for interacting with the UserPlatformQuota builders. + UserPlatformQuota *UserPlatformQuotaClient // UserSubscription is the client for interacting with the UserSubscription builders. UserSubscription *UserSubscriptionClient } @@ -170,6 +173,7 @@ func (c *Client) init() { c.UserAllowedGroup = NewUserAllowedGroupClient(c.config) c.UserAttributeDefinition = NewUserAttributeDefinitionClient(c.config) c.UserAttributeValue = NewUserAttributeValueClient(c.config) + c.UserPlatformQuota = NewUserPlatformQuotaClient(c.config) c.UserSubscription = NewUserSubscriptionClient(c.config) } @@ -296,6 +300,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { UserAllowedGroup: NewUserAllowedGroupClient(cfg), UserAttributeDefinition: NewUserAttributeDefinitionClient(cfg), UserAttributeValue: NewUserAttributeValueClient(cfg), + UserPlatformQuota: NewUserPlatformQuotaClient(cfg), UserSubscription: NewUserSubscriptionClient(cfg), }, nil } @@ -349,6 +354,7 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) UserAllowedGroup: NewUserAllowedGroupClient(cfg), UserAttributeDefinition: NewUserAttributeDefinitionClient(cfg), UserAttributeValue: NewUserAttributeValueClient(cfg), + UserPlatformQuota: NewUserPlatformQuotaClient(cfg), UserSubscription: NewUserSubscriptionClient(cfg), }, nil } @@ -388,7 +394,7 @@ func (c *Client) Use(hooks ...Hook) { c.PromoCodeUsage, c.Proxy, c.RedeemCode, c.SecuritySecret, c.Setting, c.SubscriptionPlan, c.TLSFingerprintProfile, c.UsageCleanupTask, c.UsageLog, c.User, c.UserAllowedGroup, c.UserAttributeDefinition, c.UserAttributeValue, - c.UserSubscription, + c.UserPlatformQuota, c.UserSubscription, } { n.Use(hooks...) } @@ -407,7 +413,7 @@ func (c *Client) Intercept(interceptors ...Interceptor) { c.PromoCodeUsage, c.Proxy, c.RedeemCode, c.SecuritySecret, c.Setting, c.SubscriptionPlan, c.TLSFingerprintProfile, c.UsageCleanupTask, c.UsageLog, c.User, c.UserAllowedGroup, c.UserAttributeDefinition, c.UserAttributeValue, - c.UserSubscription, + c.UserPlatformQuota, c.UserSubscription, } { n.Intercept(interceptors...) } @@ -482,6 +488,8 @@ func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) { return c.UserAttributeDefinition.mutate(ctx, m) case *UserAttributeValueMutation: return c.UserAttributeValue.mutate(ctx, m) + case *UserPlatformQuotaMutation: + return c.UserPlatformQuota.mutate(ctx, m) case *UserSubscriptionMutation: return c.UserSubscription.mutate(ctx, m) default: @@ -5341,6 +5349,22 @@ func (c *UserClient) QueryPendingAuthSessions(_m *User) *PendingAuthSessionQuery return query } +// QueryPlatformQuotas queries the platform_quotas edge of a User. +func (c *UserClient) QueryPlatformQuotas(_m *User) *UserPlatformQuotaQuery { + query := (&UserPlatformQuotaClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := _m.ID + step := sqlgraph.NewStep( + sqlgraph.From(user.Table, user.FieldID, id), + sqlgraph.To(userplatformquota.Table, userplatformquota.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, user.PlatformQuotasTable, user.PlatformQuotasColumn), + ) + fromV = sqlgraph.Neighbors(_m.driver.Dialect(), step) + return fromV, nil + } + return query +} + // QueryUserAllowedGroups queries the user_allowed_groups edge of a User. func (c *UserClient) QueryUserAllowedGroups(_m *User) *UserAllowedGroupQuery { query := (&UserAllowedGroupClient{config: c.config}).Query() @@ -5816,6 +5840,157 @@ func (c *UserAttributeValueClient) mutate(ctx context.Context, m *UserAttributeV } } +// UserPlatformQuotaClient is a client for the UserPlatformQuota schema. +type UserPlatformQuotaClient struct { + config +} + +// NewUserPlatformQuotaClient returns a client for the UserPlatformQuota from the given config. +func NewUserPlatformQuotaClient(c config) *UserPlatformQuotaClient { + return &UserPlatformQuotaClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `userplatformquota.Hooks(f(g(h())))`. +func (c *UserPlatformQuotaClient) Use(hooks ...Hook) { + c.hooks.UserPlatformQuota = append(c.hooks.UserPlatformQuota, hooks...) +} + +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `userplatformquota.Intercept(f(g(h())))`. +func (c *UserPlatformQuotaClient) Intercept(interceptors ...Interceptor) { + c.inters.UserPlatformQuota = append(c.inters.UserPlatformQuota, interceptors...) +} + +// Create returns a builder for creating a UserPlatformQuota entity. +func (c *UserPlatformQuotaClient) Create() *UserPlatformQuotaCreate { + mutation := newUserPlatformQuotaMutation(c.config, OpCreate) + return &UserPlatformQuotaCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// CreateBulk returns a builder for creating a bulk of UserPlatformQuota entities. +func (c *UserPlatformQuotaClient) CreateBulk(builders ...*UserPlatformQuotaCreate) *UserPlatformQuotaCreateBulk { + return &UserPlatformQuotaCreateBulk{config: c.config, builders: builders} +} + +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *UserPlatformQuotaClient) MapCreateBulk(slice any, setFunc func(*UserPlatformQuotaCreate, int)) *UserPlatformQuotaCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &UserPlatformQuotaCreateBulk{err: fmt.Errorf("calling to UserPlatformQuotaClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*UserPlatformQuotaCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &UserPlatformQuotaCreateBulk{config: c.config, builders: builders} +} + +// Update returns an update builder for UserPlatformQuota. +func (c *UserPlatformQuotaClient) Update() *UserPlatformQuotaUpdate { + mutation := newUserPlatformQuotaMutation(c.config, OpUpdate) + return &UserPlatformQuotaUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *UserPlatformQuotaClient) UpdateOne(_m *UserPlatformQuota) *UserPlatformQuotaUpdateOne { + mutation := newUserPlatformQuotaMutation(c.config, OpUpdateOne, withUserPlatformQuota(_m)) + return &UserPlatformQuotaUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOneID returns an update builder for the given id. +func (c *UserPlatformQuotaClient) UpdateOneID(id int64) *UserPlatformQuotaUpdateOne { + mutation := newUserPlatformQuotaMutation(c.config, OpUpdateOne, withUserPlatformQuotaID(id)) + return &UserPlatformQuotaUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for UserPlatformQuota. +func (c *UserPlatformQuotaClient) Delete() *UserPlatformQuotaDelete { + mutation := newUserPlatformQuotaMutation(c.config, OpDelete) + return &UserPlatformQuotaDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a builder for deleting the given entity. +func (c *UserPlatformQuotaClient) DeleteOne(_m *UserPlatformQuota) *UserPlatformQuotaDeleteOne { + return c.DeleteOneID(_m.ID) +} + +// DeleteOneID returns a builder for deleting the given entity by its id. +func (c *UserPlatformQuotaClient) DeleteOneID(id int64) *UserPlatformQuotaDeleteOne { + builder := c.Delete().Where(userplatformquota.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &UserPlatformQuotaDeleteOne{builder} +} + +// Query returns a query builder for UserPlatformQuota. +func (c *UserPlatformQuotaClient) Query() *UserPlatformQuotaQuery { + return &UserPlatformQuotaQuery{ + config: c.config, + ctx: &QueryContext{Type: TypeUserPlatformQuota}, + inters: c.Interceptors(), + } +} + +// Get returns a UserPlatformQuota entity by its id. +func (c *UserPlatformQuotaClient) Get(ctx context.Context, id int64) (*UserPlatformQuota, error) { + return c.Query().Where(userplatformquota.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *UserPlatformQuotaClient) GetX(ctx context.Context, id int64) *UserPlatformQuota { + obj, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return obj +} + +// QueryUser queries the user edge of a UserPlatformQuota. +func (c *UserPlatformQuotaClient) QueryUser(_m *UserPlatformQuota) *UserQuery { + query := (&UserClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := _m.ID + step := sqlgraph.NewStep( + sqlgraph.From(userplatformquota.Table, userplatformquota.FieldID, id), + sqlgraph.To(user.Table, user.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, userplatformquota.UserTable, userplatformquota.UserColumn), + ) + fromV = sqlgraph.Neighbors(_m.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// Hooks returns the client hooks. +func (c *UserPlatformQuotaClient) Hooks() []Hook { + hooks := c.hooks.UserPlatformQuota + return append(hooks[:len(hooks):len(hooks)], userplatformquota.Hooks[:]...) +} + +// Interceptors returns the client interceptors. +func (c *UserPlatformQuotaClient) Interceptors() []Interceptor { + inters := c.inters.UserPlatformQuota + return append(inters[:len(inters):len(inters)], userplatformquota.Interceptors[:]...) +} + +func (c *UserPlatformQuotaClient) mutate(ctx context.Context, m *UserPlatformQuotaMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&UserPlatformQuotaCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&UserPlatformQuotaUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&UserPlatformQuotaUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&UserPlatformQuotaDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("ent: unknown UserPlatformQuota mutation op: %q", m.Op()) + } +} + // UserSubscriptionClient is a client for the UserSubscription schema. type UserSubscriptionClient struct { config @@ -6025,7 +6200,8 @@ type ( PaymentOrder, PaymentProviderInstance, PendingAuthSession, PromoCode, PromoCodeUsage, Proxy, RedeemCode, SecuritySecret, Setting, SubscriptionPlan, TLSFingerprintProfile, UsageCleanupTask, UsageLog, User, UserAllowedGroup, - UserAttributeDefinition, UserAttributeValue, UserSubscription []ent.Hook + UserAttributeDefinition, UserAttributeValue, UserPlatformQuota, + UserSubscription []ent.Hook } inters struct { APIKey, Account, AccountGroup, Announcement, AnnouncementRead, AuthIdentity, @@ -6035,7 +6211,8 @@ type ( PaymentOrder, PaymentProviderInstance, PendingAuthSession, PromoCode, PromoCodeUsage, Proxy, RedeemCode, SecuritySecret, Setting, SubscriptionPlan, TLSFingerprintProfile, UsageCleanupTask, UsageLog, User, UserAllowedGroup, - UserAttributeDefinition, UserAttributeValue, UserSubscription []ent.Interceptor + UserAttributeDefinition, UserAttributeValue, UserPlatformQuota, + UserSubscription []ent.Interceptor } ) diff --git a/backend/ent/ent.go b/backend/ent/ent.go index c9fcc314..33d36e70 100644 --- a/backend/ent/ent.go +++ b/backend/ent/ent.go @@ -45,6 +45,7 @@ import ( "github.com/Wei-Shaw/sub2api/ent/userallowedgroup" "github.com/Wei-Shaw/sub2api/ent/userattributedefinition" "github.com/Wei-Shaw/sub2api/ent/userattributevalue" + "github.com/Wei-Shaw/sub2api/ent/userplatformquota" "github.com/Wei-Shaw/sub2api/ent/usersubscription" ) @@ -139,6 +140,7 @@ func checkColumn(t, c string) error { userallowedgroup.Table: userallowedgroup.ValidColumn, userattributedefinition.Table: userattributedefinition.ValidColumn, userattributevalue.Table: userattributevalue.ValidColumn, + userplatformquota.Table: userplatformquota.ValidColumn, usersubscription.Table: usersubscription.ValidColumn, }) }) diff --git a/backend/ent/hook/hook.go b/backend/ent/hook/hook.go index 414eba24..71bfd3b8 100644 --- a/backend/ent/hook/hook.go +++ b/backend/ent/hook/hook.go @@ -405,6 +405,18 @@ func (f UserAttributeValueFunc) Mutate(ctx context.Context, m ent.Mutation) (ent return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UserAttributeValueMutation", m) } +// The UserPlatformQuotaFunc type is an adapter to allow the use of ordinary +// function as UserPlatformQuota mutator. +type UserPlatformQuotaFunc func(context.Context, *ent.UserPlatformQuotaMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f UserPlatformQuotaFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if mv, ok := m.(*ent.UserPlatformQuotaMutation); ok { + return f(ctx, mv) + } + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UserPlatformQuotaMutation", m) +} + // The UserSubscriptionFunc type is an adapter to allow the use of ordinary // function as UserSubscription mutator. type UserSubscriptionFunc func(context.Context, *ent.UserSubscriptionMutation) (ent.Value, error) diff --git a/backend/ent/intercept/intercept.go b/backend/ent/intercept/intercept.go index 95b68e09..5d86e25b 100644 --- a/backend/ent/intercept/intercept.go +++ b/backend/ent/intercept/intercept.go @@ -42,6 +42,7 @@ import ( "github.com/Wei-Shaw/sub2api/ent/userallowedgroup" "github.com/Wei-Shaw/sub2api/ent/userattributedefinition" "github.com/Wei-Shaw/sub2api/ent/userattributevalue" + "github.com/Wei-Shaw/sub2api/ent/userplatformquota" "github.com/Wei-Shaw/sub2api/ent/usersubscription" ) @@ -992,6 +993,33 @@ func (f TraverseUserAttributeValue) Traverse(ctx context.Context, q ent.Query) e return fmt.Errorf("unexpected query type %T. expect *ent.UserAttributeValueQuery", q) } +// The UserPlatformQuotaFunc type is an adapter to allow the use of ordinary function as a Querier. +type UserPlatformQuotaFunc func(context.Context, *ent.UserPlatformQuotaQuery) (ent.Value, error) + +// Query calls f(ctx, q). +func (f UserPlatformQuotaFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) { + if q, ok := q.(*ent.UserPlatformQuotaQuery); ok { + return f(ctx, q) + } + return nil, fmt.Errorf("unexpected query type %T. expect *ent.UserPlatformQuotaQuery", q) +} + +// The TraverseUserPlatformQuota type is an adapter to allow the use of ordinary function as Traverser. +type TraverseUserPlatformQuota func(context.Context, *ent.UserPlatformQuotaQuery) error + +// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline. +func (f TraverseUserPlatformQuota) Intercept(next ent.Querier) ent.Querier { + return next +} + +// Traverse calls f(ctx, q). +func (f TraverseUserPlatformQuota) Traverse(ctx context.Context, q ent.Query) error { + if q, ok := q.(*ent.UserPlatformQuotaQuery); ok { + return f(ctx, q) + } + return fmt.Errorf("unexpected query type %T. expect *ent.UserPlatformQuotaQuery", q) +} + // The UserSubscriptionFunc type is an adapter to allow the use of ordinary function as a Querier. type UserSubscriptionFunc func(context.Context, *ent.UserSubscriptionQuery) (ent.Value, error) @@ -1088,6 +1116,8 @@ func NewQuery(q ent.Query) (Query, error) { return &query[*ent.UserAttributeDefinitionQuery, predicate.UserAttributeDefinition, userattributedefinition.OrderOption]{typ: ent.TypeUserAttributeDefinition, tq: q}, nil case *ent.UserAttributeValueQuery: return &query[*ent.UserAttributeValueQuery, predicate.UserAttributeValue, userattributevalue.OrderOption]{typ: ent.TypeUserAttributeValue, tq: q}, nil + case *ent.UserPlatformQuotaQuery: + return &query[*ent.UserPlatformQuotaQuery, predicate.UserPlatformQuota, userplatformquota.OrderOption]{typ: ent.TypeUserPlatformQuota, tq: q}, nil case *ent.UserSubscriptionQuery: return &query[*ent.UserSubscriptionQuery, predicate.UserSubscription, usersubscription.OrderOption]{typ: ent.TypeUserSubscription, tq: q}, nil default: diff --git a/backend/ent/migrate/schema.go b/backend/ent/migrate/schema.go index b1731a35..447f71ef 100644 --- a/backend/ent/migrate/schema.go +++ b/backend/ent/migrate/schema.go @@ -1612,6 +1612,53 @@ var ( }, }, } + // UserPlatformQuotasColumns holds the columns for the "user_platform_quotas" table. + UserPlatformQuotasColumns = []*schema.Column{ + {Name: "id", Type: field.TypeInt64, Increment: true}, + {Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}}, + {Name: "updated_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}}, + {Name: "deleted_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}}, + {Name: "platform", Type: field.TypeString, Size: 32}, + {Name: "daily_limit_usd", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(20,10)"}}, + {Name: "weekly_limit_usd", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(20,10)"}}, + {Name: "monthly_limit_usd", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(20,10)"}}, + {Name: "daily_usage_usd", Type: field.TypeFloat64, Default: 0, SchemaType: map[string]string{"postgres": "decimal(20,10)"}}, + {Name: "weekly_usage_usd", Type: field.TypeFloat64, Default: 0, SchemaType: map[string]string{"postgres": "decimal(20,10)"}}, + {Name: "monthly_usage_usd", Type: field.TypeFloat64, Default: 0, SchemaType: map[string]string{"postgres": "decimal(20,10)"}}, + {Name: "daily_window_start", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}}, + {Name: "weekly_window_start", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}}, + {Name: "monthly_window_start", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}}, + {Name: "user_id", Type: field.TypeInt64}, + } + // UserPlatformQuotasTable holds the schema information for the "user_platform_quotas" table. + UserPlatformQuotasTable = &schema.Table{ + Name: "user_platform_quotas", + Columns: UserPlatformQuotasColumns, + PrimaryKey: []*schema.Column{UserPlatformQuotasColumns[0]}, + ForeignKeys: []*schema.ForeignKey{ + { + Symbol: "user_platform_quotas_users_platform_quotas", + Columns: []*schema.Column{UserPlatformQuotasColumns[14]}, + RefColumns: []*schema.Column{UsersColumns[0]}, + OnDelete: schema.NoAction, + }, + }, + Indexes: []*schema.Index{ + { + Name: "userplatformquota_user_id_platform", + Unique: true, + Columns: []*schema.Column{UserPlatformQuotasColumns[14], UserPlatformQuotasColumns[4]}, + Annotation: &entsql.IndexAnnotation{ + Where: "deleted_at IS NULL", + }, + }, + { + Name: "userplatformquota_user_id", + Unique: false, + Columns: []*schema.Column{UserPlatformQuotasColumns[14]}, + }, + }, + } // UserSubscriptionsColumns holds the columns for the "user_subscriptions" table. UserSubscriptionsColumns = []*schema.Column{ {Name: "id", Type: field.TypeInt64, Increment: true}, @@ -1736,6 +1783,7 @@ var ( UserAllowedGroupsTable, UserAttributeDefinitionsTable, UserAttributeValuesTable, + UserPlatformQuotasTable, UserSubscriptionsTable, } ) @@ -1869,6 +1917,10 @@ func init() { UserAttributeValuesTable.Annotation = &entsql.Annotation{ Table: "user_attribute_values", } + UserPlatformQuotasTable.ForeignKeys[0].RefTable = UsersTable + UserPlatformQuotasTable.Annotation = &entsql.Annotation{ + Table: "user_platform_quotas", + } UserSubscriptionsTable.ForeignKeys[0].RefTable = GroupsTable UserSubscriptionsTable.ForeignKeys[1].RefTable = UsersTable UserSubscriptionsTable.ForeignKeys[2].RefTable = UsersTable diff --git a/backend/ent/mutation.go b/backend/ent/mutation.go index af0edc68..2e8fa7f4 100644 --- a/backend/ent/mutation.go +++ b/backend/ent/mutation.go @@ -46,6 +46,7 @@ import ( "github.com/Wei-Shaw/sub2api/ent/userallowedgroup" "github.com/Wei-Shaw/sub2api/ent/userattributedefinition" "github.com/Wei-Shaw/sub2api/ent/userattributevalue" + "github.com/Wei-Shaw/sub2api/ent/userplatformquota" "github.com/Wei-Shaw/sub2api/ent/usersubscription" "github.com/Wei-Shaw/sub2api/internal/domain" ) @@ -92,6 +93,7 @@ const ( TypeUserAllowedGroup = "UserAllowedGroup" TypeUserAttributeDefinition = "UserAttributeDefinition" TypeUserAttributeValue = "UserAttributeValue" + TypeUserPlatformQuota = "UserPlatformQuota" TypeUserSubscription = "UserSubscription" ) @@ -38160,6 +38162,9 @@ type UserMutation struct { pending_auth_sessions map[int64]struct{} removedpending_auth_sessions map[int64]struct{} clearedpending_auth_sessions bool + platform_quotas map[int64]struct{} + removedplatform_quotas map[int64]struct{} + clearedplatform_quotas bool done bool oldValue func(context.Context) (*User, error) predicates []predicate.User @@ -39918,6 +39923,60 @@ func (m *UserMutation) ResetPendingAuthSessions() { m.removedpending_auth_sessions = nil } +// AddPlatformQuotaIDs adds the "platform_quotas" edge to the UserPlatformQuota entity by ids. +func (m *UserMutation) AddPlatformQuotaIDs(ids ...int64) { + if m.platform_quotas == nil { + m.platform_quotas = make(map[int64]struct{}) + } + for i := range ids { + m.platform_quotas[ids[i]] = struct{}{} + } +} + +// ClearPlatformQuotas clears the "platform_quotas" edge to the UserPlatformQuota entity. +func (m *UserMutation) ClearPlatformQuotas() { + m.clearedplatform_quotas = true +} + +// PlatformQuotasCleared reports if the "platform_quotas" edge to the UserPlatformQuota entity was cleared. +func (m *UserMutation) PlatformQuotasCleared() bool { + return m.clearedplatform_quotas +} + +// RemovePlatformQuotaIDs removes the "platform_quotas" edge to the UserPlatformQuota entity by IDs. +func (m *UserMutation) RemovePlatformQuotaIDs(ids ...int64) { + if m.removedplatform_quotas == nil { + m.removedplatform_quotas = make(map[int64]struct{}) + } + for i := range ids { + delete(m.platform_quotas, ids[i]) + m.removedplatform_quotas[ids[i]] = struct{}{} + } +} + +// RemovedPlatformQuotas returns the removed IDs of the "platform_quotas" edge to the UserPlatformQuota entity. +func (m *UserMutation) RemovedPlatformQuotasIDs() (ids []int64) { + for id := range m.removedplatform_quotas { + ids = append(ids, id) + } + return +} + +// PlatformQuotasIDs returns the "platform_quotas" edge IDs in the mutation. +func (m *UserMutation) PlatformQuotasIDs() (ids []int64) { + for id := range m.platform_quotas { + ids = append(ids, id) + } + return +} + +// ResetPlatformQuotas resets all changes to the "platform_quotas" edge. +func (m *UserMutation) ResetPlatformQuotas() { + m.platform_quotas = nil + m.clearedplatform_quotas = false + m.removedplatform_quotas = nil +} + // Where appends a list predicates to the UserMutation builder. func (m *UserMutation) Where(ps ...predicate.User) { m.predicates = append(m.predicates, ps...) @@ -40527,7 +40586,7 @@ func (m *UserMutation) ResetField(name string) error { // AddedEdges returns all edge names that were set/added in this mutation. func (m *UserMutation) AddedEdges() []string { - edges := make([]string, 0, 12) + edges := make([]string, 0, 13) if m.api_keys != nil { edges = append(edges, user.EdgeAPIKeys) } @@ -40564,6 +40623,9 @@ func (m *UserMutation) AddedEdges() []string { if m.pending_auth_sessions != nil { edges = append(edges, user.EdgePendingAuthSessions) } + if m.platform_quotas != nil { + edges = append(edges, user.EdgePlatformQuotas) + } return edges } @@ -40643,13 +40705,19 @@ func (m *UserMutation) AddedIDs(name string) []ent.Value { ids = append(ids, id) } return ids + case user.EdgePlatformQuotas: + ids := make([]ent.Value, 0, len(m.platform_quotas)) + for id := range m.platform_quotas { + ids = append(ids, id) + } + return ids } return nil } // RemovedEdges returns all edge names that were removed in this mutation. func (m *UserMutation) RemovedEdges() []string { - edges := make([]string, 0, 12) + edges := make([]string, 0, 13) if m.removedapi_keys != nil { edges = append(edges, user.EdgeAPIKeys) } @@ -40686,6 +40754,9 @@ func (m *UserMutation) RemovedEdges() []string { if m.removedpending_auth_sessions != nil { edges = append(edges, user.EdgePendingAuthSessions) } + if m.removedplatform_quotas != nil { + edges = append(edges, user.EdgePlatformQuotas) + } return edges } @@ -40765,13 +40836,19 @@ func (m *UserMutation) RemovedIDs(name string) []ent.Value { ids = append(ids, id) } return ids + case user.EdgePlatformQuotas: + ids := make([]ent.Value, 0, len(m.removedplatform_quotas)) + for id := range m.removedplatform_quotas { + ids = append(ids, id) + } + return ids } return nil } // ClearedEdges returns all edge names that were cleared in this mutation. func (m *UserMutation) ClearedEdges() []string { - edges := make([]string, 0, 12) + edges := make([]string, 0, 13) if m.clearedapi_keys { edges = append(edges, user.EdgeAPIKeys) } @@ -40808,6 +40885,9 @@ func (m *UserMutation) ClearedEdges() []string { if m.clearedpending_auth_sessions { edges = append(edges, user.EdgePendingAuthSessions) } + if m.clearedplatform_quotas { + edges = append(edges, user.EdgePlatformQuotas) + } return edges } @@ -40839,6 +40919,8 @@ func (m *UserMutation) EdgeCleared(name string) bool { return m.clearedauth_identities case user.EdgePendingAuthSessions: return m.clearedpending_auth_sessions + case user.EdgePlatformQuotas: + return m.clearedplatform_quotas } return false } @@ -40891,6 +40973,9 @@ func (m *UserMutation) ResetEdge(name string) error { case user.EdgePendingAuthSessions: m.ResetPendingAuthSessions() return nil + case user.EdgePlatformQuotas: + m.ResetPlatformQuotas() + return nil } return fmt.Errorf("unknown User edge %s", name) } @@ -43111,6 +43196,1428 @@ func (m *UserAttributeValueMutation) ResetEdge(name string) error { return fmt.Errorf("unknown UserAttributeValue edge %s", name) } +// UserPlatformQuotaMutation represents an operation that mutates the UserPlatformQuota nodes in the graph. +type UserPlatformQuotaMutation struct { + config + op Op + typ string + id *int64 + created_at *time.Time + updated_at *time.Time + deleted_at *time.Time + platform *string + daily_limit_usd *float64 + adddaily_limit_usd *float64 + weekly_limit_usd *float64 + addweekly_limit_usd *float64 + monthly_limit_usd *float64 + addmonthly_limit_usd *float64 + daily_usage_usd *float64 + adddaily_usage_usd *float64 + weekly_usage_usd *float64 + addweekly_usage_usd *float64 + monthly_usage_usd *float64 + addmonthly_usage_usd *float64 + daily_window_start *time.Time + weekly_window_start *time.Time + monthly_window_start *time.Time + clearedFields map[string]struct{} + user *int64 + cleareduser bool + done bool + oldValue func(context.Context) (*UserPlatformQuota, error) + predicates []predicate.UserPlatformQuota +} + +var _ ent.Mutation = (*UserPlatformQuotaMutation)(nil) + +// userplatformquotaOption allows management of the mutation configuration using functional options. +type userplatformquotaOption func(*UserPlatformQuotaMutation) + +// newUserPlatformQuotaMutation creates new mutation for the UserPlatformQuota entity. +func newUserPlatformQuotaMutation(c config, op Op, opts ...userplatformquotaOption) *UserPlatformQuotaMutation { + m := &UserPlatformQuotaMutation{ + config: c, + op: op, + typ: TypeUserPlatformQuota, + clearedFields: make(map[string]struct{}), + } + for _, opt := range opts { + opt(m) + } + return m +} + +// withUserPlatformQuotaID sets the ID field of the mutation. +func withUserPlatformQuotaID(id int64) userplatformquotaOption { + return func(m *UserPlatformQuotaMutation) { + var ( + err error + once sync.Once + value *UserPlatformQuota + ) + m.oldValue = func(ctx context.Context) (*UserPlatformQuota, error) { + once.Do(func() { + if m.done { + err = errors.New("querying old values post mutation is not allowed") + } else { + value, err = m.Client().UserPlatformQuota.Get(ctx, id) + } + }) + return value, err + } + m.id = &id + } +} + +// withUserPlatformQuota sets the old UserPlatformQuota of the mutation. +func withUserPlatformQuota(node *UserPlatformQuota) userplatformquotaOption { + return func(m *UserPlatformQuotaMutation) { + m.oldValue = func(context.Context) (*UserPlatformQuota, error) { + return node, nil + } + m.id = &node.ID + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m UserPlatformQuotaMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m UserPlatformQuotaMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, errors.New("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the ID value in the mutation. Note that the ID is only available +// if it was provided to the builder or after it was returned from the database. +func (m *UserPlatformQuotaMutation) ID() (id int64, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// IDs queries the database and returns the entity ids that match the mutation's predicate. +// That means, if the mutation is applied within a transaction with an isolation level such +// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated +// or updated by the mutation. +func (m *UserPlatformQuotaMutation) IDs(ctx context.Context) ([]int64, error) { + switch { + case m.op.Is(OpUpdateOne | OpDeleteOne): + id, exists := m.ID() + if exists { + return []int64{id}, nil + } + fallthrough + case m.op.Is(OpUpdate | OpDelete): + return m.Client().UserPlatformQuota.Query().Where(m.predicates...).IDs(ctx) + default: + return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) + } +} + +// SetCreatedAt sets the "created_at" field. +func (m *UserPlatformQuotaMutation) SetCreatedAt(t time.Time) { + m.created_at = &t +} + +// CreatedAt returns the value of the "created_at" field in the mutation. +func (m *UserPlatformQuotaMutation) CreatedAt() (r time.Time, exists bool) { + v := m.created_at + if v == nil { + return + } + return *v, true +} + +// OldCreatedAt returns the old "created_at" field's value of the UserPlatformQuota entity. +// If the UserPlatformQuota object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserPlatformQuotaMutation) OldCreatedAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldCreatedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldCreatedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldCreatedAt: %w", err) + } + return oldValue.CreatedAt, nil +} + +// ResetCreatedAt resets all changes to the "created_at" field. +func (m *UserPlatformQuotaMutation) ResetCreatedAt() { + m.created_at = nil +} + +// SetUpdatedAt sets the "updated_at" field. +func (m *UserPlatformQuotaMutation) SetUpdatedAt(t time.Time) { + m.updated_at = &t +} + +// UpdatedAt returns the value of the "updated_at" field in the mutation. +func (m *UserPlatformQuotaMutation) UpdatedAt() (r time.Time, exists bool) { + v := m.updated_at + if v == nil { + return + } + return *v, true +} + +// OldUpdatedAt returns the old "updated_at" field's value of the UserPlatformQuota entity. +// If the UserPlatformQuota object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserPlatformQuotaMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUpdatedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUpdatedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUpdatedAt: %w", err) + } + return oldValue.UpdatedAt, nil +} + +// ResetUpdatedAt resets all changes to the "updated_at" field. +func (m *UserPlatformQuotaMutation) ResetUpdatedAt() { + m.updated_at = nil +} + +// SetDeletedAt sets the "deleted_at" field. +func (m *UserPlatformQuotaMutation) SetDeletedAt(t time.Time) { + m.deleted_at = &t +} + +// DeletedAt returns the value of the "deleted_at" field in the mutation. +func (m *UserPlatformQuotaMutation) DeletedAt() (r time.Time, exists bool) { + v := m.deleted_at + if v == nil { + return + } + return *v, true +} + +// OldDeletedAt returns the old "deleted_at" field's value of the UserPlatformQuota entity. +// If the UserPlatformQuota object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserPlatformQuotaMutation) OldDeletedAt(ctx context.Context) (v *time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldDeletedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldDeletedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldDeletedAt: %w", err) + } + return oldValue.DeletedAt, nil +} + +// ClearDeletedAt clears the value of the "deleted_at" field. +func (m *UserPlatformQuotaMutation) ClearDeletedAt() { + m.deleted_at = nil + m.clearedFields[userplatformquota.FieldDeletedAt] = struct{}{} +} + +// DeletedAtCleared returns if the "deleted_at" field was cleared in this mutation. +func (m *UserPlatformQuotaMutation) DeletedAtCleared() bool { + _, ok := m.clearedFields[userplatformquota.FieldDeletedAt] + return ok +} + +// ResetDeletedAt resets all changes to the "deleted_at" field. +func (m *UserPlatformQuotaMutation) ResetDeletedAt() { + m.deleted_at = nil + delete(m.clearedFields, userplatformquota.FieldDeletedAt) +} + +// SetUserID sets the "user_id" field. +func (m *UserPlatformQuotaMutation) SetUserID(i int64) { + m.user = &i +} + +// UserID returns the value of the "user_id" field in the mutation. +func (m *UserPlatformQuotaMutation) UserID() (r int64, exists bool) { + v := m.user + if v == nil { + return + } + return *v, true +} + +// OldUserID returns the old "user_id" field's value of the UserPlatformQuota entity. +// If the UserPlatformQuota object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserPlatformQuotaMutation) OldUserID(ctx context.Context) (v int64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUserID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUserID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUserID: %w", err) + } + return oldValue.UserID, nil +} + +// ResetUserID resets all changes to the "user_id" field. +func (m *UserPlatformQuotaMutation) ResetUserID() { + m.user = nil +} + +// SetPlatform sets the "platform" field. +func (m *UserPlatformQuotaMutation) SetPlatform(s string) { + m.platform = &s +} + +// Platform returns the value of the "platform" field in the mutation. +func (m *UserPlatformQuotaMutation) Platform() (r string, exists bool) { + v := m.platform + if v == nil { + return + } + return *v, true +} + +// OldPlatform returns the old "platform" field's value of the UserPlatformQuota entity. +// If the UserPlatformQuota object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserPlatformQuotaMutation) OldPlatform(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldPlatform is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldPlatform requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldPlatform: %w", err) + } + return oldValue.Platform, nil +} + +// ResetPlatform resets all changes to the "platform" field. +func (m *UserPlatformQuotaMutation) ResetPlatform() { + m.platform = nil +} + +// SetDailyLimitUsd sets the "daily_limit_usd" field. +func (m *UserPlatformQuotaMutation) SetDailyLimitUsd(f float64) { + m.daily_limit_usd = &f + m.adddaily_limit_usd = nil +} + +// DailyLimitUsd returns the value of the "daily_limit_usd" field in the mutation. +func (m *UserPlatformQuotaMutation) DailyLimitUsd() (r float64, exists bool) { + v := m.daily_limit_usd + if v == nil { + return + } + return *v, true +} + +// OldDailyLimitUsd returns the old "daily_limit_usd" field's value of the UserPlatformQuota entity. +// If the UserPlatformQuota object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserPlatformQuotaMutation) OldDailyLimitUsd(ctx context.Context) (v *float64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldDailyLimitUsd is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldDailyLimitUsd requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldDailyLimitUsd: %w", err) + } + return oldValue.DailyLimitUsd, nil +} + +// AddDailyLimitUsd adds f to the "daily_limit_usd" field. +func (m *UserPlatformQuotaMutation) AddDailyLimitUsd(f float64) { + if m.adddaily_limit_usd != nil { + *m.adddaily_limit_usd += f + } else { + m.adddaily_limit_usd = &f + } +} + +// AddedDailyLimitUsd returns the value that was added to the "daily_limit_usd" field in this mutation. +func (m *UserPlatformQuotaMutation) AddedDailyLimitUsd() (r float64, exists bool) { + v := m.adddaily_limit_usd + if v == nil { + return + } + return *v, true +} + +// ClearDailyLimitUsd clears the value of the "daily_limit_usd" field. +func (m *UserPlatformQuotaMutation) ClearDailyLimitUsd() { + m.daily_limit_usd = nil + m.adddaily_limit_usd = nil + m.clearedFields[userplatformquota.FieldDailyLimitUsd] = struct{}{} +} + +// DailyLimitUsdCleared returns if the "daily_limit_usd" field was cleared in this mutation. +func (m *UserPlatformQuotaMutation) DailyLimitUsdCleared() bool { + _, ok := m.clearedFields[userplatformquota.FieldDailyLimitUsd] + return ok +} + +// ResetDailyLimitUsd resets all changes to the "daily_limit_usd" field. +func (m *UserPlatformQuotaMutation) ResetDailyLimitUsd() { + m.daily_limit_usd = nil + m.adddaily_limit_usd = nil + delete(m.clearedFields, userplatformquota.FieldDailyLimitUsd) +} + +// SetWeeklyLimitUsd sets the "weekly_limit_usd" field. +func (m *UserPlatformQuotaMutation) SetWeeklyLimitUsd(f float64) { + m.weekly_limit_usd = &f + m.addweekly_limit_usd = nil +} + +// WeeklyLimitUsd returns the value of the "weekly_limit_usd" field in the mutation. +func (m *UserPlatformQuotaMutation) WeeklyLimitUsd() (r float64, exists bool) { + v := m.weekly_limit_usd + if v == nil { + return + } + return *v, true +} + +// OldWeeklyLimitUsd returns the old "weekly_limit_usd" field's value of the UserPlatformQuota entity. +// If the UserPlatformQuota object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserPlatformQuotaMutation) OldWeeklyLimitUsd(ctx context.Context) (v *float64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldWeeklyLimitUsd is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldWeeklyLimitUsd requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldWeeklyLimitUsd: %w", err) + } + return oldValue.WeeklyLimitUsd, nil +} + +// AddWeeklyLimitUsd adds f to the "weekly_limit_usd" field. +func (m *UserPlatformQuotaMutation) AddWeeklyLimitUsd(f float64) { + if m.addweekly_limit_usd != nil { + *m.addweekly_limit_usd += f + } else { + m.addweekly_limit_usd = &f + } +} + +// AddedWeeklyLimitUsd returns the value that was added to the "weekly_limit_usd" field in this mutation. +func (m *UserPlatformQuotaMutation) AddedWeeklyLimitUsd() (r float64, exists bool) { + v := m.addweekly_limit_usd + if v == nil { + return + } + return *v, true +} + +// ClearWeeklyLimitUsd clears the value of the "weekly_limit_usd" field. +func (m *UserPlatformQuotaMutation) ClearWeeklyLimitUsd() { + m.weekly_limit_usd = nil + m.addweekly_limit_usd = nil + m.clearedFields[userplatformquota.FieldWeeklyLimitUsd] = struct{}{} +} + +// WeeklyLimitUsdCleared returns if the "weekly_limit_usd" field was cleared in this mutation. +func (m *UserPlatformQuotaMutation) WeeklyLimitUsdCleared() bool { + _, ok := m.clearedFields[userplatformquota.FieldWeeklyLimitUsd] + return ok +} + +// ResetWeeklyLimitUsd resets all changes to the "weekly_limit_usd" field. +func (m *UserPlatformQuotaMutation) ResetWeeklyLimitUsd() { + m.weekly_limit_usd = nil + m.addweekly_limit_usd = nil + delete(m.clearedFields, userplatformquota.FieldWeeklyLimitUsd) +} + +// SetMonthlyLimitUsd sets the "monthly_limit_usd" field. +func (m *UserPlatformQuotaMutation) SetMonthlyLimitUsd(f float64) { + m.monthly_limit_usd = &f + m.addmonthly_limit_usd = nil +} + +// MonthlyLimitUsd returns the value of the "monthly_limit_usd" field in the mutation. +func (m *UserPlatformQuotaMutation) MonthlyLimitUsd() (r float64, exists bool) { + v := m.monthly_limit_usd + if v == nil { + return + } + return *v, true +} + +// OldMonthlyLimitUsd returns the old "monthly_limit_usd" field's value of the UserPlatformQuota entity. +// If the UserPlatformQuota object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserPlatformQuotaMutation) OldMonthlyLimitUsd(ctx context.Context) (v *float64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldMonthlyLimitUsd is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldMonthlyLimitUsd requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldMonthlyLimitUsd: %w", err) + } + return oldValue.MonthlyLimitUsd, nil +} + +// AddMonthlyLimitUsd adds f to the "monthly_limit_usd" field. +func (m *UserPlatformQuotaMutation) AddMonthlyLimitUsd(f float64) { + if m.addmonthly_limit_usd != nil { + *m.addmonthly_limit_usd += f + } else { + m.addmonthly_limit_usd = &f + } +} + +// AddedMonthlyLimitUsd returns the value that was added to the "monthly_limit_usd" field in this mutation. +func (m *UserPlatformQuotaMutation) AddedMonthlyLimitUsd() (r float64, exists bool) { + v := m.addmonthly_limit_usd + if v == nil { + return + } + return *v, true +} + +// ClearMonthlyLimitUsd clears the value of the "monthly_limit_usd" field. +func (m *UserPlatformQuotaMutation) ClearMonthlyLimitUsd() { + m.monthly_limit_usd = nil + m.addmonthly_limit_usd = nil + m.clearedFields[userplatformquota.FieldMonthlyLimitUsd] = struct{}{} +} + +// MonthlyLimitUsdCleared returns if the "monthly_limit_usd" field was cleared in this mutation. +func (m *UserPlatformQuotaMutation) MonthlyLimitUsdCleared() bool { + _, ok := m.clearedFields[userplatformquota.FieldMonthlyLimitUsd] + return ok +} + +// ResetMonthlyLimitUsd resets all changes to the "monthly_limit_usd" field. +func (m *UserPlatformQuotaMutation) ResetMonthlyLimitUsd() { + m.monthly_limit_usd = nil + m.addmonthly_limit_usd = nil + delete(m.clearedFields, userplatformquota.FieldMonthlyLimitUsd) +} + +// SetDailyUsageUsd sets the "daily_usage_usd" field. +func (m *UserPlatformQuotaMutation) SetDailyUsageUsd(f float64) { + m.daily_usage_usd = &f + m.adddaily_usage_usd = nil +} + +// DailyUsageUsd returns the value of the "daily_usage_usd" field in the mutation. +func (m *UserPlatformQuotaMutation) DailyUsageUsd() (r float64, exists bool) { + v := m.daily_usage_usd + if v == nil { + return + } + return *v, true +} + +// OldDailyUsageUsd returns the old "daily_usage_usd" field's value of the UserPlatformQuota entity. +// If the UserPlatformQuota object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserPlatformQuotaMutation) OldDailyUsageUsd(ctx context.Context) (v float64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldDailyUsageUsd is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldDailyUsageUsd requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldDailyUsageUsd: %w", err) + } + return oldValue.DailyUsageUsd, nil +} + +// AddDailyUsageUsd adds f to the "daily_usage_usd" field. +func (m *UserPlatformQuotaMutation) AddDailyUsageUsd(f float64) { + if m.adddaily_usage_usd != nil { + *m.adddaily_usage_usd += f + } else { + m.adddaily_usage_usd = &f + } +} + +// AddedDailyUsageUsd returns the value that was added to the "daily_usage_usd" field in this mutation. +func (m *UserPlatformQuotaMutation) AddedDailyUsageUsd() (r float64, exists bool) { + v := m.adddaily_usage_usd + if v == nil { + return + } + return *v, true +} + +// ResetDailyUsageUsd resets all changes to the "daily_usage_usd" field. +func (m *UserPlatformQuotaMutation) ResetDailyUsageUsd() { + m.daily_usage_usd = nil + m.adddaily_usage_usd = nil +} + +// SetWeeklyUsageUsd sets the "weekly_usage_usd" field. +func (m *UserPlatformQuotaMutation) SetWeeklyUsageUsd(f float64) { + m.weekly_usage_usd = &f + m.addweekly_usage_usd = nil +} + +// WeeklyUsageUsd returns the value of the "weekly_usage_usd" field in the mutation. +func (m *UserPlatformQuotaMutation) WeeklyUsageUsd() (r float64, exists bool) { + v := m.weekly_usage_usd + if v == nil { + return + } + return *v, true +} + +// OldWeeklyUsageUsd returns the old "weekly_usage_usd" field's value of the UserPlatformQuota entity. +// If the UserPlatformQuota object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserPlatformQuotaMutation) OldWeeklyUsageUsd(ctx context.Context) (v float64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldWeeklyUsageUsd is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldWeeklyUsageUsd requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldWeeklyUsageUsd: %w", err) + } + return oldValue.WeeklyUsageUsd, nil +} + +// AddWeeklyUsageUsd adds f to the "weekly_usage_usd" field. +func (m *UserPlatformQuotaMutation) AddWeeklyUsageUsd(f float64) { + if m.addweekly_usage_usd != nil { + *m.addweekly_usage_usd += f + } else { + m.addweekly_usage_usd = &f + } +} + +// AddedWeeklyUsageUsd returns the value that was added to the "weekly_usage_usd" field in this mutation. +func (m *UserPlatformQuotaMutation) AddedWeeklyUsageUsd() (r float64, exists bool) { + v := m.addweekly_usage_usd + if v == nil { + return + } + return *v, true +} + +// ResetWeeklyUsageUsd resets all changes to the "weekly_usage_usd" field. +func (m *UserPlatformQuotaMutation) ResetWeeklyUsageUsd() { + m.weekly_usage_usd = nil + m.addweekly_usage_usd = nil +} + +// SetMonthlyUsageUsd sets the "monthly_usage_usd" field. +func (m *UserPlatformQuotaMutation) SetMonthlyUsageUsd(f float64) { + m.monthly_usage_usd = &f + m.addmonthly_usage_usd = nil +} + +// MonthlyUsageUsd returns the value of the "monthly_usage_usd" field in the mutation. +func (m *UserPlatformQuotaMutation) MonthlyUsageUsd() (r float64, exists bool) { + v := m.monthly_usage_usd + if v == nil { + return + } + return *v, true +} + +// OldMonthlyUsageUsd returns the old "monthly_usage_usd" field's value of the UserPlatformQuota entity. +// If the UserPlatformQuota object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserPlatformQuotaMutation) OldMonthlyUsageUsd(ctx context.Context) (v float64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldMonthlyUsageUsd is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldMonthlyUsageUsd requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldMonthlyUsageUsd: %w", err) + } + return oldValue.MonthlyUsageUsd, nil +} + +// AddMonthlyUsageUsd adds f to the "monthly_usage_usd" field. +func (m *UserPlatformQuotaMutation) AddMonthlyUsageUsd(f float64) { + if m.addmonthly_usage_usd != nil { + *m.addmonthly_usage_usd += f + } else { + m.addmonthly_usage_usd = &f + } +} + +// AddedMonthlyUsageUsd returns the value that was added to the "monthly_usage_usd" field in this mutation. +func (m *UserPlatformQuotaMutation) AddedMonthlyUsageUsd() (r float64, exists bool) { + v := m.addmonthly_usage_usd + if v == nil { + return + } + return *v, true +} + +// ResetMonthlyUsageUsd resets all changes to the "monthly_usage_usd" field. +func (m *UserPlatformQuotaMutation) ResetMonthlyUsageUsd() { + m.monthly_usage_usd = nil + m.addmonthly_usage_usd = nil +} + +// SetDailyWindowStart sets the "daily_window_start" field. +func (m *UserPlatformQuotaMutation) SetDailyWindowStart(t time.Time) { + m.daily_window_start = &t +} + +// DailyWindowStart returns the value of the "daily_window_start" field in the mutation. +func (m *UserPlatformQuotaMutation) DailyWindowStart() (r time.Time, exists bool) { + v := m.daily_window_start + if v == nil { + return + } + return *v, true +} + +// OldDailyWindowStart returns the old "daily_window_start" field's value of the UserPlatformQuota entity. +// If the UserPlatformQuota object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserPlatformQuotaMutation) OldDailyWindowStart(ctx context.Context) (v *time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldDailyWindowStart is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldDailyWindowStart requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldDailyWindowStart: %w", err) + } + return oldValue.DailyWindowStart, nil +} + +// ClearDailyWindowStart clears the value of the "daily_window_start" field. +func (m *UserPlatformQuotaMutation) ClearDailyWindowStart() { + m.daily_window_start = nil + m.clearedFields[userplatformquota.FieldDailyWindowStart] = struct{}{} +} + +// DailyWindowStartCleared returns if the "daily_window_start" field was cleared in this mutation. +func (m *UserPlatformQuotaMutation) DailyWindowStartCleared() bool { + _, ok := m.clearedFields[userplatformquota.FieldDailyWindowStart] + return ok +} + +// ResetDailyWindowStart resets all changes to the "daily_window_start" field. +func (m *UserPlatformQuotaMutation) ResetDailyWindowStart() { + m.daily_window_start = nil + delete(m.clearedFields, userplatformquota.FieldDailyWindowStart) +} + +// SetWeeklyWindowStart sets the "weekly_window_start" field. +func (m *UserPlatformQuotaMutation) SetWeeklyWindowStart(t time.Time) { + m.weekly_window_start = &t +} + +// WeeklyWindowStart returns the value of the "weekly_window_start" field in the mutation. +func (m *UserPlatformQuotaMutation) WeeklyWindowStart() (r time.Time, exists bool) { + v := m.weekly_window_start + if v == nil { + return + } + return *v, true +} + +// OldWeeklyWindowStart returns the old "weekly_window_start" field's value of the UserPlatformQuota entity. +// If the UserPlatformQuota object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserPlatformQuotaMutation) OldWeeklyWindowStart(ctx context.Context) (v *time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldWeeklyWindowStart is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldWeeklyWindowStart requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldWeeklyWindowStart: %w", err) + } + return oldValue.WeeklyWindowStart, nil +} + +// ClearWeeklyWindowStart clears the value of the "weekly_window_start" field. +func (m *UserPlatformQuotaMutation) ClearWeeklyWindowStart() { + m.weekly_window_start = nil + m.clearedFields[userplatformquota.FieldWeeklyWindowStart] = struct{}{} +} + +// WeeklyWindowStartCleared returns if the "weekly_window_start" field was cleared in this mutation. +func (m *UserPlatformQuotaMutation) WeeklyWindowStartCleared() bool { + _, ok := m.clearedFields[userplatformquota.FieldWeeklyWindowStart] + return ok +} + +// ResetWeeklyWindowStart resets all changes to the "weekly_window_start" field. +func (m *UserPlatformQuotaMutation) ResetWeeklyWindowStart() { + m.weekly_window_start = nil + delete(m.clearedFields, userplatformquota.FieldWeeklyWindowStart) +} + +// SetMonthlyWindowStart sets the "monthly_window_start" field. +func (m *UserPlatformQuotaMutation) SetMonthlyWindowStart(t time.Time) { + m.monthly_window_start = &t +} + +// MonthlyWindowStart returns the value of the "monthly_window_start" field in the mutation. +func (m *UserPlatformQuotaMutation) MonthlyWindowStart() (r time.Time, exists bool) { + v := m.monthly_window_start + if v == nil { + return + } + return *v, true +} + +// OldMonthlyWindowStart returns the old "monthly_window_start" field's value of the UserPlatformQuota entity. +// If the UserPlatformQuota object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserPlatformQuotaMutation) OldMonthlyWindowStart(ctx context.Context) (v *time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldMonthlyWindowStart is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldMonthlyWindowStart requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldMonthlyWindowStart: %w", err) + } + return oldValue.MonthlyWindowStart, nil +} + +// ClearMonthlyWindowStart clears the value of the "monthly_window_start" field. +func (m *UserPlatformQuotaMutation) ClearMonthlyWindowStart() { + m.monthly_window_start = nil + m.clearedFields[userplatformquota.FieldMonthlyWindowStart] = struct{}{} +} + +// MonthlyWindowStartCleared returns if the "monthly_window_start" field was cleared in this mutation. +func (m *UserPlatformQuotaMutation) MonthlyWindowStartCleared() bool { + _, ok := m.clearedFields[userplatformquota.FieldMonthlyWindowStart] + return ok +} + +// ResetMonthlyWindowStart resets all changes to the "monthly_window_start" field. +func (m *UserPlatformQuotaMutation) ResetMonthlyWindowStart() { + m.monthly_window_start = nil + delete(m.clearedFields, userplatformquota.FieldMonthlyWindowStart) +} + +// ClearUser clears the "user" edge to the User entity. +func (m *UserPlatformQuotaMutation) ClearUser() { + m.cleareduser = true + m.clearedFields[userplatformquota.FieldUserID] = struct{}{} +} + +// UserCleared reports if the "user" edge to the User entity was cleared. +func (m *UserPlatformQuotaMutation) UserCleared() bool { + return m.cleareduser +} + +// UserIDs returns the "user" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// UserID instead. It exists only for internal usage by the builders. +func (m *UserPlatformQuotaMutation) UserIDs() (ids []int64) { + if id := m.user; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetUser resets all changes to the "user" edge. +func (m *UserPlatformQuotaMutation) ResetUser() { + m.user = nil + m.cleareduser = false +} + +// Where appends a list predicates to the UserPlatformQuotaMutation builder. +func (m *UserPlatformQuotaMutation) Where(ps ...predicate.UserPlatformQuota) { + m.predicates = append(m.predicates, ps...) +} + +// WhereP appends storage-level predicates to the UserPlatformQuotaMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *UserPlatformQuotaMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.UserPlatformQuota, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + +// Op returns the operation name. +func (m *UserPlatformQuotaMutation) Op() Op { + return m.op +} + +// SetOp allows setting the mutation operation. +func (m *UserPlatformQuotaMutation) SetOp(op Op) { + m.op = op +} + +// Type returns the node type of this mutation (UserPlatformQuota). +func (m *UserPlatformQuotaMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during this mutation. Note that in +// order to get all numeric fields that were incremented/decremented, call +// AddedFields(). +func (m *UserPlatformQuotaMutation) Fields() []string { + fields := make([]string, 0, 14) + if m.created_at != nil { + fields = append(fields, userplatformquota.FieldCreatedAt) + } + if m.updated_at != nil { + fields = append(fields, userplatformquota.FieldUpdatedAt) + } + if m.deleted_at != nil { + fields = append(fields, userplatformquota.FieldDeletedAt) + } + if m.user != nil { + fields = append(fields, userplatformquota.FieldUserID) + } + if m.platform != nil { + fields = append(fields, userplatformquota.FieldPlatform) + } + if m.daily_limit_usd != nil { + fields = append(fields, userplatformquota.FieldDailyLimitUsd) + } + if m.weekly_limit_usd != nil { + fields = append(fields, userplatformquota.FieldWeeklyLimitUsd) + } + if m.monthly_limit_usd != nil { + fields = append(fields, userplatformquota.FieldMonthlyLimitUsd) + } + if m.daily_usage_usd != nil { + fields = append(fields, userplatformquota.FieldDailyUsageUsd) + } + if m.weekly_usage_usd != nil { + fields = append(fields, userplatformquota.FieldWeeklyUsageUsd) + } + if m.monthly_usage_usd != nil { + fields = append(fields, userplatformquota.FieldMonthlyUsageUsd) + } + if m.daily_window_start != nil { + fields = append(fields, userplatformquota.FieldDailyWindowStart) + } + if m.weekly_window_start != nil { + fields = append(fields, userplatformquota.FieldWeeklyWindowStart) + } + if m.monthly_window_start != nil { + fields = append(fields, userplatformquota.FieldMonthlyWindowStart) + } + return fields +} + +// Field returns the value of a field with the given name. The second boolean +// return value indicates that this field was not set, or was not defined in the +// schema. +func (m *UserPlatformQuotaMutation) Field(name string) (ent.Value, bool) { + switch name { + case userplatformquota.FieldCreatedAt: + return m.CreatedAt() + case userplatformquota.FieldUpdatedAt: + return m.UpdatedAt() + case userplatformquota.FieldDeletedAt: + return m.DeletedAt() + case userplatformquota.FieldUserID: + return m.UserID() + case userplatformquota.FieldPlatform: + return m.Platform() + case userplatformquota.FieldDailyLimitUsd: + return m.DailyLimitUsd() + case userplatformquota.FieldWeeklyLimitUsd: + return m.WeeklyLimitUsd() + case userplatformquota.FieldMonthlyLimitUsd: + return m.MonthlyLimitUsd() + case userplatformquota.FieldDailyUsageUsd: + return m.DailyUsageUsd() + case userplatformquota.FieldWeeklyUsageUsd: + return m.WeeklyUsageUsd() + case userplatformquota.FieldMonthlyUsageUsd: + return m.MonthlyUsageUsd() + case userplatformquota.FieldDailyWindowStart: + return m.DailyWindowStart() + case userplatformquota.FieldWeeklyWindowStart: + return m.WeeklyWindowStart() + case userplatformquota.FieldMonthlyWindowStart: + return m.MonthlyWindowStart() + } + return nil, false +} + +// OldField returns the old value of the field from the database. An error is +// returned if the mutation operation is not UpdateOne, or the query to the +// database failed. +func (m *UserPlatformQuotaMutation) OldField(ctx context.Context, name string) (ent.Value, error) { + switch name { + case userplatformquota.FieldCreatedAt: + return m.OldCreatedAt(ctx) + case userplatformquota.FieldUpdatedAt: + return m.OldUpdatedAt(ctx) + case userplatformquota.FieldDeletedAt: + return m.OldDeletedAt(ctx) + case userplatformquota.FieldUserID: + return m.OldUserID(ctx) + case userplatformquota.FieldPlatform: + return m.OldPlatform(ctx) + case userplatformquota.FieldDailyLimitUsd: + return m.OldDailyLimitUsd(ctx) + case userplatformquota.FieldWeeklyLimitUsd: + return m.OldWeeklyLimitUsd(ctx) + case userplatformquota.FieldMonthlyLimitUsd: + return m.OldMonthlyLimitUsd(ctx) + case userplatformquota.FieldDailyUsageUsd: + return m.OldDailyUsageUsd(ctx) + case userplatformquota.FieldWeeklyUsageUsd: + return m.OldWeeklyUsageUsd(ctx) + case userplatformquota.FieldMonthlyUsageUsd: + return m.OldMonthlyUsageUsd(ctx) + case userplatformquota.FieldDailyWindowStart: + return m.OldDailyWindowStart(ctx) + case userplatformquota.FieldWeeklyWindowStart: + return m.OldWeeklyWindowStart(ctx) + case userplatformquota.FieldMonthlyWindowStart: + return m.OldMonthlyWindowStart(ctx) + } + return nil, fmt.Errorf("unknown UserPlatformQuota field %s", name) +} + +// SetField sets the value of a field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *UserPlatformQuotaMutation) SetField(name string, value ent.Value) error { + switch name { + case userplatformquota.FieldCreatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetCreatedAt(v) + return nil + case userplatformquota.FieldUpdatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUpdatedAt(v) + return nil + case userplatformquota.FieldDeletedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetDeletedAt(v) + return nil + case userplatformquota.FieldUserID: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUserID(v) + return nil + case userplatformquota.FieldPlatform: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetPlatform(v) + return nil + case userplatformquota.FieldDailyLimitUsd: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetDailyLimitUsd(v) + return nil + case userplatformquota.FieldWeeklyLimitUsd: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetWeeklyLimitUsd(v) + return nil + case userplatformquota.FieldMonthlyLimitUsd: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetMonthlyLimitUsd(v) + return nil + case userplatformquota.FieldDailyUsageUsd: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetDailyUsageUsd(v) + return nil + case userplatformquota.FieldWeeklyUsageUsd: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetWeeklyUsageUsd(v) + return nil + case userplatformquota.FieldMonthlyUsageUsd: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetMonthlyUsageUsd(v) + return nil + case userplatformquota.FieldDailyWindowStart: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetDailyWindowStart(v) + return nil + case userplatformquota.FieldWeeklyWindowStart: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetWeeklyWindowStart(v) + return nil + case userplatformquota.FieldMonthlyWindowStart: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetMonthlyWindowStart(v) + return nil + } + return fmt.Errorf("unknown UserPlatformQuota field %s", name) +} + +// AddedFields returns all numeric fields that were incremented/decremented during +// this mutation. +func (m *UserPlatformQuotaMutation) AddedFields() []string { + var fields []string + if m.adddaily_limit_usd != nil { + fields = append(fields, userplatformquota.FieldDailyLimitUsd) + } + if m.addweekly_limit_usd != nil { + fields = append(fields, userplatformquota.FieldWeeklyLimitUsd) + } + if m.addmonthly_limit_usd != nil { + fields = append(fields, userplatformquota.FieldMonthlyLimitUsd) + } + if m.adddaily_usage_usd != nil { + fields = append(fields, userplatformquota.FieldDailyUsageUsd) + } + if m.addweekly_usage_usd != nil { + fields = append(fields, userplatformquota.FieldWeeklyUsageUsd) + } + if m.addmonthly_usage_usd != nil { + fields = append(fields, userplatformquota.FieldMonthlyUsageUsd) + } + return fields +} + +// AddedField returns the numeric value that was incremented/decremented on a field +// with the given name. The second boolean return value indicates that this field +// was not set, or was not defined in the schema. +func (m *UserPlatformQuotaMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case userplatformquota.FieldDailyLimitUsd: + return m.AddedDailyLimitUsd() + case userplatformquota.FieldWeeklyLimitUsd: + return m.AddedWeeklyLimitUsd() + case userplatformquota.FieldMonthlyLimitUsd: + return m.AddedMonthlyLimitUsd() + case userplatformquota.FieldDailyUsageUsd: + return m.AddedDailyUsageUsd() + case userplatformquota.FieldWeeklyUsageUsd: + return m.AddedWeeklyUsageUsd() + case userplatformquota.FieldMonthlyUsageUsd: + return m.AddedMonthlyUsageUsd() + } + return nil, false +} + +// AddField adds the value to the field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *UserPlatformQuotaMutation) AddField(name string, value ent.Value) error { + switch name { + case userplatformquota.FieldDailyLimitUsd: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddDailyLimitUsd(v) + return nil + case userplatformquota.FieldWeeklyLimitUsd: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddWeeklyLimitUsd(v) + return nil + case userplatformquota.FieldMonthlyLimitUsd: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddMonthlyLimitUsd(v) + return nil + case userplatformquota.FieldDailyUsageUsd: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddDailyUsageUsd(v) + return nil + case userplatformquota.FieldWeeklyUsageUsd: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddWeeklyUsageUsd(v) + return nil + case userplatformquota.FieldMonthlyUsageUsd: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddMonthlyUsageUsd(v) + return nil + } + return fmt.Errorf("unknown UserPlatformQuota numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared during this +// mutation. +func (m *UserPlatformQuotaMutation) ClearedFields() []string { + var fields []string + if m.FieldCleared(userplatformquota.FieldDeletedAt) { + fields = append(fields, userplatformquota.FieldDeletedAt) + } + if m.FieldCleared(userplatformquota.FieldDailyLimitUsd) { + fields = append(fields, userplatformquota.FieldDailyLimitUsd) + } + if m.FieldCleared(userplatformquota.FieldWeeklyLimitUsd) { + fields = append(fields, userplatformquota.FieldWeeklyLimitUsd) + } + if m.FieldCleared(userplatformquota.FieldMonthlyLimitUsd) { + fields = append(fields, userplatformquota.FieldMonthlyLimitUsd) + } + if m.FieldCleared(userplatformquota.FieldDailyWindowStart) { + fields = append(fields, userplatformquota.FieldDailyWindowStart) + } + if m.FieldCleared(userplatformquota.FieldWeeklyWindowStart) { + fields = append(fields, userplatformquota.FieldWeeklyWindowStart) + } + if m.FieldCleared(userplatformquota.FieldMonthlyWindowStart) { + fields = append(fields, userplatformquota.FieldMonthlyWindowStart) + } + return fields +} + +// FieldCleared returns a boolean indicating if a field with the given name was +// cleared in this mutation. +func (m *UserPlatformQuotaMutation) FieldCleared(name string) bool { + _, ok := m.clearedFields[name] + return ok +} + +// ClearField clears the value of the field with the given name. It returns an +// error if the field is not defined in the schema. +func (m *UserPlatformQuotaMutation) ClearField(name string) error { + switch name { + case userplatformquota.FieldDeletedAt: + m.ClearDeletedAt() + return nil + case userplatformquota.FieldDailyLimitUsd: + m.ClearDailyLimitUsd() + return nil + case userplatformquota.FieldWeeklyLimitUsd: + m.ClearWeeklyLimitUsd() + return nil + case userplatformquota.FieldMonthlyLimitUsd: + m.ClearMonthlyLimitUsd() + return nil + case userplatformquota.FieldDailyWindowStart: + m.ClearDailyWindowStart() + return nil + case userplatformquota.FieldWeeklyWindowStart: + m.ClearWeeklyWindowStart() + return nil + case userplatformquota.FieldMonthlyWindowStart: + m.ClearMonthlyWindowStart() + return nil + } + return fmt.Errorf("unknown UserPlatformQuota nullable field %s", name) +} + +// ResetField resets all changes in the mutation for the field with the given name. +// It returns an error if the field is not defined in the schema. +func (m *UserPlatformQuotaMutation) ResetField(name string) error { + switch name { + case userplatformquota.FieldCreatedAt: + m.ResetCreatedAt() + return nil + case userplatformquota.FieldUpdatedAt: + m.ResetUpdatedAt() + return nil + case userplatformquota.FieldDeletedAt: + m.ResetDeletedAt() + return nil + case userplatformquota.FieldUserID: + m.ResetUserID() + return nil + case userplatformquota.FieldPlatform: + m.ResetPlatform() + return nil + case userplatformquota.FieldDailyLimitUsd: + m.ResetDailyLimitUsd() + return nil + case userplatformquota.FieldWeeklyLimitUsd: + m.ResetWeeklyLimitUsd() + return nil + case userplatformquota.FieldMonthlyLimitUsd: + m.ResetMonthlyLimitUsd() + return nil + case userplatformquota.FieldDailyUsageUsd: + m.ResetDailyUsageUsd() + return nil + case userplatformquota.FieldWeeklyUsageUsd: + m.ResetWeeklyUsageUsd() + return nil + case userplatformquota.FieldMonthlyUsageUsd: + m.ResetMonthlyUsageUsd() + return nil + case userplatformquota.FieldDailyWindowStart: + m.ResetDailyWindowStart() + return nil + case userplatformquota.FieldWeeklyWindowStart: + m.ResetWeeklyWindowStart() + return nil + case userplatformquota.FieldMonthlyWindowStart: + m.ResetMonthlyWindowStart() + return nil + } + return fmt.Errorf("unknown UserPlatformQuota field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this mutation. +func (m *UserPlatformQuotaMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.user != nil { + edges = append(edges, userplatformquota.EdgeUser) + } + return edges +} + +// AddedIDs returns all IDs (to other nodes) that were added for the given edge +// name in this mutation. +func (m *UserPlatformQuotaMutation) AddedIDs(name string) []ent.Value { + switch name { + case userplatformquota.EdgeUser: + if id := m.user; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this mutation. +func (m *UserPlatformQuotaMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with +// the given name in this mutation. +func (m *UserPlatformQuotaMutation) RemovedIDs(name string) []ent.Value { + return nil +} + +// ClearedEdges returns all edge names that were cleared in this mutation. +func (m *UserPlatformQuotaMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + if m.cleareduser { + edges = append(edges, userplatformquota.EdgeUser) + } + return edges +} + +// EdgeCleared returns a boolean which indicates if the edge with the given name +// was cleared in this mutation. +func (m *UserPlatformQuotaMutation) EdgeCleared(name string) bool { + switch name { + case userplatformquota.EdgeUser: + return m.cleareduser + } + return false +} + +// ClearEdge clears the value of the edge with the given name. It returns an error +// if that edge is not defined in the schema. +func (m *UserPlatformQuotaMutation) ClearEdge(name string) error { + switch name { + case userplatformquota.EdgeUser: + m.ClearUser() + return nil + } + return fmt.Errorf("unknown UserPlatformQuota unique edge %s", name) +} + +// ResetEdge resets all changes to the edge with the given name in this mutation. +// It returns an error if the edge is not defined in the schema. +func (m *UserPlatformQuotaMutation) ResetEdge(name string) error { + switch name { + case userplatformquota.EdgeUser: + m.ResetUser() + return nil + } + return fmt.Errorf("unknown UserPlatformQuota edge %s", name) +} + // UserSubscriptionMutation represents an operation that mutates the UserSubscription nodes in the graph. type UserSubscriptionMutation struct { config diff --git a/backend/ent/predicate/predicate.go b/backend/ent/predicate/predicate.go index dc86471e..ab4d7d18 100644 --- a/backend/ent/predicate/predicate.go +++ b/backend/ent/predicate/predicate.go @@ -105,5 +105,8 @@ type UserAttributeDefinition func(*sql.Selector) // UserAttributeValue is the predicate function for userattributevalue builders. type UserAttributeValue func(*sql.Selector) +// UserPlatformQuota is the predicate function for userplatformquota builders. +type UserPlatformQuota func(*sql.Selector) + // UserSubscription is the predicate function for usersubscription builders. type UserSubscription func(*sql.Selector) diff --git a/backend/ent/runtime/runtime.go b/backend/ent/runtime/runtime.go index 6d541e2f..aa6130f0 100644 --- a/backend/ent/runtime/runtime.go +++ b/backend/ent/runtime/runtime.go @@ -39,6 +39,7 @@ import ( "github.com/Wei-Shaw/sub2api/ent/userallowedgroup" "github.com/Wei-Shaw/sub2api/ent/userattributedefinition" "github.com/Wei-Shaw/sub2api/ent/userattributevalue" + "github.com/Wei-Shaw/sub2api/ent/userplatformquota" "github.com/Wei-Shaw/sub2api/ent/usersubscription" "github.com/Wei-Shaw/sub2api/internal/domain" ) @@ -1997,6 +1998,56 @@ func init() { userattributevalueDescValue := userattributevalueFields[2].Descriptor() // userattributevalue.DefaultValue holds the default value on creation for the value field. userattributevalue.DefaultValue = userattributevalueDescValue.Default.(string) + userplatformquotaMixin := schema.UserPlatformQuota{}.Mixin() + userplatformquotaMixinHooks1 := userplatformquotaMixin[1].Hooks() + userplatformquota.Hooks[0] = userplatformquotaMixinHooks1[0] + userplatformquotaMixinInters1 := userplatformquotaMixin[1].Interceptors() + userplatformquota.Interceptors[0] = userplatformquotaMixinInters1[0] + userplatformquotaMixinFields0 := userplatformquotaMixin[0].Fields() + _ = userplatformquotaMixinFields0 + userplatformquotaFields := schema.UserPlatformQuota{}.Fields() + _ = userplatformquotaFields + // userplatformquotaDescCreatedAt is the schema descriptor for created_at field. + userplatformquotaDescCreatedAt := userplatformquotaMixinFields0[0].Descriptor() + // userplatformquota.DefaultCreatedAt holds the default value on creation for the created_at field. + userplatformquota.DefaultCreatedAt = userplatformquotaDescCreatedAt.Default.(func() time.Time) + // userplatformquotaDescUpdatedAt is the schema descriptor for updated_at field. + userplatformquotaDescUpdatedAt := userplatformquotaMixinFields0[1].Descriptor() + // userplatformquota.DefaultUpdatedAt holds the default value on creation for the updated_at field. + userplatformquota.DefaultUpdatedAt = userplatformquotaDescUpdatedAt.Default.(func() time.Time) + // userplatformquota.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field. + userplatformquota.UpdateDefaultUpdatedAt = userplatformquotaDescUpdatedAt.UpdateDefault.(func() time.Time) + // userplatformquotaDescPlatform is the schema descriptor for platform field. + userplatformquotaDescPlatform := userplatformquotaFields[1].Descriptor() + // userplatformquota.PlatformValidator is a validator for the "platform" field. It is called by the builders before save. + userplatformquota.PlatformValidator = func() func(string) error { + validators := userplatformquotaDescPlatform.Validators + fns := [...]func(string) error{ + validators[0].(func(string) error), + validators[1].(func(string) error), + validators[2].(func(string) error), + } + return func(platform string) error { + for _, fn := range fns { + if err := fn(platform); err != nil { + return err + } + } + return nil + } + }() + // userplatformquotaDescDailyUsageUsd is the schema descriptor for daily_usage_usd field. + userplatformquotaDescDailyUsageUsd := userplatformquotaFields[5].Descriptor() + // userplatformquota.DefaultDailyUsageUsd holds the default value on creation for the daily_usage_usd field. + userplatformquota.DefaultDailyUsageUsd = userplatformquotaDescDailyUsageUsd.Default.(float64) + // userplatformquotaDescWeeklyUsageUsd is the schema descriptor for weekly_usage_usd field. + userplatformquotaDescWeeklyUsageUsd := userplatformquotaFields[6].Descriptor() + // userplatformquota.DefaultWeeklyUsageUsd holds the default value on creation for the weekly_usage_usd field. + userplatformquota.DefaultWeeklyUsageUsd = userplatformquotaDescWeeklyUsageUsd.Default.(float64) + // userplatformquotaDescMonthlyUsageUsd is the schema descriptor for monthly_usage_usd field. + userplatformquotaDescMonthlyUsageUsd := userplatformquotaFields[7].Descriptor() + // userplatformquota.DefaultMonthlyUsageUsd holds the default value on creation for the monthly_usage_usd field. + userplatformquota.DefaultMonthlyUsageUsd = userplatformquotaDescMonthlyUsageUsd.Default.(float64) usersubscriptionMixin := schema.UserSubscription{}.Mixin() usersubscriptionMixinHooks1 := usersubscriptionMixin[1].Hooks() usersubscription.Hooks[0] = usersubscriptionMixinHooks1[0] diff --git a/backend/ent/schema/user.go b/backend/ent/schema/user.go index c6e04273..127b5af9 100644 --- a/backend/ent/schema/user.go +++ b/backend/ent/schema/user.go @@ -131,6 +131,7 @@ func (User) Edges() []ent.Edge { edge.To("auth_identities", AuthIdentity.Type). Annotations(entsql.OnDelete(entsql.Cascade)), edge.To("pending_auth_sessions", PendingAuthSession.Type), + edge.To("platform_quotas", UserPlatformQuota.Type), } } diff --git a/backend/ent/schema/user_platform_quota.go b/backend/ent/schema/user_platform_quota.go new file mode 100644 index 00000000..8fd8acc0 --- /dev/null +++ b/backend/ent/schema/user_platform_quota.go @@ -0,0 +1,113 @@ +package schema + +import ( + "fmt" + + "entgo.io/ent" + "entgo.io/ent/dialect" + "entgo.io/ent/dialect/entsql" + "entgo.io/ent/schema" + "entgo.io/ent/schema/edge" + "entgo.io/ent/schema/field" + "entgo.io/ent/schema/index" + "github.com/Wei-Shaw/sub2api/ent/schema/mixins" +) + +// UserPlatformQuota holds the schema definition for per-user per-platform quota. +type UserPlatformQuota struct { + ent.Schema +} + +func (UserPlatformQuota) Annotations() []schema.Annotation { + return []schema.Annotation{ + entsql.Annotation{Table: "user_platform_quotas"}, + } +} + +func (UserPlatformQuota) Mixin() []ent.Mixin { + return []ent.Mixin{ + mixins.TimeMixin{}, + mixins.SoftDeleteMixin{}, + } +} + +func (UserPlatformQuota) Fields() []ent.Field { + return []ent.Field{ + field.Int64("user_id"), + field.String("platform"). + MaxLen(32). + NotEmpty(). + Validate(func(s string) error { + // 注意:平台列表的单一权威源为 service.AllowedQuotaPlatforms; + // 此处为 ent 构建期约束,需与 service.AllowedQuotaPlatforms 保持同步。 + switch s { + case "anthropic", "openai", "gemini", "antigravity": + return nil + default: + return fmt.Errorf("platform %q is not allowed", s) + } + }), + + // 日 / 周 / 月 USD 上限: + // nil / not set → 无限额(完全放行) + // 0 → 完全禁用(任何请求都会被拒绝,因为 usage >= 0 恒成立) + // > 0 → USD 限额上限 + field.Float("daily_limit_usd"). + Optional(). + Nillable(). + SchemaType(map[string]string{dialect.Postgres: "decimal(20,10)"}), + field.Float("weekly_limit_usd"). + Optional(). + Nillable(). + SchemaType(map[string]string{dialect.Postgres: "decimal(20,10)"}), + field.Float("monthly_limit_usd"). + Optional(). + Nillable(). + SchemaType(map[string]string{dialect.Postgres: "decimal(20,10)"}), + + // 当前窗口已用量(USD,preflight 时与 limit 比较) + field.Float("daily_usage_usd"). + Default(0). + SchemaType(map[string]string{dialect.Postgres: "decimal(20,10)"}), + field.Float("weekly_usage_usd"). + Default(0). + SchemaType(map[string]string{dialect.Postgres: "decimal(20,10)"}), + field.Float("monthly_usage_usd"). + Default(0). + SchemaType(map[string]string{dialect.Postgres: "decimal(20,10)"}), + + // 窗口起点(NULL = 首次还未初始化,由 InitWindowStarts 用 COALESCE 兜底) + field.Time("daily_window_start"). + Optional(). + Nillable(). + SchemaType(map[string]string{dialect.Postgres: "timestamptz"}), + field.Time("weekly_window_start"). + Optional(). + Nillable(). + SchemaType(map[string]string{dialect.Postgres: "timestamptz"}), + field.Time("monthly_window_start"). + Optional(). + Nillable(). + SchemaType(map[string]string{dialect.Postgres: "timestamptz"}), + } +} + +func (UserPlatformQuota) Edges() []ent.Edge { + return []ent.Edge{ + edge.From("user", User.Type). + Ref("platform_quotas"). + Field("user_id"). + Unique(). + Required(), + } +} + +func (UserPlatformQuota) Indexes() []ent.Index { + return []ent.Index{ + // 软删除友好:只对未删记录唯一 + index.Fields("user_id", "platform"). + Unique(). + Annotations(entsql.IndexWhere("deleted_at IS NULL")), + index.Fields("user_id"), + } +} diff --git a/backend/ent/tx.go b/backend/ent/tx.go index 611028e9..846cfcd4 100644 --- a/backend/ent/tx.go +++ b/backend/ent/tx.go @@ -80,6 +80,8 @@ type Tx struct { UserAttributeDefinition *UserAttributeDefinitionClient // UserAttributeValue is the client for interacting with the UserAttributeValue builders. UserAttributeValue *UserAttributeValueClient + // UserPlatformQuota is the client for interacting with the UserPlatformQuota builders. + UserPlatformQuota *UserPlatformQuotaClient // UserSubscription is the client for interacting with the UserSubscription builders. UserSubscription *UserSubscriptionClient @@ -246,6 +248,7 @@ func (tx *Tx) init() { tx.UserAllowedGroup = NewUserAllowedGroupClient(tx.config) tx.UserAttributeDefinition = NewUserAttributeDefinitionClient(tx.config) tx.UserAttributeValue = NewUserAttributeValueClient(tx.config) + tx.UserPlatformQuota = NewUserPlatformQuotaClient(tx.config) tx.UserSubscription = NewUserSubscriptionClient(tx.config) } diff --git a/backend/ent/user.go b/backend/ent/user.go index 06670444..486f2f64 100644 --- a/backend/ent/user.go +++ b/backend/ent/user.go @@ -95,11 +95,13 @@ type UserEdges struct { AuthIdentities []*AuthIdentity `json:"auth_identities,omitempty"` // PendingAuthSessions holds the value of the pending_auth_sessions edge. PendingAuthSessions []*PendingAuthSession `json:"pending_auth_sessions,omitempty"` + // PlatformQuotas holds the value of the platform_quotas edge. + PlatformQuotas []*UserPlatformQuota `json:"platform_quotas,omitempty"` // UserAllowedGroups holds the value of the user_allowed_groups edge. UserAllowedGroups []*UserAllowedGroup `json:"user_allowed_groups,omitempty"` // loadedTypes holds the information for reporting if a // type was loaded (or requested) in eager-loading or not. - loadedTypes [13]bool + loadedTypes [14]bool } // APIKeysOrErr returns the APIKeys value or an error if the edge @@ -210,10 +212,19 @@ func (e UserEdges) PendingAuthSessionsOrErr() ([]*PendingAuthSession, error) { return nil, &NotLoadedError{edge: "pending_auth_sessions"} } +// PlatformQuotasOrErr returns the PlatformQuotas value or an error if the edge +// was not loaded in eager-loading. +func (e UserEdges) PlatformQuotasOrErr() ([]*UserPlatformQuota, error) { + if e.loadedTypes[12] { + return e.PlatformQuotas, nil + } + return nil, &NotLoadedError{edge: "platform_quotas"} +} + // UserAllowedGroupsOrErr returns the UserAllowedGroups value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) UserAllowedGroupsOrErr() ([]*UserAllowedGroup, error) { - if e.loadedTypes[12] { + if e.loadedTypes[13] { return e.UserAllowedGroups, nil } return nil, &NotLoadedError{edge: "user_allowed_groups"} @@ -472,6 +483,11 @@ func (_m *User) QueryPendingAuthSessions() *PendingAuthSessionQuery { return NewUserClient(_m.config).QueryPendingAuthSessions(_m) } +// QueryPlatformQuotas queries the "platform_quotas" edge of the User entity. +func (_m *User) QueryPlatformQuotas() *UserPlatformQuotaQuery { + return NewUserClient(_m.config).QueryPlatformQuotas(_m) +} + // QueryUserAllowedGroups queries the "user_allowed_groups" edge of the User entity. func (_m *User) QueryUserAllowedGroups() *UserAllowedGroupQuery { return NewUserClient(_m.config).QueryUserAllowedGroups(_m) diff --git a/backend/ent/user/user.go b/backend/ent/user/user.go index e11a8a32..ff40445b 100644 --- a/backend/ent/user/user.go +++ b/backend/ent/user/user.go @@ -85,6 +85,8 @@ const ( EdgeAuthIdentities = "auth_identities" // EdgePendingAuthSessions holds the string denoting the pending_auth_sessions edge name in mutations. EdgePendingAuthSessions = "pending_auth_sessions" + // EdgePlatformQuotas holds the string denoting the platform_quotas edge name in mutations. + EdgePlatformQuotas = "platform_quotas" // EdgeUserAllowedGroups holds the string denoting the user_allowed_groups edge name in mutations. EdgeUserAllowedGroups = "user_allowed_groups" // Table holds the table name of the user in the database. @@ -171,6 +173,13 @@ const ( PendingAuthSessionsInverseTable = "pending_auth_sessions" // PendingAuthSessionsColumn is the table column denoting the pending_auth_sessions relation/edge. PendingAuthSessionsColumn = "target_user_id" + // PlatformQuotasTable is the table that holds the platform_quotas relation/edge. + PlatformQuotasTable = "user_platform_quotas" + // PlatformQuotasInverseTable is the table name for the UserPlatformQuota entity. + // It exists in this package in order to avoid circular dependency with the "userplatformquota" package. + PlatformQuotasInverseTable = "user_platform_quotas" + // PlatformQuotasColumn is the table column denoting the platform_quotas relation/edge. + PlatformQuotasColumn = "user_id" // UserAllowedGroupsTable is the table that holds the user_allowed_groups relation/edge. UserAllowedGroupsTable = "user_allowed_groups" // UserAllowedGroupsInverseTable is the table name for the UserAllowedGroup entity. @@ -569,6 +578,20 @@ func ByPendingAuthSessions(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOpti } } +// ByPlatformQuotasCount orders the results by platform_quotas count. +func ByPlatformQuotasCount(opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborsCount(s, newPlatformQuotasStep(), opts...) + } +} + +// ByPlatformQuotas orders the results by platform_quotas terms. +func ByPlatformQuotas(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newPlatformQuotasStep(), append([]sql.OrderTerm{term}, terms...)...) + } +} + // ByUserAllowedGroupsCount orders the results by user_allowed_groups count. func ByUserAllowedGroupsCount(opts ...sql.OrderTermOption) OrderOption { return func(s *sql.Selector) { @@ -666,6 +689,13 @@ func newPendingAuthSessionsStep() *sqlgraph.Step { sqlgraph.Edge(sqlgraph.O2M, false, PendingAuthSessionsTable, PendingAuthSessionsColumn), ) } +func newPlatformQuotasStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(PlatformQuotasInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, PlatformQuotasTable, PlatformQuotasColumn), + ) +} func newUserAllowedGroupsStep() *sqlgraph.Step { return sqlgraph.NewStep( sqlgraph.From(Table, FieldID), diff --git a/backend/ent/user/where.go b/backend/ent/user/where.go index 05d3b35b..a18cf497 100644 --- a/backend/ent/user/where.go +++ b/backend/ent/user/where.go @@ -1616,6 +1616,29 @@ func HasPendingAuthSessionsWith(preds ...predicate.PendingAuthSession) predicate }) } +// HasPlatformQuotas applies the HasEdge predicate on the "platform_quotas" edge. +func HasPlatformQuotas() predicate.User { + return predicate.User(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, PlatformQuotasTable, PlatformQuotasColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasPlatformQuotasWith applies the HasEdge predicate on the "platform_quotas" edge with a given conditions (other predicates). +func HasPlatformQuotasWith(preds ...predicate.UserPlatformQuota) predicate.User { + return predicate.User(func(s *sql.Selector) { + step := newPlatformQuotasStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + // HasUserAllowedGroups applies the HasEdge predicate on the "user_allowed_groups" edge. func HasUserAllowedGroups() predicate.User { return predicate.User(func(s *sql.Selector) { diff --git a/backend/ent/user_create.go b/backend/ent/user_create.go index b4161128..92f1bd5e 100644 --- a/backend/ent/user_create.go +++ b/backend/ent/user_create.go @@ -22,6 +22,7 @@ import ( "github.com/Wei-Shaw/sub2api/ent/usagelog" "github.com/Wei-Shaw/sub2api/ent/user" "github.com/Wei-Shaw/sub2api/ent/userattributevalue" + "github.com/Wei-Shaw/sub2api/ent/userplatformquota" "github.com/Wei-Shaw/sub2api/ent/usersubscription" ) @@ -519,6 +520,21 @@ func (_c *UserCreate) AddPendingAuthSessions(v ...*PendingAuthSession) *UserCrea return _c.AddPendingAuthSessionIDs(ids...) } +// AddPlatformQuotaIDs adds the "platform_quotas" edge to the UserPlatformQuota entity by IDs. +func (_c *UserCreate) AddPlatformQuotaIDs(ids ...int64) *UserCreate { + _c.mutation.AddPlatformQuotaIDs(ids...) + return _c +} + +// AddPlatformQuotas adds the "platform_quotas" edges to the UserPlatformQuota entity. +func (_c *UserCreate) AddPlatformQuotas(v ...*UserPlatformQuota) *UserCreate { + ids := make([]int64, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _c.AddPlatformQuotaIDs(ids...) +} + // Mutation returns the UserMutation object of the builder. func (_c *UserCreate) Mutation() *UserMutation { return _c.mutation @@ -1023,6 +1039,22 @@ func (_c *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) { } _spec.Edges = append(_spec.Edges, edge) } + if nodes := _c.mutation.PlatformQuotasIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.PlatformQuotasTable, + Columns: []string{user.PlatformQuotasColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(userplatformquota.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } return _node, _spec } diff --git a/backend/ent/user_query.go b/backend/ent/user_query.go index f1ee5cfe..86f4eccd 100644 --- a/backend/ent/user_query.go +++ b/backend/ent/user_query.go @@ -26,6 +26,7 @@ import ( "github.com/Wei-Shaw/sub2api/ent/user" "github.com/Wei-Shaw/sub2api/ent/userallowedgroup" "github.com/Wei-Shaw/sub2api/ent/userattributevalue" + "github.com/Wei-Shaw/sub2api/ent/userplatformquota" "github.com/Wei-Shaw/sub2api/ent/usersubscription" ) @@ -48,6 +49,7 @@ type UserQuery struct { withPaymentOrders *PaymentOrderQuery withAuthIdentities *AuthIdentityQuery withPendingAuthSessions *PendingAuthSessionQuery + withPlatformQuotas *UserPlatformQuotaQuery withUserAllowedGroups *UserAllowedGroupQuery modifiers []func(*sql.Selector) // intermediate query (i.e. traversal path). @@ -350,6 +352,28 @@ func (_q *UserQuery) QueryPendingAuthSessions() *PendingAuthSessionQuery { return query } +// QueryPlatformQuotas chains the current query on the "platform_quotas" edge. +func (_q *UserQuery) QueryPlatformQuotas() *UserPlatformQuotaQuery { + query := (&UserPlatformQuotaClient{config: _q.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := _q.prepareQuery(ctx); err != nil { + return nil, err + } + selector := _q.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(user.Table, user.FieldID, selector), + sqlgraph.To(userplatformquota.Table, userplatformquota.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, user.PlatformQuotasTable, user.PlatformQuotasColumn), + ) + fromU = sqlgraph.SetNeighbors(_q.driver.Dialect(), step) + return fromU, nil + } + return query +} + // QueryUserAllowedGroups chains the current query on the "user_allowed_groups" edge. func (_q *UserQuery) QueryUserAllowedGroups() *UserAllowedGroupQuery { query := (&UserAllowedGroupClient{config: _q.config}).Query() @@ -576,6 +600,7 @@ func (_q *UserQuery) Clone() *UserQuery { withPaymentOrders: _q.withPaymentOrders.Clone(), withAuthIdentities: _q.withAuthIdentities.Clone(), withPendingAuthSessions: _q.withPendingAuthSessions.Clone(), + withPlatformQuotas: _q.withPlatformQuotas.Clone(), withUserAllowedGroups: _q.withUserAllowedGroups.Clone(), // clone intermediate query. sql: _q.sql.Clone(), @@ -715,6 +740,17 @@ func (_q *UserQuery) WithPendingAuthSessions(opts ...func(*PendingAuthSessionQue return _q } +// WithPlatformQuotas tells the query-builder to eager-load the nodes that are connected to +// the "platform_quotas" edge. The optional arguments are used to configure the query builder of the edge. +func (_q *UserQuery) WithPlatformQuotas(opts ...func(*UserPlatformQuotaQuery)) *UserQuery { + query := (&UserPlatformQuotaClient{config: _q.config}).Query() + for _, opt := range opts { + opt(query) + } + _q.withPlatformQuotas = query + return _q +} + // WithUserAllowedGroups tells the query-builder to eager-load the nodes that are connected to // the "user_allowed_groups" edge. The optional arguments are used to configure the query builder of the edge. func (_q *UserQuery) WithUserAllowedGroups(opts ...func(*UserAllowedGroupQuery)) *UserQuery { @@ -804,7 +840,7 @@ func (_q *UserQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*User, e var ( nodes = []*User{} _spec = _q.querySpec() - loadedTypes = [13]bool{ + loadedTypes = [14]bool{ _q.withAPIKeys != nil, _q.withRedeemCodes != nil, _q.withSubscriptions != nil, @@ -817,6 +853,7 @@ func (_q *UserQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*User, e _q.withPaymentOrders != nil, _q.withAuthIdentities != nil, _q.withPendingAuthSessions != nil, + _q.withPlatformQuotas != nil, _q.withUserAllowedGroups != nil, } ) @@ -929,6 +966,13 @@ func (_q *UserQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*User, e return nil, err } } + if query := _q.withPlatformQuotas; query != nil { + if err := _q.loadPlatformQuotas(ctx, query, nodes, + func(n *User) { n.Edges.PlatformQuotas = []*UserPlatformQuota{} }, + func(n *User, e *UserPlatformQuota) { n.Edges.PlatformQuotas = append(n.Edges.PlatformQuotas, e) }); err != nil { + return nil, err + } + } if query := _q.withUserAllowedGroups; query != nil { if err := _q.loadUserAllowedGroups(ctx, query, nodes, func(n *User) { n.Edges.UserAllowedGroups = []*UserAllowedGroup{} }, @@ -1339,6 +1383,36 @@ func (_q *UserQuery) loadPendingAuthSessions(ctx context.Context, query *Pending } return nil } +func (_q *UserQuery) loadPlatformQuotas(ctx context.Context, query *UserPlatformQuotaQuery, nodes []*User, init func(*User), assign func(*User, *UserPlatformQuota)) error { + fks := make([]driver.Value, 0, len(nodes)) + nodeids := make(map[int64]*User) + for i := range nodes { + fks = append(fks, nodes[i].ID) + nodeids[nodes[i].ID] = nodes[i] + if init != nil { + init(nodes[i]) + } + } + if len(query.ctx.Fields) > 0 { + query.ctx.AppendFieldOnce(userplatformquota.FieldUserID) + } + query.Where(predicate.UserPlatformQuota(func(s *sql.Selector) { + s.Where(sql.InValues(s.C(user.PlatformQuotasColumn), fks...)) + })) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + fk := n.UserID + node, ok := nodeids[fk] + if !ok { + return fmt.Errorf(`unexpected referenced foreign-key "user_id" returned %v for node %v`, fk, n.ID) + } + assign(node, n) + } + return nil +} func (_q *UserQuery) loadUserAllowedGroups(ctx context.Context, query *UserAllowedGroupQuery, nodes []*User, init func(*User), assign func(*User, *UserAllowedGroup)) error { fks := make([]driver.Value, 0, len(nodes)) nodeids := make(map[int64]*User) diff --git a/backend/ent/user_update.go b/backend/ent/user_update.go index f1d759ce..67d3f8e6 100644 --- a/backend/ent/user_update.go +++ b/backend/ent/user_update.go @@ -23,6 +23,7 @@ import ( "github.com/Wei-Shaw/sub2api/ent/usagelog" "github.com/Wei-Shaw/sub2api/ent/user" "github.com/Wei-Shaw/sub2api/ent/userattributevalue" + "github.com/Wei-Shaw/sub2api/ent/userplatformquota" "github.com/Wei-Shaw/sub2api/ent/usersubscription" ) @@ -590,6 +591,21 @@ func (_u *UserUpdate) AddPendingAuthSessions(v ...*PendingAuthSession) *UserUpda return _u.AddPendingAuthSessionIDs(ids...) } +// AddPlatformQuotaIDs adds the "platform_quotas" edge to the UserPlatformQuota entity by IDs. +func (_u *UserUpdate) AddPlatformQuotaIDs(ids ...int64) *UserUpdate { + _u.mutation.AddPlatformQuotaIDs(ids...) + return _u +} + +// AddPlatformQuotas adds the "platform_quotas" edges to the UserPlatformQuota entity. +func (_u *UserUpdate) AddPlatformQuotas(v ...*UserPlatformQuota) *UserUpdate { + ids := make([]int64, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _u.AddPlatformQuotaIDs(ids...) +} + // Mutation returns the UserMutation object of the builder. func (_u *UserUpdate) Mutation() *UserMutation { return _u.mutation @@ -847,6 +863,27 @@ func (_u *UserUpdate) RemovePendingAuthSessions(v ...*PendingAuthSession) *UserU return _u.RemovePendingAuthSessionIDs(ids...) } +// ClearPlatformQuotas clears all "platform_quotas" edges to the UserPlatformQuota entity. +func (_u *UserUpdate) ClearPlatformQuotas() *UserUpdate { + _u.mutation.ClearPlatformQuotas() + return _u +} + +// RemovePlatformQuotaIDs removes the "platform_quotas" edge to UserPlatformQuota entities by IDs. +func (_u *UserUpdate) RemovePlatformQuotaIDs(ids ...int64) *UserUpdate { + _u.mutation.RemovePlatformQuotaIDs(ids...) + return _u +} + +// RemovePlatformQuotas removes "platform_quotas" edges to UserPlatformQuota entities. +func (_u *UserUpdate) RemovePlatformQuotas(v ...*UserPlatformQuota) *UserUpdate { + ids := make([]int64, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _u.RemovePlatformQuotaIDs(ids...) +} + // Save executes the query and returns the number of nodes affected by the update operation. func (_u *UserUpdate) Save(ctx context.Context) (int, error) { if err := _u.defaults(); err != nil { @@ -1587,6 +1624,51 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } + if _u.mutation.PlatformQuotasCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.PlatformQuotasTable, + Columns: []string{user.PlatformQuotasColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(userplatformquota.FieldID, field.TypeInt64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.RemovedPlatformQuotasIDs(); len(nodes) > 0 && !_u.mutation.PlatformQuotasCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.PlatformQuotasTable, + Columns: []string{user.PlatformQuotasColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(userplatformquota.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.PlatformQuotasIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.PlatformQuotasTable, + Columns: []string{user.PlatformQuotasColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(userplatformquota.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{user.Label} @@ -2158,6 +2240,21 @@ func (_u *UserUpdateOne) AddPendingAuthSessions(v ...*PendingAuthSession) *UserU return _u.AddPendingAuthSessionIDs(ids...) } +// AddPlatformQuotaIDs adds the "platform_quotas" edge to the UserPlatformQuota entity by IDs. +func (_u *UserUpdateOne) AddPlatformQuotaIDs(ids ...int64) *UserUpdateOne { + _u.mutation.AddPlatformQuotaIDs(ids...) + return _u +} + +// AddPlatformQuotas adds the "platform_quotas" edges to the UserPlatformQuota entity. +func (_u *UserUpdateOne) AddPlatformQuotas(v ...*UserPlatformQuota) *UserUpdateOne { + ids := make([]int64, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _u.AddPlatformQuotaIDs(ids...) +} + // Mutation returns the UserMutation object of the builder. func (_u *UserUpdateOne) Mutation() *UserMutation { return _u.mutation @@ -2415,6 +2512,27 @@ func (_u *UserUpdateOne) RemovePendingAuthSessions(v ...*PendingAuthSession) *Us return _u.RemovePendingAuthSessionIDs(ids...) } +// ClearPlatformQuotas clears all "platform_quotas" edges to the UserPlatformQuota entity. +func (_u *UserUpdateOne) ClearPlatformQuotas() *UserUpdateOne { + _u.mutation.ClearPlatformQuotas() + return _u +} + +// RemovePlatformQuotaIDs removes the "platform_quotas" edge to UserPlatformQuota entities by IDs. +func (_u *UserUpdateOne) RemovePlatformQuotaIDs(ids ...int64) *UserUpdateOne { + _u.mutation.RemovePlatformQuotaIDs(ids...) + return _u +} + +// RemovePlatformQuotas removes "platform_quotas" edges to UserPlatformQuota entities. +func (_u *UserUpdateOne) RemovePlatformQuotas(v ...*UserPlatformQuota) *UserUpdateOne { + ids := make([]int64, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _u.RemovePlatformQuotaIDs(ids...) +} + // Where appends a list predicates to the UserUpdate builder. func (_u *UserUpdateOne) Where(ps ...predicate.User) *UserUpdateOne { _u.mutation.Where(ps...) @@ -3185,6 +3303,51 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } + if _u.mutation.PlatformQuotasCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.PlatformQuotasTable, + Columns: []string{user.PlatformQuotasColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(userplatformquota.FieldID, field.TypeInt64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.RemovedPlatformQuotasIDs(); len(nodes) > 0 && !_u.mutation.PlatformQuotasCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.PlatformQuotasTable, + Columns: []string{user.PlatformQuotasColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(userplatformquota.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.PlatformQuotasIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.PlatformQuotasTable, + Columns: []string{user.PlatformQuotasColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(userplatformquota.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } _node = &User{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues diff --git a/backend/ent/userplatformquota.go b/backend/ent/userplatformquota.go new file mode 100644 index 00000000..d00a1f9a --- /dev/null +++ b/backend/ent/userplatformquota.go @@ -0,0 +1,301 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "fmt" + "strings" + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "github.com/Wei-Shaw/sub2api/ent/user" + "github.com/Wei-Shaw/sub2api/ent/userplatformquota" +) + +// UserPlatformQuota is the model entity for the UserPlatformQuota schema. +type UserPlatformQuota struct { + config `json:"-"` + // ID of the ent. + ID int64 `json:"id,omitempty"` + // CreatedAt holds the value of the "created_at" field. + CreatedAt time.Time `json:"created_at,omitempty"` + // UpdatedAt holds the value of the "updated_at" field. + UpdatedAt time.Time `json:"updated_at,omitempty"` + // DeletedAt holds the value of the "deleted_at" field. + DeletedAt *time.Time `json:"deleted_at,omitempty"` + // UserID holds the value of the "user_id" field. + UserID int64 `json:"user_id,omitempty"` + // Platform holds the value of the "platform" field. + Platform string `json:"platform,omitempty"` + // DailyLimitUsd holds the value of the "daily_limit_usd" field. + DailyLimitUsd *float64 `json:"daily_limit_usd,omitempty"` + // WeeklyLimitUsd holds the value of the "weekly_limit_usd" field. + WeeklyLimitUsd *float64 `json:"weekly_limit_usd,omitempty"` + // MonthlyLimitUsd holds the value of the "monthly_limit_usd" field. + MonthlyLimitUsd *float64 `json:"monthly_limit_usd,omitempty"` + // DailyUsageUsd holds the value of the "daily_usage_usd" field. + DailyUsageUsd float64 `json:"daily_usage_usd,omitempty"` + // WeeklyUsageUsd holds the value of the "weekly_usage_usd" field. + WeeklyUsageUsd float64 `json:"weekly_usage_usd,omitempty"` + // MonthlyUsageUsd holds the value of the "monthly_usage_usd" field. + MonthlyUsageUsd float64 `json:"monthly_usage_usd,omitempty"` + // DailyWindowStart holds the value of the "daily_window_start" field. + DailyWindowStart *time.Time `json:"daily_window_start,omitempty"` + // WeeklyWindowStart holds the value of the "weekly_window_start" field. + WeeklyWindowStart *time.Time `json:"weekly_window_start,omitempty"` + // MonthlyWindowStart holds the value of the "monthly_window_start" field. + MonthlyWindowStart *time.Time `json:"monthly_window_start,omitempty"` + // Edges holds the relations/edges for other nodes in the graph. + // The values are being populated by the UserPlatformQuotaQuery when eager-loading is set. + Edges UserPlatformQuotaEdges `json:"edges"` + selectValues sql.SelectValues +} + +// UserPlatformQuotaEdges holds the relations/edges for other nodes in the graph. +type UserPlatformQuotaEdges struct { + // User holds the value of the user edge. + User *User `json:"user,omitempty"` + // loadedTypes holds the information for reporting if a + // type was loaded (or requested) in eager-loading or not. + loadedTypes [1]bool +} + +// UserOrErr returns the User value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e UserPlatformQuotaEdges) UserOrErr() (*User, error) { + if e.User != nil { + return e.User, nil + } else if e.loadedTypes[0] { + return nil, &NotFoundError{label: user.Label} + } + return nil, &NotLoadedError{edge: "user"} +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*UserPlatformQuota) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) + for i := range columns { + switch columns[i] { + case userplatformquota.FieldDailyLimitUsd, userplatformquota.FieldWeeklyLimitUsd, userplatformquota.FieldMonthlyLimitUsd, userplatformquota.FieldDailyUsageUsd, userplatformquota.FieldWeeklyUsageUsd, userplatformquota.FieldMonthlyUsageUsd: + values[i] = new(sql.NullFloat64) + case userplatformquota.FieldID, userplatformquota.FieldUserID: + values[i] = new(sql.NullInt64) + case userplatformquota.FieldPlatform: + values[i] = new(sql.NullString) + case userplatformquota.FieldCreatedAt, userplatformquota.FieldUpdatedAt, userplatformquota.FieldDeletedAt, userplatformquota.FieldDailyWindowStart, userplatformquota.FieldWeeklyWindowStart, userplatformquota.FieldMonthlyWindowStart: + values[i] = new(sql.NullTime) + default: + values[i] = new(sql.UnknownType) + } + } + return values, nil +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the UserPlatformQuota fields. +func (_m *UserPlatformQuota) assignValues(columns []string, values []any) error { + if m, n := len(values), len(columns); m < n { + return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) + } + for i := range columns { + switch columns[i] { + case userplatformquota.FieldID: + value, ok := values[i].(*sql.NullInt64) + if !ok { + return fmt.Errorf("unexpected type %T for field id", value) + } + _m.ID = int64(value.Int64) + case userplatformquota.FieldCreatedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field created_at", values[i]) + } else if value.Valid { + _m.CreatedAt = value.Time + } + case userplatformquota.FieldUpdatedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field updated_at", values[i]) + } else if value.Valid { + _m.UpdatedAt = value.Time + } + case userplatformquota.FieldDeletedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field deleted_at", values[i]) + } else if value.Valid { + _m.DeletedAt = new(time.Time) + *_m.DeletedAt = value.Time + } + case userplatformquota.FieldUserID: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field user_id", values[i]) + } else if value.Valid { + _m.UserID = value.Int64 + } + case userplatformquota.FieldPlatform: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field platform", values[i]) + } else if value.Valid { + _m.Platform = value.String + } + case userplatformquota.FieldDailyLimitUsd: + if value, ok := values[i].(*sql.NullFloat64); !ok { + return fmt.Errorf("unexpected type %T for field daily_limit_usd", values[i]) + } else if value.Valid { + _m.DailyLimitUsd = new(float64) + *_m.DailyLimitUsd = value.Float64 + } + case userplatformquota.FieldWeeklyLimitUsd: + if value, ok := values[i].(*sql.NullFloat64); !ok { + return fmt.Errorf("unexpected type %T for field weekly_limit_usd", values[i]) + } else if value.Valid { + _m.WeeklyLimitUsd = new(float64) + *_m.WeeklyLimitUsd = value.Float64 + } + case userplatformquota.FieldMonthlyLimitUsd: + if value, ok := values[i].(*sql.NullFloat64); !ok { + return fmt.Errorf("unexpected type %T for field monthly_limit_usd", values[i]) + } else if value.Valid { + _m.MonthlyLimitUsd = new(float64) + *_m.MonthlyLimitUsd = value.Float64 + } + case userplatformquota.FieldDailyUsageUsd: + if value, ok := values[i].(*sql.NullFloat64); !ok { + return fmt.Errorf("unexpected type %T for field daily_usage_usd", values[i]) + } else if value.Valid { + _m.DailyUsageUsd = value.Float64 + } + case userplatformquota.FieldWeeklyUsageUsd: + if value, ok := values[i].(*sql.NullFloat64); !ok { + return fmt.Errorf("unexpected type %T for field weekly_usage_usd", values[i]) + } else if value.Valid { + _m.WeeklyUsageUsd = value.Float64 + } + case userplatformquota.FieldMonthlyUsageUsd: + if value, ok := values[i].(*sql.NullFloat64); !ok { + return fmt.Errorf("unexpected type %T for field monthly_usage_usd", values[i]) + } else if value.Valid { + _m.MonthlyUsageUsd = value.Float64 + } + case userplatformquota.FieldDailyWindowStart: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field daily_window_start", values[i]) + } else if value.Valid { + _m.DailyWindowStart = new(time.Time) + *_m.DailyWindowStart = value.Time + } + case userplatformquota.FieldWeeklyWindowStart: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field weekly_window_start", values[i]) + } else if value.Valid { + _m.WeeklyWindowStart = new(time.Time) + *_m.WeeklyWindowStart = value.Time + } + case userplatformquota.FieldMonthlyWindowStart: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field monthly_window_start", values[i]) + } else if value.Valid { + _m.MonthlyWindowStart = new(time.Time) + *_m.MonthlyWindowStart = value.Time + } + default: + _m.selectValues.Set(columns[i], values[i]) + } + } + return nil +} + +// Value returns the ent.Value that was dynamically selected and assigned to the UserPlatformQuota. +// This includes values selected through modifiers, order, etc. +func (_m *UserPlatformQuota) Value(name string) (ent.Value, error) { + return _m.selectValues.Get(name) +} + +// QueryUser queries the "user" edge of the UserPlatformQuota entity. +func (_m *UserPlatformQuota) QueryUser() *UserQuery { + return NewUserPlatformQuotaClient(_m.config).QueryUser(_m) +} + +// Update returns a builder for updating this UserPlatformQuota. +// Note that you need to call UserPlatformQuota.Unwrap() before calling this method if this UserPlatformQuota +// was returned from a transaction, and the transaction was committed or rolled back. +func (_m *UserPlatformQuota) Update() *UserPlatformQuotaUpdateOne { + return NewUserPlatformQuotaClient(_m.config).UpdateOne(_m) +} + +// Unwrap unwraps the UserPlatformQuota entity that was returned from a transaction after it was closed, +// so that all future queries will be executed through the driver which created the transaction. +func (_m *UserPlatformQuota) Unwrap() *UserPlatformQuota { + _tx, ok := _m.config.driver.(*txDriver) + if !ok { + panic("ent: UserPlatformQuota is not a transactional entity") + } + _m.config.driver = _tx.drv + return _m +} + +// String implements the fmt.Stringer. +func (_m *UserPlatformQuota) String() string { + var builder strings.Builder + builder.WriteString("UserPlatformQuota(") + builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID)) + builder.WriteString("created_at=") + builder.WriteString(_m.CreatedAt.Format(time.ANSIC)) + builder.WriteString(", ") + builder.WriteString("updated_at=") + builder.WriteString(_m.UpdatedAt.Format(time.ANSIC)) + builder.WriteString(", ") + if v := _m.DeletedAt; v != nil { + builder.WriteString("deleted_at=") + builder.WriteString(v.Format(time.ANSIC)) + } + builder.WriteString(", ") + builder.WriteString("user_id=") + builder.WriteString(fmt.Sprintf("%v", _m.UserID)) + builder.WriteString(", ") + builder.WriteString("platform=") + builder.WriteString(_m.Platform) + builder.WriteString(", ") + if v := _m.DailyLimitUsd; v != nil { + builder.WriteString("daily_limit_usd=") + builder.WriteString(fmt.Sprintf("%v", *v)) + } + builder.WriteString(", ") + if v := _m.WeeklyLimitUsd; v != nil { + builder.WriteString("weekly_limit_usd=") + builder.WriteString(fmt.Sprintf("%v", *v)) + } + builder.WriteString(", ") + if v := _m.MonthlyLimitUsd; v != nil { + builder.WriteString("monthly_limit_usd=") + builder.WriteString(fmt.Sprintf("%v", *v)) + } + builder.WriteString(", ") + builder.WriteString("daily_usage_usd=") + builder.WriteString(fmt.Sprintf("%v", _m.DailyUsageUsd)) + builder.WriteString(", ") + builder.WriteString("weekly_usage_usd=") + builder.WriteString(fmt.Sprintf("%v", _m.WeeklyUsageUsd)) + builder.WriteString(", ") + builder.WriteString("monthly_usage_usd=") + builder.WriteString(fmt.Sprintf("%v", _m.MonthlyUsageUsd)) + builder.WriteString(", ") + if v := _m.DailyWindowStart; v != nil { + builder.WriteString("daily_window_start=") + builder.WriteString(v.Format(time.ANSIC)) + } + builder.WriteString(", ") + if v := _m.WeeklyWindowStart; v != nil { + builder.WriteString("weekly_window_start=") + builder.WriteString(v.Format(time.ANSIC)) + } + builder.WriteString(", ") + if v := _m.MonthlyWindowStart; v != nil { + builder.WriteString("monthly_window_start=") + builder.WriteString(v.Format(time.ANSIC)) + } + builder.WriteByte(')') + return builder.String() +} + +// UserPlatformQuotaSlice is a parsable slice of UserPlatformQuota. +type UserPlatformQuotaSlice []*UserPlatformQuota diff --git a/backend/ent/userplatformquota/userplatformquota.go b/backend/ent/userplatformquota/userplatformquota.go new file mode 100644 index 00000000..01903853 --- /dev/null +++ b/backend/ent/userplatformquota/userplatformquota.go @@ -0,0 +1,202 @@ +// Code generated by ent, DO NOT EDIT. + +package userplatformquota + +import ( + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" +) + +const ( + // Label holds the string label denoting the userplatformquota type in the database. + Label = "user_platform_quota" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" + // FieldCreatedAt holds the string denoting the created_at field in the database. + FieldCreatedAt = "created_at" + // FieldUpdatedAt holds the string denoting the updated_at field in the database. + FieldUpdatedAt = "updated_at" + // FieldDeletedAt holds the string denoting the deleted_at field in the database. + FieldDeletedAt = "deleted_at" + // FieldUserID holds the string denoting the user_id field in the database. + FieldUserID = "user_id" + // FieldPlatform holds the string denoting the platform field in the database. + FieldPlatform = "platform" + // FieldDailyLimitUsd holds the string denoting the daily_limit_usd field in the database. + FieldDailyLimitUsd = "daily_limit_usd" + // FieldWeeklyLimitUsd holds the string denoting the weekly_limit_usd field in the database. + FieldWeeklyLimitUsd = "weekly_limit_usd" + // FieldMonthlyLimitUsd holds the string denoting the monthly_limit_usd field in the database. + FieldMonthlyLimitUsd = "monthly_limit_usd" + // FieldDailyUsageUsd holds the string denoting the daily_usage_usd field in the database. + FieldDailyUsageUsd = "daily_usage_usd" + // FieldWeeklyUsageUsd holds the string denoting the weekly_usage_usd field in the database. + FieldWeeklyUsageUsd = "weekly_usage_usd" + // FieldMonthlyUsageUsd holds the string denoting the monthly_usage_usd field in the database. + FieldMonthlyUsageUsd = "monthly_usage_usd" + // FieldDailyWindowStart holds the string denoting the daily_window_start field in the database. + FieldDailyWindowStart = "daily_window_start" + // FieldWeeklyWindowStart holds the string denoting the weekly_window_start field in the database. + FieldWeeklyWindowStart = "weekly_window_start" + // FieldMonthlyWindowStart holds the string denoting the monthly_window_start field in the database. + FieldMonthlyWindowStart = "monthly_window_start" + // EdgeUser holds the string denoting the user edge name in mutations. + EdgeUser = "user" + // Table holds the table name of the userplatformquota in the database. + Table = "user_platform_quotas" + // UserTable is the table that holds the user relation/edge. + UserTable = "user_platform_quotas" + // UserInverseTable is the table name for the User entity. + // It exists in this package in order to avoid circular dependency with the "user" package. + UserInverseTable = "users" + // UserColumn is the table column denoting the user relation/edge. + UserColumn = "user_id" +) + +// Columns holds all SQL columns for userplatformquota fields. +var Columns = []string{ + FieldID, + FieldCreatedAt, + FieldUpdatedAt, + FieldDeletedAt, + FieldUserID, + FieldPlatform, + FieldDailyLimitUsd, + FieldWeeklyLimitUsd, + FieldMonthlyLimitUsd, + FieldDailyUsageUsd, + FieldWeeklyUsageUsd, + FieldMonthlyUsageUsd, + FieldDailyWindowStart, + FieldWeeklyWindowStart, + FieldMonthlyWindowStart, +} + +// ValidColumn reports if the column name is valid (part of the table columns). +func ValidColumn(column string) bool { + for i := range Columns { + if column == Columns[i] { + return true + } + } + return false +} + +// Note that the variables below are initialized by the runtime +// package on the initialization of the application. Therefore, +// it should be imported in the main as follows: +// +// import _ "github.com/Wei-Shaw/sub2api/ent/runtime" +var ( + Hooks [1]ent.Hook + Interceptors [1]ent.Interceptor + // DefaultCreatedAt holds the default value on creation for the "created_at" field. + DefaultCreatedAt func() time.Time + // DefaultUpdatedAt holds the default value on creation for the "updated_at" field. + DefaultUpdatedAt func() time.Time + // UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field. + UpdateDefaultUpdatedAt func() time.Time + // PlatformValidator is a validator for the "platform" field. It is called by the builders before save. + PlatformValidator func(string) error + // DefaultDailyUsageUsd holds the default value on creation for the "daily_usage_usd" field. + DefaultDailyUsageUsd float64 + // DefaultWeeklyUsageUsd holds the default value on creation for the "weekly_usage_usd" field. + DefaultWeeklyUsageUsd float64 + // DefaultMonthlyUsageUsd holds the default value on creation for the "monthly_usage_usd" field. + DefaultMonthlyUsageUsd float64 +) + +// OrderOption defines the ordering options for the UserPlatformQuota queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByCreatedAt orders the results by the created_at field. +func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldCreatedAt, opts...).ToFunc() +} + +// ByUpdatedAt orders the results by the updated_at field. +func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc() +} + +// ByDeletedAt orders the results by the deleted_at field. +func ByDeletedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldDeletedAt, opts...).ToFunc() +} + +// ByUserID orders the results by the user_id field. +func ByUserID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUserID, opts...).ToFunc() +} + +// ByPlatform orders the results by the platform field. +func ByPlatform(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldPlatform, opts...).ToFunc() +} + +// ByDailyLimitUsd orders the results by the daily_limit_usd field. +func ByDailyLimitUsd(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldDailyLimitUsd, opts...).ToFunc() +} + +// ByWeeklyLimitUsd orders the results by the weekly_limit_usd field. +func ByWeeklyLimitUsd(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldWeeklyLimitUsd, opts...).ToFunc() +} + +// ByMonthlyLimitUsd orders the results by the monthly_limit_usd field. +func ByMonthlyLimitUsd(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldMonthlyLimitUsd, opts...).ToFunc() +} + +// ByDailyUsageUsd orders the results by the daily_usage_usd field. +func ByDailyUsageUsd(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldDailyUsageUsd, opts...).ToFunc() +} + +// ByWeeklyUsageUsd orders the results by the weekly_usage_usd field. +func ByWeeklyUsageUsd(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldWeeklyUsageUsd, opts...).ToFunc() +} + +// ByMonthlyUsageUsd orders the results by the monthly_usage_usd field. +func ByMonthlyUsageUsd(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldMonthlyUsageUsd, opts...).ToFunc() +} + +// ByDailyWindowStart orders the results by the daily_window_start field. +func ByDailyWindowStart(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldDailyWindowStart, opts...).ToFunc() +} + +// ByWeeklyWindowStart orders the results by the weekly_window_start field. +func ByWeeklyWindowStart(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldWeeklyWindowStart, opts...).ToFunc() +} + +// ByMonthlyWindowStart orders the results by the monthly_window_start field. +func ByMonthlyWindowStart(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldMonthlyWindowStart, opts...).ToFunc() +} + +// ByUserField orders the results by user field. +func ByUserField(field string, opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newUserStep(), sql.OrderByField(field, opts...)) + } +} +func newUserStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(UserInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, UserTable, UserColumn), + ) +} diff --git a/backend/ent/userplatformquota/where.go b/backend/ent/userplatformquota/where.go new file mode 100644 index 00000000..37d371c6 --- /dev/null +++ b/backend/ent/userplatformquota/where.go @@ -0,0 +1,799 @@ +// Code generated by ent, DO NOT EDIT. + +package userplatformquota + +import ( + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "github.com/Wei-Shaw/sub2api/ent/predicate" +) + +// ID filters vertices based on their ID field. +func ID(id int64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldID, id)) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id int64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldID, id)) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id int64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNEQ(FieldID, id)) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...int64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldIn(FieldID, ids...)) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...int64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNotIn(FieldID, ids...)) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id int64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGT(FieldID, id)) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id int64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGTE(FieldID, id)) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id int64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLT(FieldID, id)) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id int64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLTE(FieldID, id)) +} + +// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ. +func CreatedAt(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldCreatedAt, v)) +} + +// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ. +func UpdatedAt(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldUpdatedAt, v)) +} + +// DeletedAt applies equality check predicate on the "deleted_at" field. It's identical to DeletedAtEQ. +func DeletedAt(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldDeletedAt, v)) +} + +// UserID applies equality check predicate on the "user_id" field. It's identical to UserIDEQ. +func UserID(v int64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldUserID, v)) +} + +// Platform applies equality check predicate on the "platform" field. It's identical to PlatformEQ. +func Platform(v string) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldPlatform, v)) +} + +// DailyLimitUsd applies equality check predicate on the "daily_limit_usd" field. It's identical to DailyLimitUsdEQ. +func DailyLimitUsd(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldDailyLimitUsd, v)) +} + +// WeeklyLimitUsd applies equality check predicate on the "weekly_limit_usd" field. It's identical to WeeklyLimitUsdEQ. +func WeeklyLimitUsd(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldWeeklyLimitUsd, v)) +} + +// MonthlyLimitUsd applies equality check predicate on the "monthly_limit_usd" field. It's identical to MonthlyLimitUsdEQ. +func MonthlyLimitUsd(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldMonthlyLimitUsd, v)) +} + +// DailyUsageUsd applies equality check predicate on the "daily_usage_usd" field. It's identical to DailyUsageUsdEQ. +func DailyUsageUsd(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldDailyUsageUsd, v)) +} + +// WeeklyUsageUsd applies equality check predicate on the "weekly_usage_usd" field. It's identical to WeeklyUsageUsdEQ. +func WeeklyUsageUsd(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldWeeklyUsageUsd, v)) +} + +// MonthlyUsageUsd applies equality check predicate on the "monthly_usage_usd" field. It's identical to MonthlyUsageUsdEQ. +func MonthlyUsageUsd(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldMonthlyUsageUsd, v)) +} + +// DailyWindowStart applies equality check predicate on the "daily_window_start" field. It's identical to DailyWindowStartEQ. +func DailyWindowStart(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldDailyWindowStart, v)) +} + +// WeeklyWindowStart applies equality check predicate on the "weekly_window_start" field. It's identical to WeeklyWindowStartEQ. +func WeeklyWindowStart(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldWeeklyWindowStart, v)) +} + +// MonthlyWindowStart applies equality check predicate on the "monthly_window_start" field. It's identical to MonthlyWindowStartEQ. +func MonthlyWindowStart(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldMonthlyWindowStart, v)) +} + +// CreatedAtEQ applies the EQ predicate on the "created_at" field. +func CreatedAtEQ(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldCreatedAt, v)) +} + +// CreatedAtNEQ applies the NEQ predicate on the "created_at" field. +func CreatedAtNEQ(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNEQ(FieldCreatedAt, v)) +} + +// CreatedAtIn applies the In predicate on the "created_at" field. +func CreatedAtIn(vs ...time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldIn(FieldCreatedAt, vs...)) +} + +// CreatedAtNotIn applies the NotIn predicate on the "created_at" field. +func CreatedAtNotIn(vs ...time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNotIn(FieldCreatedAt, vs...)) +} + +// CreatedAtGT applies the GT predicate on the "created_at" field. +func CreatedAtGT(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGT(FieldCreatedAt, v)) +} + +// CreatedAtGTE applies the GTE predicate on the "created_at" field. +func CreatedAtGTE(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGTE(FieldCreatedAt, v)) +} + +// CreatedAtLT applies the LT predicate on the "created_at" field. +func CreatedAtLT(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLT(FieldCreatedAt, v)) +} + +// CreatedAtLTE applies the LTE predicate on the "created_at" field. +func CreatedAtLTE(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLTE(FieldCreatedAt, v)) +} + +// UpdatedAtEQ applies the EQ predicate on the "updated_at" field. +func UpdatedAtEQ(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldUpdatedAt, v)) +} + +// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field. +func UpdatedAtNEQ(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNEQ(FieldUpdatedAt, v)) +} + +// UpdatedAtIn applies the In predicate on the "updated_at" field. +func UpdatedAtIn(vs ...time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldIn(FieldUpdatedAt, vs...)) +} + +// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field. +func UpdatedAtNotIn(vs ...time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNotIn(FieldUpdatedAt, vs...)) +} + +// UpdatedAtGT applies the GT predicate on the "updated_at" field. +func UpdatedAtGT(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGT(FieldUpdatedAt, v)) +} + +// UpdatedAtGTE applies the GTE predicate on the "updated_at" field. +func UpdatedAtGTE(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGTE(FieldUpdatedAt, v)) +} + +// UpdatedAtLT applies the LT predicate on the "updated_at" field. +func UpdatedAtLT(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLT(FieldUpdatedAt, v)) +} + +// UpdatedAtLTE applies the LTE predicate on the "updated_at" field. +func UpdatedAtLTE(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLTE(FieldUpdatedAt, v)) +} + +// DeletedAtEQ applies the EQ predicate on the "deleted_at" field. +func DeletedAtEQ(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldDeletedAt, v)) +} + +// DeletedAtNEQ applies the NEQ predicate on the "deleted_at" field. +func DeletedAtNEQ(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNEQ(FieldDeletedAt, v)) +} + +// DeletedAtIn applies the In predicate on the "deleted_at" field. +func DeletedAtIn(vs ...time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldIn(FieldDeletedAt, vs...)) +} + +// DeletedAtNotIn applies the NotIn predicate on the "deleted_at" field. +func DeletedAtNotIn(vs ...time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNotIn(FieldDeletedAt, vs...)) +} + +// DeletedAtGT applies the GT predicate on the "deleted_at" field. +func DeletedAtGT(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGT(FieldDeletedAt, v)) +} + +// DeletedAtGTE applies the GTE predicate on the "deleted_at" field. +func DeletedAtGTE(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGTE(FieldDeletedAt, v)) +} + +// DeletedAtLT applies the LT predicate on the "deleted_at" field. +func DeletedAtLT(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLT(FieldDeletedAt, v)) +} + +// DeletedAtLTE applies the LTE predicate on the "deleted_at" field. +func DeletedAtLTE(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLTE(FieldDeletedAt, v)) +} + +// DeletedAtIsNil applies the IsNil predicate on the "deleted_at" field. +func DeletedAtIsNil() predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldIsNull(FieldDeletedAt)) +} + +// DeletedAtNotNil applies the NotNil predicate on the "deleted_at" field. +func DeletedAtNotNil() predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNotNull(FieldDeletedAt)) +} + +// UserIDEQ applies the EQ predicate on the "user_id" field. +func UserIDEQ(v int64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldUserID, v)) +} + +// UserIDNEQ applies the NEQ predicate on the "user_id" field. +func UserIDNEQ(v int64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNEQ(FieldUserID, v)) +} + +// UserIDIn applies the In predicate on the "user_id" field. +func UserIDIn(vs ...int64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldIn(FieldUserID, vs...)) +} + +// UserIDNotIn applies the NotIn predicate on the "user_id" field. +func UserIDNotIn(vs ...int64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNotIn(FieldUserID, vs...)) +} + +// PlatformEQ applies the EQ predicate on the "platform" field. +func PlatformEQ(v string) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldPlatform, v)) +} + +// PlatformNEQ applies the NEQ predicate on the "platform" field. +func PlatformNEQ(v string) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNEQ(FieldPlatform, v)) +} + +// PlatformIn applies the In predicate on the "platform" field. +func PlatformIn(vs ...string) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldIn(FieldPlatform, vs...)) +} + +// PlatformNotIn applies the NotIn predicate on the "platform" field. +func PlatformNotIn(vs ...string) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNotIn(FieldPlatform, vs...)) +} + +// PlatformGT applies the GT predicate on the "platform" field. +func PlatformGT(v string) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGT(FieldPlatform, v)) +} + +// PlatformGTE applies the GTE predicate on the "platform" field. +func PlatformGTE(v string) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGTE(FieldPlatform, v)) +} + +// PlatformLT applies the LT predicate on the "platform" field. +func PlatformLT(v string) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLT(FieldPlatform, v)) +} + +// PlatformLTE applies the LTE predicate on the "platform" field. +func PlatformLTE(v string) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLTE(FieldPlatform, v)) +} + +// PlatformContains applies the Contains predicate on the "platform" field. +func PlatformContains(v string) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldContains(FieldPlatform, v)) +} + +// PlatformHasPrefix applies the HasPrefix predicate on the "platform" field. +func PlatformHasPrefix(v string) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldHasPrefix(FieldPlatform, v)) +} + +// PlatformHasSuffix applies the HasSuffix predicate on the "platform" field. +func PlatformHasSuffix(v string) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldHasSuffix(FieldPlatform, v)) +} + +// PlatformEqualFold applies the EqualFold predicate on the "platform" field. +func PlatformEqualFold(v string) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEqualFold(FieldPlatform, v)) +} + +// PlatformContainsFold applies the ContainsFold predicate on the "platform" field. +func PlatformContainsFold(v string) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldContainsFold(FieldPlatform, v)) +} + +// DailyLimitUsdEQ applies the EQ predicate on the "daily_limit_usd" field. +func DailyLimitUsdEQ(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldDailyLimitUsd, v)) +} + +// DailyLimitUsdNEQ applies the NEQ predicate on the "daily_limit_usd" field. +func DailyLimitUsdNEQ(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNEQ(FieldDailyLimitUsd, v)) +} + +// DailyLimitUsdIn applies the In predicate on the "daily_limit_usd" field. +func DailyLimitUsdIn(vs ...float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldIn(FieldDailyLimitUsd, vs...)) +} + +// DailyLimitUsdNotIn applies the NotIn predicate on the "daily_limit_usd" field. +func DailyLimitUsdNotIn(vs ...float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNotIn(FieldDailyLimitUsd, vs...)) +} + +// DailyLimitUsdGT applies the GT predicate on the "daily_limit_usd" field. +func DailyLimitUsdGT(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGT(FieldDailyLimitUsd, v)) +} + +// DailyLimitUsdGTE applies the GTE predicate on the "daily_limit_usd" field. +func DailyLimitUsdGTE(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGTE(FieldDailyLimitUsd, v)) +} + +// DailyLimitUsdLT applies the LT predicate on the "daily_limit_usd" field. +func DailyLimitUsdLT(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLT(FieldDailyLimitUsd, v)) +} + +// DailyLimitUsdLTE applies the LTE predicate on the "daily_limit_usd" field. +func DailyLimitUsdLTE(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLTE(FieldDailyLimitUsd, v)) +} + +// DailyLimitUsdIsNil applies the IsNil predicate on the "daily_limit_usd" field. +func DailyLimitUsdIsNil() predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldIsNull(FieldDailyLimitUsd)) +} + +// DailyLimitUsdNotNil applies the NotNil predicate on the "daily_limit_usd" field. +func DailyLimitUsdNotNil() predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNotNull(FieldDailyLimitUsd)) +} + +// WeeklyLimitUsdEQ applies the EQ predicate on the "weekly_limit_usd" field. +func WeeklyLimitUsdEQ(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldWeeklyLimitUsd, v)) +} + +// WeeklyLimitUsdNEQ applies the NEQ predicate on the "weekly_limit_usd" field. +func WeeklyLimitUsdNEQ(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNEQ(FieldWeeklyLimitUsd, v)) +} + +// WeeklyLimitUsdIn applies the In predicate on the "weekly_limit_usd" field. +func WeeklyLimitUsdIn(vs ...float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldIn(FieldWeeklyLimitUsd, vs...)) +} + +// WeeklyLimitUsdNotIn applies the NotIn predicate on the "weekly_limit_usd" field. +func WeeklyLimitUsdNotIn(vs ...float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNotIn(FieldWeeklyLimitUsd, vs...)) +} + +// WeeklyLimitUsdGT applies the GT predicate on the "weekly_limit_usd" field. +func WeeklyLimitUsdGT(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGT(FieldWeeklyLimitUsd, v)) +} + +// WeeklyLimitUsdGTE applies the GTE predicate on the "weekly_limit_usd" field. +func WeeklyLimitUsdGTE(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGTE(FieldWeeklyLimitUsd, v)) +} + +// WeeklyLimitUsdLT applies the LT predicate on the "weekly_limit_usd" field. +func WeeklyLimitUsdLT(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLT(FieldWeeklyLimitUsd, v)) +} + +// WeeklyLimitUsdLTE applies the LTE predicate on the "weekly_limit_usd" field. +func WeeklyLimitUsdLTE(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLTE(FieldWeeklyLimitUsd, v)) +} + +// WeeklyLimitUsdIsNil applies the IsNil predicate on the "weekly_limit_usd" field. +func WeeklyLimitUsdIsNil() predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldIsNull(FieldWeeklyLimitUsd)) +} + +// WeeklyLimitUsdNotNil applies the NotNil predicate on the "weekly_limit_usd" field. +func WeeklyLimitUsdNotNil() predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNotNull(FieldWeeklyLimitUsd)) +} + +// MonthlyLimitUsdEQ applies the EQ predicate on the "monthly_limit_usd" field. +func MonthlyLimitUsdEQ(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldMonthlyLimitUsd, v)) +} + +// MonthlyLimitUsdNEQ applies the NEQ predicate on the "monthly_limit_usd" field. +func MonthlyLimitUsdNEQ(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNEQ(FieldMonthlyLimitUsd, v)) +} + +// MonthlyLimitUsdIn applies the In predicate on the "monthly_limit_usd" field. +func MonthlyLimitUsdIn(vs ...float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldIn(FieldMonthlyLimitUsd, vs...)) +} + +// MonthlyLimitUsdNotIn applies the NotIn predicate on the "monthly_limit_usd" field. +func MonthlyLimitUsdNotIn(vs ...float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNotIn(FieldMonthlyLimitUsd, vs...)) +} + +// MonthlyLimitUsdGT applies the GT predicate on the "monthly_limit_usd" field. +func MonthlyLimitUsdGT(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGT(FieldMonthlyLimitUsd, v)) +} + +// MonthlyLimitUsdGTE applies the GTE predicate on the "monthly_limit_usd" field. +func MonthlyLimitUsdGTE(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGTE(FieldMonthlyLimitUsd, v)) +} + +// MonthlyLimitUsdLT applies the LT predicate on the "monthly_limit_usd" field. +func MonthlyLimitUsdLT(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLT(FieldMonthlyLimitUsd, v)) +} + +// MonthlyLimitUsdLTE applies the LTE predicate on the "monthly_limit_usd" field. +func MonthlyLimitUsdLTE(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLTE(FieldMonthlyLimitUsd, v)) +} + +// MonthlyLimitUsdIsNil applies the IsNil predicate on the "monthly_limit_usd" field. +func MonthlyLimitUsdIsNil() predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldIsNull(FieldMonthlyLimitUsd)) +} + +// MonthlyLimitUsdNotNil applies the NotNil predicate on the "monthly_limit_usd" field. +func MonthlyLimitUsdNotNil() predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNotNull(FieldMonthlyLimitUsd)) +} + +// DailyUsageUsdEQ applies the EQ predicate on the "daily_usage_usd" field. +func DailyUsageUsdEQ(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldDailyUsageUsd, v)) +} + +// DailyUsageUsdNEQ applies the NEQ predicate on the "daily_usage_usd" field. +func DailyUsageUsdNEQ(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNEQ(FieldDailyUsageUsd, v)) +} + +// DailyUsageUsdIn applies the In predicate on the "daily_usage_usd" field. +func DailyUsageUsdIn(vs ...float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldIn(FieldDailyUsageUsd, vs...)) +} + +// DailyUsageUsdNotIn applies the NotIn predicate on the "daily_usage_usd" field. +func DailyUsageUsdNotIn(vs ...float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNotIn(FieldDailyUsageUsd, vs...)) +} + +// DailyUsageUsdGT applies the GT predicate on the "daily_usage_usd" field. +func DailyUsageUsdGT(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGT(FieldDailyUsageUsd, v)) +} + +// DailyUsageUsdGTE applies the GTE predicate on the "daily_usage_usd" field. +func DailyUsageUsdGTE(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGTE(FieldDailyUsageUsd, v)) +} + +// DailyUsageUsdLT applies the LT predicate on the "daily_usage_usd" field. +func DailyUsageUsdLT(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLT(FieldDailyUsageUsd, v)) +} + +// DailyUsageUsdLTE applies the LTE predicate on the "daily_usage_usd" field. +func DailyUsageUsdLTE(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLTE(FieldDailyUsageUsd, v)) +} + +// WeeklyUsageUsdEQ applies the EQ predicate on the "weekly_usage_usd" field. +func WeeklyUsageUsdEQ(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldWeeklyUsageUsd, v)) +} + +// WeeklyUsageUsdNEQ applies the NEQ predicate on the "weekly_usage_usd" field. +func WeeklyUsageUsdNEQ(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNEQ(FieldWeeklyUsageUsd, v)) +} + +// WeeklyUsageUsdIn applies the In predicate on the "weekly_usage_usd" field. +func WeeklyUsageUsdIn(vs ...float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldIn(FieldWeeklyUsageUsd, vs...)) +} + +// WeeklyUsageUsdNotIn applies the NotIn predicate on the "weekly_usage_usd" field. +func WeeklyUsageUsdNotIn(vs ...float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNotIn(FieldWeeklyUsageUsd, vs...)) +} + +// WeeklyUsageUsdGT applies the GT predicate on the "weekly_usage_usd" field. +func WeeklyUsageUsdGT(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGT(FieldWeeklyUsageUsd, v)) +} + +// WeeklyUsageUsdGTE applies the GTE predicate on the "weekly_usage_usd" field. +func WeeklyUsageUsdGTE(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGTE(FieldWeeklyUsageUsd, v)) +} + +// WeeklyUsageUsdLT applies the LT predicate on the "weekly_usage_usd" field. +func WeeklyUsageUsdLT(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLT(FieldWeeklyUsageUsd, v)) +} + +// WeeklyUsageUsdLTE applies the LTE predicate on the "weekly_usage_usd" field. +func WeeklyUsageUsdLTE(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLTE(FieldWeeklyUsageUsd, v)) +} + +// MonthlyUsageUsdEQ applies the EQ predicate on the "monthly_usage_usd" field. +func MonthlyUsageUsdEQ(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldMonthlyUsageUsd, v)) +} + +// MonthlyUsageUsdNEQ applies the NEQ predicate on the "monthly_usage_usd" field. +func MonthlyUsageUsdNEQ(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNEQ(FieldMonthlyUsageUsd, v)) +} + +// MonthlyUsageUsdIn applies the In predicate on the "monthly_usage_usd" field. +func MonthlyUsageUsdIn(vs ...float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldIn(FieldMonthlyUsageUsd, vs...)) +} + +// MonthlyUsageUsdNotIn applies the NotIn predicate on the "monthly_usage_usd" field. +func MonthlyUsageUsdNotIn(vs ...float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNotIn(FieldMonthlyUsageUsd, vs...)) +} + +// MonthlyUsageUsdGT applies the GT predicate on the "monthly_usage_usd" field. +func MonthlyUsageUsdGT(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGT(FieldMonthlyUsageUsd, v)) +} + +// MonthlyUsageUsdGTE applies the GTE predicate on the "monthly_usage_usd" field. +func MonthlyUsageUsdGTE(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGTE(FieldMonthlyUsageUsd, v)) +} + +// MonthlyUsageUsdLT applies the LT predicate on the "monthly_usage_usd" field. +func MonthlyUsageUsdLT(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLT(FieldMonthlyUsageUsd, v)) +} + +// MonthlyUsageUsdLTE applies the LTE predicate on the "monthly_usage_usd" field. +func MonthlyUsageUsdLTE(v float64) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLTE(FieldMonthlyUsageUsd, v)) +} + +// DailyWindowStartEQ applies the EQ predicate on the "daily_window_start" field. +func DailyWindowStartEQ(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldDailyWindowStart, v)) +} + +// DailyWindowStartNEQ applies the NEQ predicate on the "daily_window_start" field. +func DailyWindowStartNEQ(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNEQ(FieldDailyWindowStart, v)) +} + +// DailyWindowStartIn applies the In predicate on the "daily_window_start" field. +func DailyWindowStartIn(vs ...time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldIn(FieldDailyWindowStart, vs...)) +} + +// DailyWindowStartNotIn applies the NotIn predicate on the "daily_window_start" field. +func DailyWindowStartNotIn(vs ...time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNotIn(FieldDailyWindowStart, vs...)) +} + +// DailyWindowStartGT applies the GT predicate on the "daily_window_start" field. +func DailyWindowStartGT(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGT(FieldDailyWindowStart, v)) +} + +// DailyWindowStartGTE applies the GTE predicate on the "daily_window_start" field. +func DailyWindowStartGTE(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGTE(FieldDailyWindowStart, v)) +} + +// DailyWindowStartLT applies the LT predicate on the "daily_window_start" field. +func DailyWindowStartLT(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLT(FieldDailyWindowStart, v)) +} + +// DailyWindowStartLTE applies the LTE predicate on the "daily_window_start" field. +func DailyWindowStartLTE(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLTE(FieldDailyWindowStart, v)) +} + +// DailyWindowStartIsNil applies the IsNil predicate on the "daily_window_start" field. +func DailyWindowStartIsNil() predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldIsNull(FieldDailyWindowStart)) +} + +// DailyWindowStartNotNil applies the NotNil predicate on the "daily_window_start" field. +func DailyWindowStartNotNil() predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNotNull(FieldDailyWindowStart)) +} + +// WeeklyWindowStartEQ applies the EQ predicate on the "weekly_window_start" field. +func WeeklyWindowStartEQ(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldWeeklyWindowStart, v)) +} + +// WeeklyWindowStartNEQ applies the NEQ predicate on the "weekly_window_start" field. +func WeeklyWindowStartNEQ(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNEQ(FieldWeeklyWindowStart, v)) +} + +// WeeklyWindowStartIn applies the In predicate on the "weekly_window_start" field. +func WeeklyWindowStartIn(vs ...time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldIn(FieldWeeklyWindowStart, vs...)) +} + +// WeeklyWindowStartNotIn applies the NotIn predicate on the "weekly_window_start" field. +func WeeklyWindowStartNotIn(vs ...time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNotIn(FieldWeeklyWindowStart, vs...)) +} + +// WeeklyWindowStartGT applies the GT predicate on the "weekly_window_start" field. +func WeeklyWindowStartGT(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGT(FieldWeeklyWindowStart, v)) +} + +// WeeklyWindowStartGTE applies the GTE predicate on the "weekly_window_start" field. +func WeeklyWindowStartGTE(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGTE(FieldWeeklyWindowStart, v)) +} + +// WeeklyWindowStartLT applies the LT predicate on the "weekly_window_start" field. +func WeeklyWindowStartLT(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLT(FieldWeeklyWindowStart, v)) +} + +// WeeklyWindowStartLTE applies the LTE predicate on the "weekly_window_start" field. +func WeeklyWindowStartLTE(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLTE(FieldWeeklyWindowStart, v)) +} + +// WeeklyWindowStartIsNil applies the IsNil predicate on the "weekly_window_start" field. +func WeeklyWindowStartIsNil() predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldIsNull(FieldWeeklyWindowStart)) +} + +// WeeklyWindowStartNotNil applies the NotNil predicate on the "weekly_window_start" field. +func WeeklyWindowStartNotNil() predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNotNull(FieldWeeklyWindowStart)) +} + +// MonthlyWindowStartEQ applies the EQ predicate on the "monthly_window_start" field. +func MonthlyWindowStartEQ(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldEQ(FieldMonthlyWindowStart, v)) +} + +// MonthlyWindowStartNEQ applies the NEQ predicate on the "monthly_window_start" field. +func MonthlyWindowStartNEQ(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNEQ(FieldMonthlyWindowStart, v)) +} + +// MonthlyWindowStartIn applies the In predicate on the "monthly_window_start" field. +func MonthlyWindowStartIn(vs ...time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldIn(FieldMonthlyWindowStart, vs...)) +} + +// MonthlyWindowStartNotIn applies the NotIn predicate on the "monthly_window_start" field. +func MonthlyWindowStartNotIn(vs ...time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNotIn(FieldMonthlyWindowStart, vs...)) +} + +// MonthlyWindowStartGT applies the GT predicate on the "monthly_window_start" field. +func MonthlyWindowStartGT(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGT(FieldMonthlyWindowStart, v)) +} + +// MonthlyWindowStartGTE applies the GTE predicate on the "monthly_window_start" field. +func MonthlyWindowStartGTE(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldGTE(FieldMonthlyWindowStart, v)) +} + +// MonthlyWindowStartLT applies the LT predicate on the "monthly_window_start" field. +func MonthlyWindowStartLT(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLT(FieldMonthlyWindowStart, v)) +} + +// MonthlyWindowStartLTE applies the LTE predicate on the "monthly_window_start" field. +func MonthlyWindowStartLTE(v time.Time) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldLTE(FieldMonthlyWindowStart, v)) +} + +// MonthlyWindowStartIsNil applies the IsNil predicate on the "monthly_window_start" field. +func MonthlyWindowStartIsNil() predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldIsNull(FieldMonthlyWindowStart)) +} + +// MonthlyWindowStartNotNil applies the NotNil predicate on the "monthly_window_start" field. +func MonthlyWindowStartNotNil() predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.FieldNotNull(FieldMonthlyWindowStart)) +} + +// HasUser applies the HasEdge predicate on the "user" edge. +func HasUser() predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, UserTable, UserColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasUserWith applies the HasEdge predicate on the "user" edge with a given conditions (other predicates). +func HasUserWith(preds ...predicate.User) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(func(s *sql.Selector) { + step := newUserStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// And groups predicates with the AND operator between them. +func And(predicates ...predicate.UserPlatformQuota) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.AndPredicates(predicates...)) +} + +// Or groups predicates with the OR operator between them. +func Or(predicates ...predicate.UserPlatformQuota) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.OrPredicates(predicates...)) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.UserPlatformQuota) predicate.UserPlatformQuota { + return predicate.UserPlatformQuota(sql.NotPredicates(p)) +} diff --git a/backend/ent/userplatformquota_create.go b/backend/ent/userplatformquota_create.go new file mode 100644 index 00000000..da6c3ce6 --- /dev/null +++ b/backend/ent/userplatformquota_create.go @@ -0,0 +1,1513 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/Wei-Shaw/sub2api/ent/user" + "github.com/Wei-Shaw/sub2api/ent/userplatformquota" +) + +// UserPlatformQuotaCreate is the builder for creating a UserPlatformQuota entity. +type UserPlatformQuotaCreate struct { + config + mutation *UserPlatformQuotaMutation + hooks []Hook + conflict []sql.ConflictOption +} + +// SetCreatedAt sets the "created_at" field. +func (_c *UserPlatformQuotaCreate) SetCreatedAt(v time.Time) *UserPlatformQuotaCreate { + _c.mutation.SetCreatedAt(v) + return _c +} + +// SetNillableCreatedAt sets the "created_at" field if the given value is not nil. +func (_c *UserPlatformQuotaCreate) SetNillableCreatedAt(v *time.Time) *UserPlatformQuotaCreate { + if v != nil { + _c.SetCreatedAt(*v) + } + return _c +} + +// SetUpdatedAt sets the "updated_at" field. +func (_c *UserPlatformQuotaCreate) SetUpdatedAt(v time.Time) *UserPlatformQuotaCreate { + _c.mutation.SetUpdatedAt(v) + return _c +} + +// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. +func (_c *UserPlatformQuotaCreate) SetNillableUpdatedAt(v *time.Time) *UserPlatformQuotaCreate { + if v != nil { + _c.SetUpdatedAt(*v) + } + return _c +} + +// SetDeletedAt sets the "deleted_at" field. +func (_c *UserPlatformQuotaCreate) SetDeletedAt(v time.Time) *UserPlatformQuotaCreate { + _c.mutation.SetDeletedAt(v) + return _c +} + +// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil. +func (_c *UserPlatformQuotaCreate) SetNillableDeletedAt(v *time.Time) *UserPlatformQuotaCreate { + if v != nil { + _c.SetDeletedAt(*v) + } + return _c +} + +// SetUserID sets the "user_id" field. +func (_c *UserPlatformQuotaCreate) SetUserID(v int64) *UserPlatformQuotaCreate { + _c.mutation.SetUserID(v) + return _c +} + +// SetPlatform sets the "platform" field. +func (_c *UserPlatformQuotaCreate) SetPlatform(v string) *UserPlatformQuotaCreate { + _c.mutation.SetPlatform(v) + return _c +} + +// SetDailyLimitUsd sets the "daily_limit_usd" field. +func (_c *UserPlatformQuotaCreate) SetDailyLimitUsd(v float64) *UserPlatformQuotaCreate { + _c.mutation.SetDailyLimitUsd(v) + return _c +} + +// SetNillableDailyLimitUsd sets the "daily_limit_usd" field if the given value is not nil. +func (_c *UserPlatformQuotaCreate) SetNillableDailyLimitUsd(v *float64) *UserPlatformQuotaCreate { + if v != nil { + _c.SetDailyLimitUsd(*v) + } + return _c +} + +// SetWeeklyLimitUsd sets the "weekly_limit_usd" field. +func (_c *UserPlatformQuotaCreate) SetWeeklyLimitUsd(v float64) *UserPlatformQuotaCreate { + _c.mutation.SetWeeklyLimitUsd(v) + return _c +} + +// SetNillableWeeklyLimitUsd sets the "weekly_limit_usd" field if the given value is not nil. +func (_c *UserPlatformQuotaCreate) SetNillableWeeklyLimitUsd(v *float64) *UserPlatformQuotaCreate { + if v != nil { + _c.SetWeeklyLimitUsd(*v) + } + return _c +} + +// SetMonthlyLimitUsd sets the "monthly_limit_usd" field. +func (_c *UserPlatformQuotaCreate) SetMonthlyLimitUsd(v float64) *UserPlatformQuotaCreate { + _c.mutation.SetMonthlyLimitUsd(v) + return _c +} + +// SetNillableMonthlyLimitUsd sets the "monthly_limit_usd" field if the given value is not nil. +func (_c *UserPlatformQuotaCreate) SetNillableMonthlyLimitUsd(v *float64) *UserPlatformQuotaCreate { + if v != nil { + _c.SetMonthlyLimitUsd(*v) + } + return _c +} + +// SetDailyUsageUsd sets the "daily_usage_usd" field. +func (_c *UserPlatformQuotaCreate) SetDailyUsageUsd(v float64) *UserPlatformQuotaCreate { + _c.mutation.SetDailyUsageUsd(v) + return _c +} + +// SetNillableDailyUsageUsd sets the "daily_usage_usd" field if the given value is not nil. +func (_c *UserPlatformQuotaCreate) SetNillableDailyUsageUsd(v *float64) *UserPlatformQuotaCreate { + if v != nil { + _c.SetDailyUsageUsd(*v) + } + return _c +} + +// SetWeeklyUsageUsd sets the "weekly_usage_usd" field. +func (_c *UserPlatformQuotaCreate) SetWeeklyUsageUsd(v float64) *UserPlatformQuotaCreate { + _c.mutation.SetWeeklyUsageUsd(v) + return _c +} + +// SetNillableWeeklyUsageUsd sets the "weekly_usage_usd" field if the given value is not nil. +func (_c *UserPlatformQuotaCreate) SetNillableWeeklyUsageUsd(v *float64) *UserPlatformQuotaCreate { + if v != nil { + _c.SetWeeklyUsageUsd(*v) + } + return _c +} + +// SetMonthlyUsageUsd sets the "monthly_usage_usd" field. +func (_c *UserPlatformQuotaCreate) SetMonthlyUsageUsd(v float64) *UserPlatformQuotaCreate { + _c.mutation.SetMonthlyUsageUsd(v) + return _c +} + +// SetNillableMonthlyUsageUsd sets the "monthly_usage_usd" field if the given value is not nil. +func (_c *UserPlatformQuotaCreate) SetNillableMonthlyUsageUsd(v *float64) *UserPlatformQuotaCreate { + if v != nil { + _c.SetMonthlyUsageUsd(*v) + } + return _c +} + +// SetDailyWindowStart sets the "daily_window_start" field. +func (_c *UserPlatformQuotaCreate) SetDailyWindowStart(v time.Time) *UserPlatformQuotaCreate { + _c.mutation.SetDailyWindowStart(v) + return _c +} + +// SetNillableDailyWindowStart sets the "daily_window_start" field if the given value is not nil. +func (_c *UserPlatformQuotaCreate) SetNillableDailyWindowStart(v *time.Time) *UserPlatformQuotaCreate { + if v != nil { + _c.SetDailyWindowStart(*v) + } + return _c +} + +// SetWeeklyWindowStart sets the "weekly_window_start" field. +func (_c *UserPlatformQuotaCreate) SetWeeklyWindowStart(v time.Time) *UserPlatformQuotaCreate { + _c.mutation.SetWeeklyWindowStart(v) + return _c +} + +// SetNillableWeeklyWindowStart sets the "weekly_window_start" field if the given value is not nil. +func (_c *UserPlatformQuotaCreate) SetNillableWeeklyWindowStart(v *time.Time) *UserPlatformQuotaCreate { + if v != nil { + _c.SetWeeklyWindowStart(*v) + } + return _c +} + +// SetMonthlyWindowStart sets the "monthly_window_start" field. +func (_c *UserPlatformQuotaCreate) SetMonthlyWindowStart(v time.Time) *UserPlatformQuotaCreate { + _c.mutation.SetMonthlyWindowStart(v) + return _c +} + +// SetNillableMonthlyWindowStart sets the "monthly_window_start" field if the given value is not nil. +func (_c *UserPlatformQuotaCreate) SetNillableMonthlyWindowStart(v *time.Time) *UserPlatformQuotaCreate { + if v != nil { + _c.SetMonthlyWindowStart(*v) + } + return _c +} + +// SetUser sets the "user" edge to the User entity. +func (_c *UserPlatformQuotaCreate) SetUser(v *User) *UserPlatformQuotaCreate { + return _c.SetUserID(v.ID) +} + +// Mutation returns the UserPlatformQuotaMutation object of the builder. +func (_c *UserPlatformQuotaCreate) Mutation() *UserPlatformQuotaMutation { + return _c.mutation +} + +// Save creates the UserPlatformQuota in the database. +func (_c *UserPlatformQuotaCreate) Save(ctx context.Context) (*UserPlatformQuota, error) { + if err := _c.defaults(); err != nil { + return nil, err + } + return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks) +} + +// SaveX calls Save and panics if Save returns an error. +func (_c *UserPlatformQuotaCreate) SaveX(ctx context.Context) *UserPlatformQuota { + v, err := _c.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (_c *UserPlatformQuotaCreate) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_c *UserPlatformQuotaCreate) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (_c *UserPlatformQuotaCreate) defaults() error { + if _, ok := _c.mutation.CreatedAt(); !ok { + if userplatformquota.DefaultCreatedAt == nil { + return fmt.Errorf("ent: uninitialized userplatformquota.DefaultCreatedAt (forgotten import ent/runtime?)") + } + v := userplatformquota.DefaultCreatedAt() + _c.mutation.SetCreatedAt(v) + } + if _, ok := _c.mutation.UpdatedAt(); !ok { + if userplatformquota.DefaultUpdatedAt == nil { + return fmt.Errorf("ent: uninitialized userplatformquota.DefaultUpdatedAt (forgotten import ent/runtime?)") + } + v := userplatformquota.DefaultUpdatedAt() + _c.mutation.SetUpdatedAt(v) + } + if _, ok := _c.mutation.DailyUsageUsd(); !ok { + v := userplatformquota.DefaultDailyUsageUsd + _c.mutation.SetDailyUsageUsd(v) + } + if _, ok := _c.mutation.WeeklyUsageUsd(); !ok { + v := userplatformquota.DefaultWeeklyUsageUsd + _c.mutation.SetWeeklyUsageUsd(v) + } + if _, ok := _c.mutation.MonthlyUsageUsd(); !ok { + v := userplatformquota.DefaultMonthlyUsageUsd + _c.mutation.SetMonthlyUsageUsd(v) + } + return nil +} + +// check runs all checks and user-defined validators on the builder. +func (_c *UserPlatformQuotaCreate) check() error { + if _, ok := _c.mutation.CreatedAt(); !ok { + return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "UserPlatformQuota.created_at"`)} + } + if _, ok := _c.mutation.UpdatedAt(); !ok { + return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "UserPlatformQuota.updated_at"`)} + } + if _, ok := _c.mutation.UserID(); !ok { + return &ValidationError{Name: "user_id", err: errors.New(`ent: missing required field "UserPlatformQuota.user_id"`)} + } + if _, ok := _c.mutation.Platform(); !ok { + return &ValidationError{Name: "platform", err: errors.New(`ent: missing required field "UserPlatformQuota.platform"`)} + } + if v, ok := _c.mutation.Platform(); ok { + if err := userplatformquota.PlatformValidator(v); err != nil { + return &ValidationError{Name: "platform", err: fmt.Errorf(`ent: validator failed for field "UserPlatformQuota.platform": %w`, err)} + } + } + if _, ok := _c.mutation.DailyUsageUsd(); !ok { + return &ValidationError{Name: "daily_usage_usd", err: errors.New(`ent: missing required field "UserPlatformQuota.daily_usage_usd"`)} + } + if _, ok := _c.mutation.WeeklyUsageUsd(); !ok { + return &ValidationError{Name: "weekly_usage_usd", err: errors.New(`ent: missing required field "UserPlatformQuota.weekly_usage_usd"`)} + } + if _, ok := _c.mutation.MonthlyUsageUsd(); !ok { + return &ValidationError{Name: "monthly_usage_usd", err: errors.New(`ent: missing required field "UserPlatformQuota.monthly_usage_usd"`)} + } + if len(_c.mutation.UserIDs()) == 0 { + return &ValidationError{Name: "user", err: errors.New(`ent: missing required edge "UserPlatformQuota.user"`)} + } + return nil +} + +func (_c *UserPlatformQuotaCreate) sqlSave(ctx context.Context) (*UserPlatformQuota, error) { + if err := _c.check(); err != nil { + return nil, err + } + _node, _spec := _c.createSpec() + if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + id := _spec.ID.Value.(int64) + _node.ID = int64(id) + _c.mutation.id = &_node.ID + _c.mutation.done = true + return _node, nil +} + +func (_c *UserPlatformQuotaCreate) createSpec() (*UserPlatformQuota, *sqlgraph.CreateSpec) { + var ( + _node = &UserPlatformQuota{config: _c.config} + _spec = sqlgraph.NewCreateSpec(userplatformquota.Table, sqlgraph.NewFieldSpec(userplatformquota.FieldID, field.TypeInt64)) + ) + _spec.OnConflict = _c.conflict + if value, ok := _c.mutation.CreatedAt(); ok { + _spec.SetField(userplatformquota.FieldCreatedAt, field.TypeTime, value) + _node.CreatedAt = value + } + if value, ok := _c.mutation.UpdatedAt(); ok { + _spec.SetField(userplatformquota.FieldUpdatedAt, field.TypeTime, value) + _node.UpdatedAt = value + } + if value, ok := _c.mutation.DeletedAt(); ok { + _spec.SetField(userplatformquota.FieldDeletedAt, field.TypeTime, value) + _node.DeletedAt = &value + } + if value, ok := _c.mutation.Platform(); ok { + _spec.SetField(userplatformquota.FieldPlatform, field.TypeString, value) + _node.Platform = value + } + if value, ok := _c.mutation.DailyLimitUsd(); ok { + _spec.SetField(userplatformquota.FieldDailyLimitUsd, field.TypeFloat64, value) + _node.DailyLimitUsd = &value + } + if value, ok := _c.mutation.WeeklyLimitUsd(); ok { + _spec.SetField(userplatformquota.FieldWeeklyLimitUsd, field.TypeFloat64, value) + _node.WeeklyLimitUsd = &value + } + if value, ok := _c.mutation.MonthlyLimitUsd(); ok { + _spec.SetField(userplatformquota.FieldMonthlyLimitUsd, field.TypeFloat64, value) + _node.MonthlyLimitUsd = &value + } + if value, ok := _c.mutation.DailyUsageUsd(); ok { + _spec.SetField(userplatformquota.FieldDailyUsageUsd, field.TypeFloat64, value) + _node.DailyUsageUsd = value + } + if value, ok := _c.mutation.WeeklyUsageUsd(); ok { + _spec.SetField(userplatformquota.FieldWeeklyUsageUsd, field.TypeFloat64, value) + _node.WeeklyUsageUsd = value + } + if value, ok := _c.mutation.MonthlyUsageUsd(); ok { + _spec.SetField(userplatformquota.FieldMonthlyUsageUsd, field.TypeFloat64, value) + _node.MonthlyUsageUsd = value + } + if value, ok := _c.mutation.DailyWindowStart(); ok { + _spec.SetField(userplatformquota.FieldDailyWindowStart, field.TypeTime, value) + _node.DailyWindowStart = &value + } + if value, ok := _c.mutation.WeeklyWindowStart(); ok { + _spec.SetField(userplatformquota.FieldWeeklyWindowStart, field.TypeTime, value) + _node.WeeklyWindowStart = &value + } + if value, ok := _c.mutation.MonthlyWindowStart(); ok { + _spec.SetField(userplatformquota.FieldMonthlyWindowStart, field.TypeTime, value) + _node.MonthlyWindowStart = &value + } + if nodes := _c.mutation.UserIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: userplatformquota.UserTable, + Columns: []string{userplatformquota.UserColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _node.UserID = nodes[0] + _spec.Edges = append(_spec.Edges, edge) + } + return _node, _spec +} + +// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause +// of the `INSERT` statement. For example: +// +// client.UserPlatformQuota.Create(). +// SetCreatedAt(v). +// OnConflict( +// // Update the row with the new values +// // the was proposed for insertion. +// sql.ResolveWithNewValues(), +// ). +// // Override some of the fields with custom +// // update values. +// Update(func(u *ent.UserPlatformQuotaUpsert) { +// SetCreatedAt(v+v). +// }). +// Exec(ctx) +func (_c *UserPlatformQuotaCreate) OnConflict(opts ...sql.ConflictOption) *UserPlatformQuotaUpsertOne { + _c.conflict = opts + return &UserPlatformQuotaUpsertOne{ + create: _c, + } +} + +// OnConflictColumns calls `OnConflict` and configures the columns +// as conflict target. Using this option is equivalent to using: +// +// client.UserPlatformQuota.Create(). +// OnConflict(sql.ConflictColumns(columns...)). +// Exec(ctx) +func (_c *UserPlatformQuotaCreate) OnConflictColumns(columns ...string) *UserPlatformQuotaUpsertOne { + _c.conflict = append(_c.conflict, sql.ConflictColumns(columns...)) + return &UserPlatformQuotaUpsertOne{ + create: _c, + } +} + +type ( + // UserPlatformQuotaUpsertOne is the builder for "upsert"-ing + // one UserPlatformQuota node. + UserPlatformQuotaUpsertOne struct { + create *UserPlatformQuotaCreate + } + + // UserPlatformQuotaUpsert is the "OnConflict" setter. + UserPlatformQuotaUpsert struct { + *sql.UpdateSet + } +) + +// SetUpdatedAt sets the "updated_at" field. +func (u *UserPlatformQuotaUpsert) SetUpdatedAt(v time.Time) *UserPlatformQuotaUpsert { + u.Set(userplatformquota.FieldUpdatedAt, v) + return u +} + +// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsert) UpdateUpdatedAt() *UserPlatformQuotaUpsert { + u.SetExcluded(userplatformquota.FieldUpdatedAt) + return u +} + +// SetDeletedAt sets the "deleted_at" field. +func (u *UserPlatformQuotaUpsert) SetDeletedAt(v time.Time) *UserPlatformQuotaUpsert { + u.Set(userplatformquota.FieldDeletedAt, v) + return u +} + +// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsert) UpdateDeletedAt() *UserPlatformQuotaUpsert { + u.SetExcluded(userplatformquota.FieldDeletedAt) + return u +} + +// ClearDeletedAt clears the value of the "deleted_at" field. +func (u *UserPlatformQuotaUpsert) ClearDeletedAt() *UserPlatformQuotaUpsert { + u.SetNull(userplatformquota.FieldDeletedAt) + return u +} + +// SetUserID sets the "user_id" field. +func (u *UserPlatformQuotaUpsert) SetUserID(v int64) *UserPlatformQuotaUpsert { + u.Set(userplatformquota.FieldUserID, v) + return u +} + +// UpdateUserID sets the "user_id" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsert) UpdateUserID() *UserPlatformQuotaUpsert { + u.SetExcluded(userplatformquota.FieldUserID) + return u +} + +// SetPlatform sets the "platform" field. +func (u *UserPlatformQuotaUpsert) SetPlatform(v string) *UserPlatformQuotaUpsert { + u.Set(userplatformquota.FieldPlatform, v) + return u +} + +// UpdatePlatform sets the "platform" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsert) UpdatePlatform() *UserPlatformQuotaUpsert { + u.SetExcluded(userplatformquota.FieldPlatform) + return u +} + +// SetDailyLimitUsd sets the "daily_limit_usd" field. +func (u *UserPlatformQuotaUpsert) SetDailyLimitUsd(v float64) *UserPlatformQuotaUpsert { + u.Set(userplatformquota.FieldDailyLimitUsd, v) + return u +} + +// UpdateDailyLimitUsd sets the "daily_limit_usd" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsert) UpdateDailyLimitUsd() *UserPlatformQuotaUpsert { + u.SetExcluded(userplatformquota.FieldDailyLimitUsd) + return u +} + +// AddDailyLimitUsd adds v to the "daily_limit_usd" field. +func (u *UserPlatformQuotaUpsert) AddDailyLimitUsd(v float64) *UserPlatformQuotaUpsert { + u.Add(userplatformquota.FieldDailyLimitUsd, v) + return u +} + +// ClearDailyLimitUsd clears the value of the "daily_limit_usd" field. +func (u *UserPlatformQuotaUpsert) ClearDailyLimitUsd() *UserPlatformQuotaUpsert { + u.SetNull(userplatformquota.FieldDailyLimitUsd) + return u +} + +// SetWeeklyLimitUsd sets the "weekly_limit_usd" field. +func (u *UserPlatformQuotaUpsert) SetWeeklyLimitUsd(v float64) *UserPlatformQuotaUpsert { + u.Set(userplatformquota.FieldWeeklyLimitUsd, v) + return u +} + +// UpdateWeeklyLimitUsd sets the "weekly_limit_usd" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsert) UpdateWeeklyLimitUsd() *UserPlatformQuotaUpsert { + u.SetExcluded(userplatformquota.FieldWeeklyLimitUsd) + return u +} + +// AddWeeklyLimitUsd adds v to the "weekly_limit_usd" field. +func (u *UserPlatformQuotaUpsert) AddWeeklyLimitUsd(v float64) *UserPlatformQuotaUpsert { + u.Add(userplatformquota.FieldWeeklyLimitUsd, v) + return u +} + +// ClearWeeklyLimitUsd clears the value of the "weekly_limit_usd" field. +func (u *UserPlatformQuotaUpsert) ClearWeeklyLimitUsd() *UserPlatformQuotaUpsert { + u.SetNull(userplatformquota.FieldWeeklyLimitUsd) + return u +} + +// SetMonthlyLimitUsd sets the "monthly_limit_usd" field. +func (u *UserPlatformQuotaUpsert) SetMonthlyLimitUsd(v float64) *UserPlatformQuotaUpsert { + u.Set(userplatformquota.FieldMonthlyLimitUsd, v) + return u +} + +// UpdateMonthlyLimitUsd sets the "monthly_limit_usd" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsert) UpdateMonthlyLimitUsd() *UserPlatformQuotaUpsert { + u.SetExcluded(userplatformquota.FieldMonthlyLimitUsd) + return u +} + +// AddMonthlyLimitUsd adds v to the "monthly_limit_usd" field. +func (u *UserPlatformQuotaUpsert) AddMonthlyLimitUsd(v float64) *UserPlatformQuotaUpsert { + u.Add(userplatformquota.FieldMonthlyLimitUsd, v) + return u +} + +// ClearMonthlyLimitUsd clears the value of the "monthly_limit_usd" field. +func (u *UserPlatformQuotaUpsert) ClearMonthlyLimitUsd() *UserPlatformQuotaUpsert { + u.SetNull(userplatformquota.FieldMonthlyLimitUsd) + return u +} + +// SetDailyUsageUsd sets the "daily_usage_usd" field. +func (u *UserPlatformQuotaUpsert) SetDailyUsageUsd(v float64) *UserPlatformQuotaUpsert { + u.Set(userplatformquota.FieldDailyUsageUsd, v) + return u +} + +// UpdateDailyUsageUsd sets the "daily_usage_usd" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsert) UpdateDailyUsageUsd() *UserPlatformQuotaUpsert { + u.SetExcluded(userplatformquota.FieldDailyUsageUsd) + return u +} + +// AddDailyUsageUsd adds v to the "daily_usage_usd" field. +func (u *UserPlatformQuotaUpsert) AddDailyUsageUsd(v float64) *UserPlatformQuotaUpsert { + u.Add(userplatformquota.FieldDailyUsageUsd, v) + return u +} + +// SetWeeklyUsageUsd sets the "weekly_usage_usd" field. +func (u *UserPlatformQuotaUpsert) SetWeeklyUsageUsd(v float64) *UserPlatformQuotaUpsert { + u.Set(userplatformquota.FieldWeeklyUsageUsd, v) + return u +} + +// UpdateWeeklyUsageUsd sets the "weekly_usage_usd" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsert) UpdateWeeklyUsageUsd() *UserPlatformQuotaUpsert { + u.SetExcluded(userplatformquota.FieldWeeklyUsageUsd) + return u +} + +// AddWeeklyUsageUsd adds v to the "weekly_usage_usd" field. +func (u *UserPlatformQuotaUpsert) AddWeeklyUsageUsd(v float64) *UserPlatformQuotaUpsert { + u.Add(userplatformquota.FieldWeeklyUsageUsd, v) + return u +} + +// SetMonthlyUsageUsd sets the "monthly_usage_usd" field. +func (u *UserPlatformQuotaUpsert) SetMonthlyUsageUsd(v float64) *UserPlatformQuotaUpsert { + u.Set(userplatformquota.FieldMonthlyUsageUsd, v) + return u +} + +// UpdateMonthlyUsageUsd sets the "monthly_usage_usd" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsert) UpdateMonthlyUsageUsd() *UserPlatformQuotaUpsert { + u.SetExcluded(userplatformquota.FieldMonthlyUsageUsd) + return u +} + +// AddMonthlyUsageUsd adds v to the "monthly_usage_usd" field. +func (u *UserPlatformQuotaUpsert) AddMonthlyUsageUsd(v float64) *UserPlatformQuotaUpsert { + u.Add(userplatformquota.FieldMonthlyUsageUsd, v) + return u +} + +// SetDailyWindowStart sets the "daily_window_start" field. +func (u *UserPlatformQuotaUpsert) SetDailyWindowStart(v time.Time) *UserPlatformQuotaUpsert { + u.Set(userplatformquota.FieldDailyWindowStart, v) + return u +} + +// UpdateDailyWindowStart sets the "daily_window_start" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsert) UpdateDailyWindowStart() *UserPlatformQuotaUpsert { + u.SetExcluded(userplatformquota.FieldDailyWindowStart) + return u +} + +// ClearDailyWindowStart clears the value of the "daily_window_start" field. +func (u *UserPlatformQuotaUpsert) ClearDailyWindowStart() *UserPlatformQuotaUpsert { + u.SetNull(userplatformquota.FieldDailyWindowStart) + return u +} + +// SetWeeklyWindowStart sets the "weekly_window_start" field. +func (u *UserPlatformQuotaUpsert) SetWeeklyWindowStart(v time.Time) *UserPlatformQuotaUpsert { + u.Set(userplatformquota.FieldWeeklyWindowStart, v) + return u +} + +// UpdateWeeklyWindowStart sets the "weekly_window_start" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsert) UpdateWeeklyWindowStart() *UserPlatformQuotaUpsert { + u.SetExcluded(userplatformquota.FieldWeeklyWindowStart) + return u +} + +// ClearWeeklyWindowStart clears the value of the "weekly_window_start" field. +func (u *UserPlatformQuotaUpsert) ClearWeeklyWindowStart() *UserPlatformQuotaUpsert { + u.SetNull(userplatformquota.FieldWeeklyWindowStart) + return u +} + +// SetMonthlyWindowStart sets the "monthly_window_start" field. +func (u *UserPlatformQuotaUpsert) SetMonthlyWindowStart(v time.Time) *UserPlatformQuotaUpsert { + u.Set(userplatformquota.FieldMonthlyWindowStart, v) + return u +} + +// UpdateMonthlyWindowStart sets the "monthly_window_start" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsert) UpdateMonthlyWindowStart() *UserPlatformQuotaUpsert { + u.SetExcluded(userplatformquota.FieldMonthlyWindowStart) + return u +} + +// ClearMonthlyWindowStart clears the value of the "monthly_window_start" field. +func (u *UserPlatformQuotaUpsert) ClearMonthlyWindowStart() *UserPlatformQuotaUpsert { + u.SetNull(userplatformquota.FieldMonthlyWindowStart) + return u +} + +// UpdateNewValues updates the mutable fields using the new values that were set on create. +// Using this option is equivalent to using: +// +// client.UserPlatformQuota.Create(). +// OnConflict( +// sql.ResolveWithNewValues(), +// ). +// Exec(ctx) +func (u *UserPlatformQuotaUpsertOne) UpdateNewValues() *UserPlatformQuotaUpsertOne { + u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues()) + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) { + if _, exists := u.create.mutation.CreatedAt(); exists { + s.SetIgnore(userplatformquota.FieldCreatedAt) + } + })) + return u +} + +// Ignore sets each column to itself in case of conflict. +// Using this option is equivalent to using: +// +// client.UserPlatformQuota.Create(). +// OnConflict(sql.ResolveWithIgnore()). +// Exec(ctx) +func (u *UserPlatformQuotaUpsertOne) Ignore() *UserPlatformQuotaUpsertOne { + u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore()) + return u +} + +// DoNothing configures the conflict_action to `DO NOTHING`. +// Supported only by SQLite and PostgreSQL. +func (u *UserPlatformQuotaUpsertOne) DoNothing() *UserPlatformQuotaUpsertOne { + u.create.conflict = append(u.create.conflict, sql.DoNothing()) + return u +} + +// Update allows overriding fields `UPDATE` values. See the UserPlatformQuotaCreate.OnConflict +// documentation for more info. +func (u *UserPlatformQuotaUpsertOne) Update(set func(*UserPlatformQuotaUpsert)) *UserPlatformQuotaUpsertOne { + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) { + set(&UserPlatformQuotaUpsert{UpdateSet: update}) + })) + return u +} + +// SetUpdatedAt sets the "updated_at" field. +func (u *UserPlatformQuotaUpsertOne) SetUpdatedAt(v time.Time) *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.SetUpdatedAt(v) + }) +} + +// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsertOne) UpdateUpdatedAt() *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.UpdateUpdatedAt() + }) +} + +// SetDeletedAt sets the "deleted_at" field. +func (u *UserPlatformQuotaUpsertOne) SetDeletedAt(v time.Time) *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.SetDeletedAt(v) + }) +} + +// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsertOne) UpdateDeletedAt() *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.UpdateDeletedAt() + }) +} + +// ClearDeletedAt clears the value of the "deleted_at" field. +func (u *UserPlatformQuotaUpsertOne) ClearDeletedAt() *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.ClearDeletedAt() + }) +} + +// SetUserID sets the "user_id" field. +func (u *UserPlatformQuotaUpsertOne) SetUserID(v int64) *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.SetUserID(v) + }) +} + +// UpdateUserID sets the "user_id" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsertOne) UpdateUserID() *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.UpdateUserID() + }) +} + +// SetPlatform sets the "platform" field. +func (u *UserPlatformQuotaUpsertOne) SetPlatform(v string) *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.SetPlatform(v) + }) +} + +// UpdatePlatform sets the "platform" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsertOne) UpdatePlatform() *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.UpdatePlatform() + }) +} + +// SetDailyLimitUsd sets the "daily_limit_usd" field. +func (u *UserPlatformQuotaUpsertOne) SetDailyLimitUsd(v float64) *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.SetDailyLimitUsd(v) + }) +} + +// AddDailyLimitUsd adds v to the "daily_limit_usd" field. +func (u *UserPlatformQuotaUpsertOne) AddDailyLimitUsd(v float64) *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.AddDailyLimitUsd(v) + }) +} + +// UpdateDailyLimitUsd sets the "daily_limit_usd" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsertOne) UpdateDailyLimitUsd() *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.UpdateDailyLimitUsd() + }) +} + +// ClearDailyLimitUsd clears the value of the "daily_limit_usd" field. +func (u *UserPlatformQuotaUpsertOne) ClearDailyLimitUsd() *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.ClearDailyLimitUsd() + }) +} + +// SetWeeklyLimitUsd sets the "weekly_limit_usd" field. +func (u *UserPlatformQuotaUpsertOne) SetWeeklyLimitUsd(v float64) *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.SetWeeklyLimitUsd(v) + }) +} + +// AddWeeklyLimitUsd adds v to the "weekly_limit_usd" field. +func (u *UserPlatformQuotaUpsertOne) AddWeeklyLimitUsd(v float64) *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.AddWeeklyLimitUsd(v) + }) +} + +// UpdateWeeklyLimitUsd sets the "weekly_limit_usd" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsertOne) UpdateWeeklyLimitUsd() *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.UpdateWeeklyLimitUsd() + }) +} + +// ClearWeeklyLimitUsd clears the value of the "weekly_limit_usd" field. +func (u *UserPlatformQuotaUpsertOne) ClearWeeklyLimitUsd() *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.ClearWeeklyLimitUsd() + }) +} + +// SetMonthlyLimitUsd sets the "monthly_limit_usd" field. +func (u *UserPlatformQuotaUpsertOne) SetMonthlyLimitUsd(v float64) *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.SetMonthlyLimitUsd(v) + }) +} + +// AddMonthlyLimitUsd adds v to the "monthly_limit_usd" field. +func (u *UserPlatformQuotaUpsertOne) AddMonthlyLimitUsd(v float64) *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.AddMonthlyLimitUsd(v) + }) +} + +// UpdateMonthlyLimitUsd sets the "monthly_limit_usd" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsertOne) UpdateMonthlyLimitUsd() *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.UpdateMonthlyLimitUsd() + }) +} + +// ClearMonthlyLimitUsd clears the value of the "monthly_limit_usd" field. +func (u *UserPlatformQuotaUpsertOne) ClearMonthlyLimitUsd() *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.ClearMonthlyLimitUsd() + }) +} + +// SetDailyUsageUsd sets the "daily_usage_usd" field. +func (u *UserPlatformQuotaUpsertOne) SetDailyUsageUsd(v float64) *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.SetDailyUsageUsd(v) + }) +} + +// AddDailyUsageUsd adds v to the "daily_usage_usd" field. +func (u *UserPlatformQuotaUpsertOne) AddDailyUsageUsd(v float64) *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.AddDailyUsageUsd(v) + }) +} + +// UpdateDailyUsageUsd sets the "daily_usage_usd" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsertOne) UpdateDailyUsageUsd() *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.UpdateDailyUsageUsd() + }) +} + +// SetWeeklyUsageUsd sets the "weekly_usage_usd" field. +func (u *UserPlatformQuotaUpsertOne) SetWeeklyUsageUsd(v float64) *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.SetWeeklyUsageUsd(v) + }) +} + +// AddWeeklyUsageUsd adds v to the "weekly_usage_usd" field. +func (u *UserPlatformQuotaUpsertOne) AddWeeklyUsageUsd(v float64) *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.AddWeeklyUsageUsd(v) + }) +} + +// UpdateWeeklyUsageUsd sets the "weekly_usage_usd" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsertOne) UpdateWeeklyUsageUsd() *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.UpdateWeeklyUsageUsd() + }) +} + +// SetMonthlyUsageUsd sets the "monthly_usage_usd" field. +func (u *UserPlatformQuotaUpsertOne) SetMonthlyUsageUsd(v float64) *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.SetMonthlyUsageUsd(v) + }) +} + +// AddMonthlyUsageUsd adds v to the "monthly_usage_usd" field. +func (u *UserPlatformQuotaUpsertOne) AddMonthlyUsageUsd(v float64) *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.AddMonthlyUsageUsd(v) + }) +} + +// UpdateMonthlyUsageUsd sets the "monthly_usage_usd" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsertOne) UpdateMonthlyUsageUsd() *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.UpdateMonthlyUsageUsd() + }) +} + +// SetDailyWindowStart sets the "daily_window_start" field. +func (u *UserPlatformQuotaUpsertOne) SetDailyWindowStart(v time.Time) *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.SetDailyWindowStart(v) + }) +} + +// UpdateDailyWindowStart sets the "daily_window_start" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsertOne) UpdateDailyWindowStart() *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.UpdateDailyWindowStart() + }) +} + +// ClearDailyWindowStart clears the value of the "daily_window_start" field. +func (u *UserPlatformQuotaUpsertOne) ClearDailyWindowStart() *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.ClearDailyWindowStart() + }) +} + +// SetWeeklyWindowStart sets the "weekly_window_start" field. +func (u *UserPlatformQuotaUpsertOne) SetWeeklyWindowStart(v time.Time) *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.SetWeeklyWindowStart(v) + }) +} + +// UpdateWeeklyWindowStart sets the "weekly_window_start" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsertOne) UpdateWeeklyWindowStart() *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.UpdateWeeklyWindowStart() + }) +} + +// ClearWeeklyWindowStart clears the value of the "weekly_window_start" field. +func (u *UserPlatformQuotaUpsertOne) ClearWeeklyWindowStart() *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.ClearWeeklyWindowStart() + }) +} + +// SetMonthlyWindowStart sets the "monthly_window_start" field. +func (u *UserPlatformQuotaUpsertOne) SetMonthlyWindowStart(v time.Time) *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.SetMonthlyWindowStart(v) + }) +} + +// UpdateMonthlyWindowStart sets the "monthly_window_start" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsertOne) UpdateMonthlyWindowStart() *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.UpdateMonthlyWindowStart() + }) +} + +// ClearMonthlyWindowStart clears the value of the "monthly_window_start" field. +func (u *UserPlatformQuotaUpsertOne) ClearMonthlyWindowStart() *UserPlatformQuotaUpsertOne { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.ClearMonthlyWindowStart() + }) +} + +// Exec executes the query. +func (u *UserPlatformQuotaUpsertOne) Exec(ctx context.Context) error { + if len(u.create.conflict) == 0 { + return errors.New("ent: missing options for UserPlatformQuotaCreate.OnConflict") + } + return u.create.Exec(ctx) +} + +// ExecX is like Exec, but panics if an error occurs. +func (u *UserPlatformQuotaUpsertOne) ExecX(ctx context.Context) { + if err := u.create.Exec(ctx); err != nil { + panic(err) + } +} + +// Exec executes the UPSERT query and returns the inserted/updated ID. +func (u *UserPlatformQuotaUpsertOne) ID(ctx context.Context) (id int64, err error) { + node, err := u.create.Save(ctx) + if err != nil { + return id, err + } + return node.ID, nil +} + +// IDX is like ID, but panics if an error occurs. +func (u *UserPlatformQuotaUpsertOne) IDX(ctx context.Context) int64 { + id, err := u.ID(ctx) + if err != nil { + panic(err) + } + return id +} + +// UserPlatformQuotaCreateBulk is the builder for creating many UserPlatformQuota entities in bulk. +type UserPlatformQuotaCreateBulk struct { + config + err error + builders []*UserPlatformQuotaCreate + conflict []sql.ConflictOption +} + +// Save creates the UserPlatformQuota entities in the database. +func (_c *UserPlatformQuotaCreateBulk) Save(ctx context.Context) ([]*UserPlatformQuota, error) { + if _c.err != nil { + return nil, _c.err + } + specs := make([]*sqlgraph.CreateSpec, len(_c.builders)) + nodes := make([]*UserPlatformQuota, len(_c.builders)) + mutators := make([]Mutator, len(_c.builders)) + for i := range _c.builders { + func(i int, root context.Context) { + builder := _c.builders[i] + builder.defaults() + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserPlatformQuotaMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err := builder.check(); err != nil { + return nil, err + } + builder.mutation = mutation + var err error + nodes[i], specs[i] = builder.createSpec() + if i < len(mutators)-1 { + _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) + } else { + spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.OnConflict = _c.conflict + // Invoke the actual operation on the latest mutation in the chain. + if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + } + } + if err != nil { + return nil, err + } + mutation.id = &nodes[i].ID + if specs[i].ID.Value != nil { + id := specs[i].ID.Value.(int64) + nodes[i].ID = int64(id) + } + mutation.done = true + return nodes[i], nil + }) + for i := len(builder.hooks) - 1; i >= 0; i-- { + mut = builder.hooks[i](mut) + } + mutators[i] = mut + }(i, ctx) + } + if len(mutators) > 0 { + if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil { + return nil, err + } + } + return nodes, nil +} + +// SaveX is like Save, but panics if an error occurs. +func (_c *UserPlatformQuotaCreateBulk) SaveX(ctx context.Context) []*UserPlatformQuota { + v, err := _c.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (_c *UserPlatformQuotaCreateBulk) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_c *UserPlatformQuotaCreateBulk) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { + panic(err) + } +} + +// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause +// of the `INSERT` statement. For example: +// +// client.UserPlatformQuota.CreateBulk(builders...). +// OnConflict( +// // Update the row with the new values +// // the was proposed for insertion. +// sql.ResolveWithNewValues(), +// ). +// // Override some of the fields with custom +// // update values. +// Update(func(u *ent.UserPlatformQuotaUpsert) { +// SetCreatedAt(v+v). +// }). +// Exec(ctx) +func (_c *UserPlatformQuotaCreateBulk) OnConflict(opts ...sql.ConflictOption) *UserPlatformQuotaUpsertBulk { + _c.conflict = opts + return &UserPlatformQuotaUpsertBulk{ + create: _c, + } +} + +// OnConflictColumns calls `OnConflict` and configures the columns +// as conflict target. Using this option is equivalent to using: +// +// client.UserPlatformQuota.Create(). +// OnConflict(sql.ConflictColumns(columns...)). +// Exec(ctx) +func (_c *UserPlatformQuotaCreateBulk) OnConflictColumns(columns ...string) *UserPlatformQuotaUpsertBulk { + _c.conflict = append(_c.conflict, sql.ConflictColumns(columns...)) + return &UserPlatformQuotaUpsertBulk{ + create: _c, + } +} + +// UserPlatformQuotaUpsertBulk is the builder for "upsert"-ing +// a bulk of UserPlatformQuota nodes. +type UserPlatformQuotaUpsertBulk struct { + create *UserPlatformQuotaCreateBulk +} + +// UpdateNewValues updates the mutable fields using the new values that +// were set on create. Using this option is equivalent to using: +// +// client.UserPlatformQuota.Create(). +// OnConflict( +// sql.ResolveWithNewValues(), +// ). +// Exec(ctx) +func (u *UserPlatformQuotaUpsertBulk) UpdateNewValues() *UserPlatformQuotaUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues()) + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) { + for _, b := range u.create.builders { + if _, exists := b.mutation.CreatedAt(); exists { + s.SetIgnore(userplatformquota.FieldCreatedAt) + } + } + })) + return u +} + +// Ignore sets each column to itself in case of conflict. +// Using this option is equivalent to using: +// +// client.UserPlatformQuota.Create(). +// OnConflict(sql.ResolveWithIgnore()). +// Exec(ctx) +func (u *UserPlatformQuotaUpsertBulk) Ignore() *UserPlatformQuotaUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore()) + return u +} + +// DoNothing configures the conflict_action to `DO NOTHING`. +// Supported only by SQLite and PostgreSQL. +func (u *UserPlatformQuotaUpsertBulk) DoNothing() *UserPlatformQuotaUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.DoNothing()) + return u +} + +// Update allows overriding fields `UPDATE` values. See the UserPlatformQuotaCreateBulk.OnConflict +// documentation for more info. +func (u *UserPlatformQuotaUpsertBulk) Update(set func(*UserPlatformQuotaUpsert)) *UserPlatformQuotaUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) { + set(&UserPlatformQuotaUpsert{UpdateSet: update}) + })) + return u +} + +// SetUpdatedAt sets the "updated_at" field. +func (u *UserPlatformQuotaUpsertBulk) SetUpdatedAt(v time.Time) *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.SetUpdatedAt(v) + }) +} + +// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsertBulk) UpdateUpdatedAt() *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.UpdateUpdatedAt() + }) +} + +// SetDeletedAt sets the "deleted_at" field. +func (u *UserPlatformQuotaUpsertBulk) SetDeletedAt(v time.Time) *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.SetDeletedAt(v) + }) +} + +// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsertBulk) UpdateDeletedAt() *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.UpdateDeletedAt() + }) +} + +// ClearDeletedAt clears the value of the "deleted_at" field. +func (u *UserPlatformQuotaUpsertBulk) ClearDeletedAt() *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.ClearDeletedAt() + }) +} + +// SetUserID sets the "user_id" field. +func (u *UserPlatformQuotaUpsertBulk) SetUserID(v int64) *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.SetUserID(v) + }) +} + +// UpdateUserID sets the "user_id" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsertBulk) UpdateUserID() *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.UpdateUserID() + }) +} + +// SetPlatform sets the "platform" field. +func (u *UserPlatformQuotaUpsertBulk) SetPlatform(v string) *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.SetPlatform(v) + }) +} + +// UpdatePlatform sets the "platform" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsertBulk) UpdatePlatform() *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.UpdatePlatform() + }) +} + +// SetDailyLimitUsd sets the "daily_limit_usd" field. +func (u *UserPlatformQuotaUpsertBulk) SetDailyLimitUsd(v float64) *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.SetDailyLimitUsd(v) + }) +} + +// AddDailyLimitUsd adds v to the "daily_limit_usd" field. +func (u *UserPlatformQuotaUpsertBulk) AddDailyLimitUsd(v float64) *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.AddDailyLimitUsd(v) + }) +} + +// UpdateDailyLimitUsd sets the "daily_limit_usd" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsertBulk) UpdateDailyLimitUsd() *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.UpdateDailyLimitUsd() + }) +} + +// ClearDailyLimitUsd clears the value of the "daily_limit_usd" field. +func (u *UserPlatformQuotaUpsertBulk) ClearDailyLimitUsd() *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.ClearDailyLimitUsd() + }) +} + +// SetWeeklyLimitUsd sets the "weekly_limit_usd" field. +func (u *UserPlatformQuotaUpsertBulk) SetWeeklyLimitUsd(v float64) *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.SetWeeklyLimitUsd(v) + }) +} + +// AddWeeklyLimitUsd adds v to the "weekly_limit_usd" field. +func (u *UserPlatformQuotaUpsertBulk) AddWeeklyLimitUsd(v float64) *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.AddWeeklyLimitUsd(v) + }) +} + +// UpdateWeeklyLimitUsd sets the "weekly_limit_usd" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsertBulk) UpdateWeeklyLimitUsd() *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.UpdateWeeklyLimitUsd() + }) +} + +// ClearWeeklyLimitUsd clears the value of the "weekly_limit_usd" field. +func (u *UserPlatformQuotaUpsertBulk) ClearWeeklyLimitUsd() *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.ClearWeeklyLimitUsd() + }) +} + +// SetMonthlyLimitUsd sets the "monthly_limit_usd" field. +func (u *UserPlatformQuotaUpsertBulk) SetMonthlyLimitUsd(v float64) *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.SetMonthlyLimitUsd(v) + }) +} + +// AddMonthlyLimitUsd adds v to the "monthly_limit_usd" field. +func (u *UserPlatformQuotaUpsertBulk) AddMonthlyLimitUsd(v float64) *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.AddMonthlyLimitUsd(v) + }) +} + +// UpdateMonthlyLimitUsd sets the "monthly_limit_usd" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsertBulk) UpdateMonthlyLimitUsd() *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.UpdateMonthlyLimitUsd() + }) +} + +// ClearMonthlyLimitUsd clears the value of the "monthly_limit_usd" field. +func (u *UserPlatformQuotaUpsertBulk) ClearMonthlyLimitUsd() *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.ClearMonthlyLimitUsd() + }) +} + +// SetDailyUsageUsd sets the "daily_usage_usd" field. +func (u *UserPlatformQuotaUpsertBulk) SetDailyUsageUsd(v float64) *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.SetDailyUsageUsd(v) + }) +} + +// AddDailyUsageUsd adds v to the "daily_usage_usd" field. +func (u *UserPlatformQuotaUpsertBulk) AddDailyUsageUsd(v float64) *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.AddDailyUsageUsd(v) + }) +} + +// UpdateDailyUsageUsd sets the "daily_usage_usd" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsertBulk) UpdateDailyUsageUsd() *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.UpdateDailyUsageUsd() + }) +} + +// SetWeeklyUsageUsd sets the "weekly_usage_usd" field. +func (u *UserPlatformQuotaUpsertBulk) SetWeeklyUsageUsd(v float64) *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.SetWeeklyUsageUsd(v) + }) +} + +// AddWeeklyUsageUsd adds v to the "weekly_usage_usd" field. +func (u *UserPlatformQuotaUpsertBulk) AddWeeklyUsageUsd(v float64) *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.AddWeeklyUsageUsd(v) + }) +} + +// UpdateWeeklyUsageUsd sets the "weekly_usage_usd" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsertBulk) UpdateWeeklyUsageUsd() *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.UpdateWeeklyUsageUsd() + }) +} + +// SetMonthlyUsageUsd sets the "monthly_usage_usd" field. +func (u *UserPlatformQuotaUpsertBulk) SetMonthlyUsageUsd(v float64) *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.SetMonthlyUsageUsd(v) + }) +} + +// AddMonthlyUsageUsd adds v to the "monthly_usage_usd" field. +func (u *UserPlatformQuotaUpsertBulk) AddMonthlyUsageUsd(v float64) *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.AddMonthlyUsageUsd(v) + }) +} + +// UpdateMonthlyUsageUsd sets the "monthly_usage_usd" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsertBulk) UpdateMonthlyUsageUsd() *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.UpdateMonthlyUsageUsd() + }) +} + +// SetDailyWindowStart sets the "daily_window_start" field. +func (u *UserPlatformQuotaUpsertBulk) SetDailyWindowStart(v time.Time) *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.SetDailyWindowStart(v) + }) +} + +// UpdateDailyWindowStart sets the "daily_window_start" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsertBulk) UpdateDailyWindowStart() *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.UpdateDailyWindowStart() + }) +} + +// ClearDailyWindowStart clears the value of the "daily_window_start" field. +func (u *UserPlatformQuotaUpsertBulk) ClearDailyWindowStart() *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.ClearDailyWindowStart() + }) +} + +// SetWeeklyWindowStart sets the "weekly_window_start" field. +func (u *UserPlatformQuotaUpsertBulk) SetWeeklyWindowStart(v time.Time) *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.SetWeeklyWindowStart(v) + }) +} + +// UpdateWeeklyWindowStart sets the "weekly_window_start" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsertBulk) UpdateWeeklyWindowStart() *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.UpdateWeeklyWindowStart() + }) +} + +// ClearWeeklyWindowStart clears the value of the "weekly_window_start" field. +func (u *UserPlatformQuotaUpsertBulk) ClearWeeklyWindowStart() *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.ClearWeeklyWindowStart() + }) +} + +// SetMonthlyWindowStart sets the "monthly_window_start" field. +func (u *UserPlatformQuotaUpsertBulk) SetMonthlyWindowStart(v time.Time) *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.SetMonthlyWindowStart(v) + }) +} + +// UpdateMonthlyWindowStart sets the "monthly_window_start" field to the value that was provided on create. +func (u *UserPlatformQuotaUpsertBulk) UpdateMonthlyWindowStart() *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.UpdateMonthlyWindowStart() + }) +} + +// ClearMonthlyWindowStart clears the value of the "monthly_window_start" field. +func (u *UserPlatformQuotaUpsertBulk) ClearMonthlyWindowStart() *UserPlatformQuotaUpsertBulk { + return u.Update(func(s *UserPlatformQuotaUpsert) { + s.ClearMonthlyWindowStart() + }) +} + +// Exec executes the query. +func (u *UserPlatformQuotaUpsertBulk) Exec(ctx context.Context) error { + if u.create.err != nil { + return u.create.err + } + for i, b := range u.create.builders { + if len(b.conflict) != 0 { + return fmt.Errorf("ent: OnConflict was set for builder %d. Set it on the UserPlatformQuotaCreateBulk instead", i) + } + } + if len(u.create.conflict) == 0 { + return errors.New("ent: missing options for UserPlatformQuotaCreateBulk.OnConflict") + } + return u.create.Exec(ctx) +} + +// ExecX is like Exec, but panics if an error occurs. +func (u *UserPlatformQuotaUpsertBulk) ExecX(ctx context.Context) { + if err := u.create.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/backend/ent/userplatformquota_delete.go b/backend/ent/userplatformquota_delete.go new file mode 100644 index 00000000..1d80e31b --- /dev/null +++ b/backend/ent/userplatformquota_delete.go @@ -0,0 +1,88 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/Wei-Shaw/sub2api/ent/predicate" + "github.com/Wei-Shaw/sub2api/ent/userplatformquota" +) + +// UserPlatformQuotaDelete is the builder for deleting a UserPlatformQuota entity. +type UserPlatformQuotaDelete struct { + config + hooks []Hook + mutation *UserPlatformQuotaMutation +} + +// Where appends a list predicates to the UserPlatformQuotaDelete builder. +func (_d *UserPlatformQuotaDelete) Where(ps ...predicate.UserPlatformQuota) *UserPlatformQuotaDelete { + _d.mutation.Where(ps...) + return _d +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (_d *UserPlatformQuotaDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks) +} + +// ExecX is like Exec, but panics if an error occurs. +func (_d *UserPlatformQuotaDelete) ExecX(ctx context.Context) int { + n, err := _d.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (_d *UserPlatformQuotaDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(userplatformquota.Table, sqlgraph.NewFieldSpec(userplatformquota.FieldID, field.TypeInt64)) + if ps := _d.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec) + if err != nil && sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + _d.mutation.done = true + return affected, err +} + +// UserPlatformQuotaDeleteOne is the builder for deleting a single UserPlatformQuota entity. +type UserPlatformQuotaDeleteOne struct { + _d *UserPlatformQuotaDelete +} + +// Where appends a list predicates to the UserPlatformQuotaDelete builder. +func (_d *UserPlatformQuotaDeleteOne) Where(ps ...predicate.UserPlatformQuota) *UserPlatformQuotaDeleteOne { + _d._d.mutation.Where(ps...) + return _d +} + +// Exec executes the deletion query. +func (_d *UserPlatformQuotaDeleteOne) Exec(ctx context.Context) error { + n, err := _d._d.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{userplatformquota.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (_d *UserPlatformQuotaDeleteOne) ExecX(ctx context.Context) { + if err := _d.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/backend/ent/userplatformquota_query.go b/backend/ent/userplatformquota_query.go new file mode 100644 index 00000000..c68fe904 --- /dev/null +++ b/backend/ent/userplatformquota_query.go @@ -0,0 +1,643 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + "math" + + "entgo.io/ent" + "entgo.io/ent/dialect" + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/Wei-Shaw/sub2api/ent/predicate" + "github.com/Wei-Shaw/sub2api/ent/user" + "github.com/Wei-Shaw/sub2api/ent/userplatformquota" +) + +// UserPlatformQuotaQuery is the builder for querying UserPlatformQuota entities. +type UserPlatformQuotaQuery struct { + config + ctx *QueryContext + order []userplatformquota.OrderOption + inters []Interceptor + predicates []predicate.UserPlatformQuota + withUser *UserQuery + modifiers []func(*sql.Selector) + // intermediate query (i.e. traversal path). + sql *sql.Selector + path func(context.Context) (*sql.Selector, error) +} + +// Where adds a new predicate for the UserPlatformQuotaQuery builder. +func (_q *UserPlatformQuotaQuery) Where(ps ...predicate.UserPlatformQuota) *UserPlatformQuotaQuery { + _q.predicates = append(_q.predicates, ps...) + return _q +} + +// Limit the number of records to be returned by this query. +func (_q *UserPlatformQuotaQuery) Limit(limit int) *UserPlatformQuotaQuery { + _q.ctx.Limit = &limit + return _q +} + +// Offset to start from. +func (_q *UserPlatformQuotaQuery) Offset(offset int) *UserPlatformQuotaQuery { + _q.ctx.Offset = &offset + return _q +} + +// Unique configures the query builder to filter duplicate records on query. +// By default, unique is set to true, and can be disabled using this method. +func (_q *UserPlatformQuotaQuery) Unique(unique bool) *UserPlatformQuotaQuery { + _q.ctx.Unique = &unique + return _q +} + +// Order specifies how the records should be ordered. +func (_q *UserPlatformQuotaQuery) Order(o ...userplatformquota.OrderOption) *UserPlatformQuotaQuery { + _q.order = append(_q.order, o...) + return _q +} + +// QueryUser chains the current query on the "user" edge. +func (_q *UserPlatformQuotaQuery) QueryUser() *UserQuery { + query := (&UserClient{config: _q.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := _q.prepareQuery(ctx); err != nil { + return nil, err + } + selector := _q.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(userplatformquota.Table, userplatformquota.FieldID, selector), + sqlgraph.To(user.Table, user.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, userplatformquota.UserTable, userplatformquota.UserColumn), + ) + fromU = sqlgraph.SetNeighbors(_q.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// First returns the first UserPlatformQuota entity from the query. +// Returns a *NotFoundError when no UserPlatformQuota was found. +func (_q *UserPlatformQuotaQuery) First(ctx context.Context) (*UserPlatformQuota, error) { + nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst)) + if err != nil { + return nil, err + } + if len(nodes) == 0 { + return nil, &NotFoundError{userplatformquota.Label} + } + return nodes[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (_q *UserPlatformQuotaQuery) FirstX(ctx context.Context) *UserPlatformQuota { + node, err := _q.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return node +} + +// FirstID returns the first UserPlatformQuota ID from the query. +// Returns a *NotFoundError when no UserPlatformQuota ID was found. +func (_q *UserPlatformQuotaQuery) FirstID(ctx context.Context) (id int64, err error) { + var ids []int64 + if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{userplatformquota.Label} + return + } + return ids[0], nil +} + +// FirstIDX is like FirstID, but panics if an error occurs. +func (_q *UserPlatformQuotaQuery) FirstIDX(ctx context.Context) int64 { + id, err := _q.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns a single UserPlatformQuota entity found by the query, ensuring it only returns one. +// Returns a *NotSingularError when more than one UserPlatformQuota entity is found. +// Returns a *NotFoundError when no UserPlatformQuota entities are found. +func (_q *UserPlatformQuotaQuery) Only(ctx context.Context) (*UserPlatformQuota, error) { + nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly)) + if err != nil { + return nil, err + } + switch len(nodes) { + case 1: + return nodes[0], nil + case 0: + return nil, &NotFoundError{userplatformquota.Label} + default: + return nil, &NotSingularError{userplatformquota.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (_q *UserPlatformQuotaQuery) OnlyX(ctx context.Context) *UserPlatformQuota { + node, err := _q.Only(ctx) + if err != nil { + panic(err) + } + return node +} + +// OnlyID is like Only, but returns the only UserPlatformQuota ID in the query. +// Returns a *NotSingularError when more than one UserPlatformQuota ID is found. +// Returns a *NotFoundError when no entities are found. +func (_q *UserPlatformQuotaQuery) OnlyID(ctx context.Context) (id int64, err error) { + var ids []int64 + if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{userplatformquota.Label} + default: + err = &NotSingularError{userplatformquota.Label} + } + return +} + +// OnlyIDX is like OnlyID, but panics if an error occurs. +func (_q *UserPlatformQuotaQuery) OnlyIDX(ctx context.Context) int64 { + id, err := _q.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of UserPlatformQuotaSlice. +func (_q *UserPlatformQuotaQuery) All(ctx context.Context) ([]*UserPlatformQuota, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll) + if err := _q.prepareQuery(ctx); err != nil { + return nil, err + } + qr := querierAll[[]*UserPlatformQuota, *UserPlatformQuotaQuery]() + return withInterceptors[[]*UserPlatformQuota](ctx, _q, qr, _q.inters) +} + +// AllX is like All, but panics if an error occurs. +func (_q *UserPlatformQuotaQuery) AllX(ctx context.Context) []*UserPlatformQuota { + nodes, err := _q.All(ctx) + if err != nil { + panic(err) + } + return nodes +} + +// IDs executes the query and returns a list of UserPlatformQuota IDs. +func (_q *UserPlatformQuotaQuery) IDs(ctx context.Context) (ids []int64, err error) { + if _q.ctx.Unique == nil && _q.path != nil { + _q.Unique(true) + } + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs) + if err = _q.Select(userplatformquota.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (_q *UserPlatformQuotaQuery) IDsX(ctx context.Context) []int64 { + ids, err := _q.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (_q *UserPlatformQuotaQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount) + if err := _q.prepareQuery(ctx); err != nil { + return 0, err + } + return withInterceptors[int](ctx, _q, querierCount[*UserPlatformQuotaQuery](), _q.inters) +} + +// CountX is like Count, but panics if an error occurs. +func (_q *UserPlatformQuotaQuery) CountX(ctx context.Context) int { + count, err := _q.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (_q *UserPlatformQuotaQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist) + switch _, err := _q.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("ent: check existence: %w", err) + default: + return true, nil + } +} + +// ExistX is like Exist, but panics if an error occurs. +func (_q *UserPlatformQuotaQuery) ExistX(ctx context.Context) bool { + exist, err := _q.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the UserPlatformQuotaQuery builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (_q *UserPlatformQuotaQuery) Clone() *UserPlatformQuotaQuery { + if _q == nil { + return nil + } + return &UserPlatformQuotaQuery{ + config: _q.config, + ctx: _q.ctx.Clone(), + order: append([]userplatformquota.OrderOption{}, _q.order...), + inters: append([]Interceptor{}, _q.inters...), + predicates: append([]predicate.UserPlatformQuota{}, _q.predicates...), + withUser: _q.withUser.Clone(), + // clone intermediate query. + sql: _q.sql.Clone(), + path: _q.path, + } +} + +// WithUser tells the query-builder to eager-load the nodes that are connected to +// the "user" edge. The optional arguments are used to configure the query builder of the edge. +func (_q *UserPlatformQuotaQuery) WithUser(opts ...func(*UserQuery)) *UserPlatformQuotaQuery { + query := (&UserClient{config: _q.config}).Query() + for _, opt := range opts { + opt(query) + } + _q.withUser = query + return _q +} + +// GroupBy is used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +// +// Example: +// +// var v []struct { +// CreatedAt time.Time `json:"created_at,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.UserPlatformQuota.Query(). +// GroupBy(userplatformquota.FieldCreatedAt). +// Aggregate(ent.Count()). +// Scan(ctx, &v) +func (_q *UserPlatformQuotaQuery) GroupBy(field string, fields ...string) *UserPlatformQuotaGroupBy { + _q.ctx.Fields = append([]string{field}, fields...) + grbuild := &UserPlatformQuotaGroupBy{build: _q} + grbuild.flds = &_q.ctx.Fields + grbuild.label = userplatformquota.Label + grbuild.scan = grbuild.Scan + return grbuild +} + +// Select allows the selection one or more fields/columns for the given query, +// instead of selecting all fields in the entity. +// +// Example: +// +// var v []struct { +// CreatedAt time.Time `json:"created_at,omitempty"` +// } +// +// client.UserPlatformQuota.Query(). +// Select(userplatformquota.FieldCreatedAt). +// Scan(ctx, &v) +func (_q *UserPlatformQuotaQuery) Select(fields ...string) *UserPlatformQuotaSelect { + _q.ctx.Fields = append(_q.ctx.Fields, fields...) + sbuild := &UserPlatformQuotaSelect{UserPlatformQuotaQuery: _q} + sbuild.label = userplatformquota.Label + sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a UserPlatformQuotaSelect configured with the given aggregations. +func (_q *UserPlatformQuotaQuery) Aggregate(fns ...AggregateFunc) *UserPlatformQuotaSelect { + return _q.Select().Aggregate(fns...) +} + +func (_q *UserPlatformQuotaQuery) prepareQuery(ctx context.Context) error { + for _, inter := range _q.inters { + if inter == nil { + return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, _q); err != nil { + return err + } + } + } + for _, f := range _q.ctx.Fields { + if !userplatformquota.ValidColumn(f) { + return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + } + if _q.path != nil { + prev, err := _q.path(ctx) + if err != nil { + return err + } + _q.sql = prev + } + return nil +} + +func (_q *UserPlatformQuotaQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*UserPlatformQuota, error) { + var ( + nodes = []*UserPlatformQuota{} + _spec = _q.querySpec() + loadedTypes = [1]bool{ + _q.withUser != nil, + } + ) + _spec.ScanValues = func(columns []string) ([]any, error) { + return (*UserPlatformQuota).scanValues(nil, columns) + } + _spec.Assign = func(columns []string, values []any) error { + node := &UserPlatformQuota{config: _q.config} + nodes = append(nodes, node) + node.Edges.loadedTypes = loadedTypes + return node.assignValues(columns, values) + } + if len(_q.modifiers) > 0 { + _spec.Modifiers = _q.modifiers + } + for i := range hooks { + hooks[i](ctx, _spec) + } + if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + if query := _q.withUser; query != nil { + if err := _q.loadUser(ctx, query, nodes, nil, + func(n *UserPlatformQuota, e *User) { n.Edges.User = e }); err != nil { + return nil, err + } + } + return nodes, nil +} + +func (_q *UserPlatformQuotaQuery) loadUser(ctx context.Context, query *UserQuery, nodes []*UserPlatformQuota, init func(*UserPlatformQuota), assign func(*UserPlatformQuota, *User)) error { + ids := make([]int64, 0, len(nodes)) + nodeids := make(map[int64][]*UserPlatformQuota) + for i := range nodes { + fk := nodes[i].UserID + if _, ok := nodeids[fk]; !ok { + ids = append(ids, fk) + } + nodeids[fk] = append(nodeids[fk], nodes[i]) + } + if len(ids) == 0 { + return nil + } + query.Where(user.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return fmt.Errorf(`unexpected foreign-key "user_id" returned %v`, n.ID) + } + for i := range nodes { + assign(nodes[i], n) + } + } + return nil +} + +func (_q *UserPlatformQuotaQuery) sqlCount(ctx context.Context) (int, error) { + _spec := _q.querySpec() + if len(_q.modifiers) > 0 { + _spec.Modifiers = _q.modifiers + } + _spec.Node.Columns = _q.ctx.Fields + if len(_q.ctx.Fields) > 0 { + _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique + } + return sqlgraph.CountNodes(ctx, _q.driver, _spec) +} + +func (_q *UserPlatformQuotaQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(userplatformquota.Table, userplatformquota.Columns, sqlgraph.NewFieldSpec(userplatformquota.FieldID, field.TypeInt64)) + _spec.From = _q.sql + if unique := _q.ctx.Unique; unique != nil { + _spec.Unique = *unique + } else if _q.path != nil { + _spec.Unique = true + } + if fields := _q.ctx.Fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, userplatformquota.FieldID) + for i := range fields { + if fields[i] != userplatformquota.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) + } + } + if _q.withUser != nil { + _spec.Node.AddColumnOnce(userplatformquota.FieldUserID) + } + } + if ps := _q.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := _q.ctx.Limit; limit != nil { + _spec.Limit = *limit + } + if offset := _q.ctx.Offset; offset != nil { + _spec.Offset = *offset + } + if ps := _q.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (_q *UserPlatformQuotaQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(_q.driver.Dialect()) + t1 := builder.Table(userplatformquota.Table) + columns := _q.ctx.Fields + if len(columns) == 0 { + columns = userplatformquota.Columns + } + selector := builder.Select(t1.Columns(columns...)...).From(t1) + if _q.sql != nil { + selector = _q.sql + selector.Select(selector.Columns(columns...)...) + } + if _q.ctx.Unique != nil && *_q.ctx.Unique { + selector.Distinct() + } + for _, m := range _q.modifiers { + m(selector) + } + for _, p := range _q.predicates { + p(selector) + } + for _, p := range _q.order { + p(selector) + } + if offset := _q.ctx.Offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := _q.ctx.Limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// ForUpdate locks the selected rows against concurrent updates, and prevent them from being +// updated, deleted or "selected ... for update" by other sessions, until the transaction is +// either committed or rolled-back. +func (_q *UserPlatformQuotaQuery) ForUpdate(opts ...sql.LockOption) *UserPlatformQuotaQuery { + if _q.driver.Dialect() == dialect.Postgres { + _q.Unique(false) + } + _q.modifiers = append(_q.modifiers, func(s *sql.Selector) { + s.ForUpdate(opts...) + }) + return _q +} + +// ForShare behaves similarly to ForUpdate, except that it acquires a shared mode lock +// on any rows that are read. Other sessions can read the rows, but cannot modify them +// until your transaction commits. +func (_q *UserPlatformQuotaQuery) ForShare(opts ...sql.LockOption) *UserPlatformQuotaQuery { + if _q.driver.Dialect() == dialect.Postgres { + _q.Unique(false) + } + _q.modifiers = append(_q.modifiers, func(s *sql.Selector) { + s.ForShare(opts...) + }) + return _q +} + +// UserPlatformQuotaGroupBy is the group-by builder for UserPlatformQuota entities. +type UserPlatformQuotaGroupBy struct { + selector + build *UserPlatformQuotaQuery +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (_g *UserPlatformQuotaGroupBy) Aggregate(fns ...AggregateFunc) *UserPlatformQuotaGroupBy { + _g.fns = append(_g.fns, fns...) + return _g +} + +// Scan applies the selector query and scans the result into the given value. +func (_g *UserPlatformQuotaGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy) + if err := _g.build.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*UserPlatformQuotaQuery, *UserPlatformQuotaGroupBy](ctx, _g.build, _g, _g.build.inters, v) +} + +func (_g *UserPlatformQuotaGroupBy) sqlScan(ctx context.Context, root *UserPlatformQuotaQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(_g.fns)) + for _, fn := range _g.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*_g.flds)+len(_g.fns)) + for _, f := range *_g.flds { + columns = append(columns, selector.C(f)) + } + columns = append(columns, aggregation...) + selector.Select(columns...) + } + selector.GroupBy(selector.Columns(*_g.flds...)...) + if err := selector.Err(); err != nil { + return err + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := _g.build.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +// UserPlatformQuotaSelect is the builder for selecting fields of UserPlatformQuota entities. +type UserPlatformQuotaSelect struct { + *UserPlatformQuotaQuery + selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (_s *UserPlatformQuotaSelect) Aggregate(fns ...AggregateFunc) *UserPlatformQuotaSelect { + _s.fns = append(_s.fns, fns...) + return _s +} + +// Scan applies the selector query and scans the result into the given value. +func (_s *UserPlatformQuotaSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect) + if err := _s.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*UserPlatformQuotaQuery, *UserPlatformQuotaSelect](ctx, _s.UserPlatformQuotaQuery, _s, _s.inters, v) +} + +func (_s *UserPlatformQuotaSelect) sqlScan(ctx context.Context, root *UserPlatformQuotaQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(_s.fns)) + for _, fn := range _s.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*_s.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := _s.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} diff --git a/backend/ent/userplatformquota_update.go b/backend/ent/userplatformquota_update.go new file mode 100644 index 00000000..4e924cc8 --- /dev/null +++ b/backend/ent/userplatformquota_update.go @@ -0,0 +1,985 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/Wei-Shaw/sub2api/ent/predicate" + "github.com/Wei-Shaw/sub2api/ent/user" + "github.com/Wei-Shaw/sub2api/ent/userplatformquota" +) + +// UserPlatformQuotaUpdate is the builder for updating UserPlatformQuota entities. +type UserPlatformQuotaUpdate struct { + config + hooks []Hook + mutation *UserPlatformQuotaMutation +} + +// Where appends a list predicates to the UserPlatformQuotaUpdate builder. +func (_u *UserPlatformQuotaUpdate) Where(ps ...predicate.UserPlatformQuota) *UserPlatformQuotaUpdate { + _u.mutation.Where(ps...) + return _u +} + +// SetUpdatedAt sets the "updated_at" field. +func (_u *UserPlatformQuotaUpdate) SetUpdatedAt(v time.Time) *UserPlatformQuotaUpdate { + _u.mutation.SetUpdatedAt(v) + return _u +} + +// SetDeletedAt sets the "deleted_at" field. +func (_u *UserPlatformQuotaUpdate) SetDeletedAt(v time.Time) *UserPlatformQuotaUpdate { + _u.mutation.SetDeletedAt(v) + return _u +} + +// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil. +func (_u *UserPlatformQuotaUpdate) SetNillableDeletedAt(v *time.Time) *UserPlatformQuotaUpdate { + if v != nil { + _u.SetDeletedAt(*v) + } + return _u +} + +// ClearDeletedAt clears the value of the "deleted_at" field. +func (_u *UserPlatformQuotaUpdate) ClearDeletedAt() *UserPlatformQuotaUpdate { + _u.mutation.ClearDeletedAt() + return _u +} + +// SetUserID sets the "user_id" field. +func (_u *UserPlatformQuotaUpdate) SetUserID(v int64) *UserPlatformQuotaUpdate { + _u.mutation.SetUserID(v) + return _u +} + +// SetNillableUserID sets the "user_id" field if the given value is not nil. +func (_u *UserPlatformQuotaUpdate) SetNillableUserID(v *int64) *UserPlatformQuotaUpdate { + if v != nil { + _u.SetUserID(*v) + } + return _u +} + +// SetPlatform sets the "platform" field. +func (_u *UserPlatformQuotaUpdate) SetPlatform(v string) *UserPlatformQuotaUpdate { + _u.mutation.SetPlatform(v) + return _u +} + +// SetNillablePlatform sets the "platform" field if the given value is not nil. +func (_u *UserPlatformQuotaUpdate) SetNillablePlatform(v *string) *UserPlatformQuotaUpdate { + if v != nil { + _u.SetPlatform(*v) + } + return _u +} + +// SetDailyLimitUsd sets the "daily_limit_usd" field. +func (_u *UserPlatformQuotaUpdate) SetDailyLimitUsd(v float64) *UserPlatformQuotaUpdate { + _u.mutation.ResetDailyLimitUsd() + _u.mutation.SetDailyLimitUsd(v) + return _u +} + +// SetNillableDailyLimitUsd sets the "daily_limit_usd" field if the given value is not nil. +func (_u *UserPlatformQuotaUpdate) SetNillableDailyLimitUsd(v *float64) *UserPlatformQuotaUpdate { + if v != nil { + _u.SetDailyLimitUsd(*v) + } + return _u +} + +// AddDailyLimitUsd adds value to the "daily_limit_usd" field. +func (_u *UserPlatformQuotaUpdate) AddDailyLimitUsd(v float64) *UserPlatformQuotaUpdate { + _u.mutation.AddDailyLimitUsd(v) + return _u +} + +// ClearDailyLimitUsd clears the value of the "daily_limit_usd" field. +func (_u *UserPlatformQuotaUpdate) ClearDailyLimitUsd() *UserPlatformQuotaUpdate { + _u.mutation.ClearDailyLimitUsd() + return _u +} + +// SetWeeklyLimitUsd sets the "weekly_limit_usd" field. +func (_u *UserPlatformQuotaUpdate) SetWeeklyLimitUsd(v float64) *UserPlatformQuotaUpdate { + _u.mutation.ResetWeeklyLimitUsd() + _u.mutation.SetWeeklyLimitUsd(v) + return _u +} + +// SetNillableWeeklyLimitUsd sets the "weekly_limit_usd" field if the given value is not nil. +func (_u *UserPlatformQuotaUpdate) SetNillableWeeklyLimitUsd(v *float64) *UserPlatformQuotaUpdate { + if v != nil { + _u.SetWeeklyLimitUsd(*v) + } + return _u +} + +// AddWeeklyLimitUsd adds value to the "weekly_limit_usd" field. +func (_u *UserPlatformQuotaUpdate) AddWeeklyLimitUsd(v float64) *UserPlatformQuotaUpdate { + _u.mutation.AddWeeklyLimitUsd(v) + return _u +} + +// ClearWeeklyLimitUsd clears the value of the "weekly_limit_usd" field. +func (_u *UserPlatformQuotaUpdate) ClearWeeklyLimitUsd() *UserPlatformQuotaUpdate { + _u.mutation.ClearWeeklyLimitUsd() + return _u +} + +// SetMonthlyLimitUsd sets the "monthly_limit_usd" field. +func (_u *UserPlatformQuotaUpdate) SetMonthlyLimitUsd(v float64) *UserPlatformQuotaUpdate { + _u.mutation.ResetMonthlyLimitUsd() + _u.mutation.SetMonthlyLimitUsd(v) + return _u +} + +// SetNillableMonthlyLimitUsd sets the "monthly_limit_usd" field if the given value is not nil. +func (_u *UserPlatformQuotaUpdate) SetNillableMonthlyLimitUsd(v *float64) *UserPlatformQuotaUpdate { + if v != nil { + _u.SetMonthlyLimitUsd(*v) + } + return _u +} + +// AddMonthlyLimitUsd adds value to the "monthly_limit_usd" field. +func (_u *UserPlatformQuotaUpdate) AddMonthlyLimitUsd(v float64) *UserPlatformQuotaUpdate { + _u.mutation.AddMonthlyLimitUsd(v) + return _u +} + +// ClearMonthlyLimitUsd clears the value of the "monthly_limit_usd" field. +func (_u *UserPlatformQuotaUpdate) ClearMonthlyLimitUsd() *UserPlatformQuotaUpdate { + _u.mutation.ClearMonthlyLimitUsd() + return _u +} + +// SetDailyUsageUsd sets the "daily_usage_usd" field. +func (_u *UserPlatformQuotaUpdate) SetDailyUsageUsd(v float64) *UserPlatformQuotaUpdate { + _u.mutation.ResetDailyUsageUsd() + _u.mutation.SetDailyUsageUsd(v) + return _u +} + +// SetNillableDailyUsageUsd sets the "daily_usage_usd" field if the given value is not nil. +func (_u *UserPlatformQuotaUpdate) SetNillableDailyUsageUsd(v *float64) *UserPlatformQuotaUpdate { + if v != nil { + _u.SetDailyUsageUsd(*v) + } + return _u +} + +// AddDailyUsageUsd adds value to the "daily_usage_usd" field. +func (_u *UserPlatformQuotaUpdate) AddDailyUsageUsd(v float64) *UserPlatformQuotaUpdate { + _u.mutation.AddDailyUsageUsd(v) + return _u +} + +// SetWeeklyUsageUsd sets the "weekly_usage_usd" field. +func (_u *UserPlatformQuotaUpdate) SetWeeklyUsageUsd(v float64) *UserPlatformQuotaUpdate { + _u.mutation.ResetWeeklyUsageUsd() + _u.mutation.SetWeeklyUsageUsd(v) + return _u +} + +// SetNillableWeeklyUsageUsd sets the "weekly_usage_usd" field if the given value is not nil. +func (_u *UserPlatformQuotaUpdate) SetNillableWeeklyUsageUsd(v *float64) *UserPlatformQuotaUpdate { + if v != nil { + _u.SetWeeklyUsageUsd(*v) + } + return _u +} + +// AddWeeklyUsageUsd adds value to the "weekly_usage_usd" field. +func (_u *UserPlatformQuotaUpdate) AddWeeklyUsageUsd(v float64) *UserPlatformQuotaUpdate { + _u.mutation.AddWeeklyUsageUsd(v) + return _u +} + +// SetMonthlyUsageUsd sets the "monthly_usage_usd" field. +func (_u *UserPlatformQuotaUpdate) SetMonthlyUsageUsd(v float64) *UserPlatformQuotaUpdate { + _u.mutation.ResetMonthlyUsageUsd() + _u.mutation.SetMonthlyUsageUsd(v) + return _u +} + +// SetNillableMonthlyUsageUsd sets the "monthly_usage_usd" field if the given value is not nil. +func (_u *UserPlatformQuotaUpdate) SetNillableMonthlyUsageUsd(v *float64) *UserPlatformQuotaUpdate { + if v != nil { + _u.SetMonthlyUsageUsd(*v) + } + return _u +} + +// AddMonthlyUsageUsd adds value to the "monthly_usage_usd" field. +func (_u *UserPlatformQuotaUpdate) AddMonthlyUsageUsd(v float64) *UserPlatformQuotaUpdate { + _u.mutation.AddMonthlyUsageUsd(v) + return _u +} + +// SetDailyWindowStart sets the "daily_window_start" field. +func (_u *UserPlatformQuotaUpdate) SetDailyWindowStart(v time.Time) *UserPlatformQuotaUpdate { + _u.mutation.SetDailyWindowStart(v) + return _u +} + +// SetNillableDailyWindowStart sets the "daily_window_start" field if the given value is not nil. +func (_u *UserPlatformQuotaUpdate) SetNillableDailyWindowStart(v *time.Time) *UserPlatformQuotaUpdate { + if v != nil { + _u.SetDailyWindowStart(*v) + } + return _u +} + +// ClearDailyWindowStart clears the value of the "daily_window_start" field. +func (_u *UserPlatformQuotaUpdate) ClearDailyWindowStart() *UserPlatformQuotaUpdate { + _u.mutation.ClearDailyWindowStart() + return _u +} + +// SetWeeklyWindowStart sets the "weekly_window_start" field. +func (_u *UserPlatformQuotaUpdate) SetWeeklyWindowStart(v time.Time) *UserPlatformQuotaUpdate { + _u.mutation.SetWeeklyWindowStart(v) + return _u +} + +// SetNillableWeeklyWindowStart sets the "weekly_window_start" field if the given value is not nil. +func (_u *UserPlatformQuotaUpdate) SetNillableWeeklyWindowStart(v *time.Time) *UserPlatformQuotaUpdate { + if v != nil { + _u.SetWeeklyWindowStart(*v) + } + return _u +} + +// ClearWeeklyWindowStart clears the value of the "weekly_window_start" field. +func (_u *UserPlatformQuotaUpdate) ClearWeeklyWindowStart() *UserPlatformQuotaUpdate { + _u.mutation.ClearWeeklyWindowStart() + return _u +} + +// SetMonthlyWindowStart sets the "monthly_window_start" field. +func (_u *UserPlatformQuotaUpdate) SetMonthlyWindowStart(v time.Time) *UserPlatformQuotaUpdate { + _u.mutation.SetMonthlyWindowStart(v) + return _u +} + +// SetNillableMonthlyWindowStart sets the "monthly_window_start" field if the given value is not nil. +func (_u *UserPlatformQuotaUpdate) SetNillableMonthlyWindowStart(v *time.Time) *UserPlatformQuotaUpdate { + if v != nil { + _u.SetMonthlyWindowStart(*v) + } + return _u +} + +// ClearMonthlyWindowStart clears the value of the "monthly_window_start" field. +func (_u *UserPlatformQuotaUpdate) ClearMonthlyWindowStart() *UserPlatformQuotaUpdate { + _u.mutation.ClearMonthlyWindowStart() + return _u +} + +// SetUser sets the "user" edge to the User entity. +func (_u *UserPlatformQuotaUpdate) SetUser(v *User) *UserPlatformQuotaUpdate { + return _u.SetUserID(v.ID) +} + +// Mutation returns the UserPlatformQuotaMutation object of the builder. +func (_u *UserPlatformQuotaUpdate) Mutation() *UserPlatformQuotaMutation { + return _u.mutation +} + +// ClearUser clears the "user" edge to the User entity. +func (_u *UserPlatformQuotaUpdate) ClearUser() *UserPlatformQuotaUpdate { + _u.mutation.ClearUser() + return _u +} + +// Save executes the query and returns the number of nodes affected by the update operation. +func (_u *UserPlatformQuotaUpdate) Save(ctx context.Context) (int, error) { + if err := _u.defaults(); err != nil { + return 0, err + } + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (_u *UserPlatformQuotaUpdate) SaveX(ctx context.Context) int { + affected, err := _u.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (_u *UserPlatformQuotaUpdate) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_u *UserPlatformQuotaUpdate) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (_u *UserPlatformQuotaUpdate) defaults() error { + if _, ok := _u.mutation.UpdatedAt(); !ok { + if userplatformquota.UpdateDefaultUpdatedAt == nil { + return fmt.Errorf("ent: uninitialized userplatformquota.UpdateDefaultUpdatedAt (forgotten import ent/runtime?)") + } + v := userplatformquota.UpdateDefaultUpdatedAt() + _u.mutation.SetUpdatedAt(v) + } + return nil +} + +// check runs all checks and user-defined validators on the builder. +func (_u *UserPlatformQuotaUpdate) check() error { + if v, ok := _u.mutation.Platform(); ok { + if err := userplatformquota.PlatformValidator(v); err != nil { + return &ValidationError{Name: "platform", err: fmt.Errorf(`ent: validator failed for field "UserPlatformQuota.platform": %w`, err)} + } + } + if _u.mutation.UserCleared() && len(_u.mutation.UserIDs()) > 0 { + return errors.New(`ent: clearing a required unique edge "UserPlatformQuota.user"`) + } + return nil +} + +func (_u *UserPlatformQuotaUpdate) sqlSave(ctx context.Context) (_node int, err error) { + if err := _u.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(userplatformquota.Table, userplatformquota.Columns, sqlgraph.NewFieldSpec(userplatformquota.FieldID, field.TypeInt64)) + if ps := _u.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := _u.mutation.UpdatedAt(); ok { + _spec.SetField(userplatformquota.FieldUpdatedAt, field.TypeTime, value) + } + if value, ok := _u.mutation.DeletedAt(); ok { + _spec.SetField(userplatformquota.FieldDeletedAt, field.TypeTime, value) + } + if _u.mutation.DeletedAtCleared() { + _spec.ClearField(userplatformquota.FieldDeletedAt, field.TypeTime) + } + if value, ok := _u.mutation.Platform(); ok { + _spec.SetField(userplatformquota.FieldPlatform, field.TypeString, value) + } + if value, ok := _u.mutation.DailyLimitUsd(); ok { + _spec.SetField(userplatformquota.FieldDailyLimitUsd, field.TypeFloat64, value) + } + if value, ok := _u.mutation.AddedDailyLimitUsd(); ok { + _spec.AddField(userplatformquota.FieldDailyLimitUsd, field.TypeFloat64, value) + } + if _u.mutation.DailyLimitUsdCleared() { + _spec.ClearField(userplatformquota.FieldDailyLimitUsd, field.TypeFloat64) + } + if value, ok := _u.mutation.WeeklyLimitUsd(); ok { + _spec.SetField(userplatformquota.FieldWeeklyLimitUsd, field.TypeFloat64, value) + } + if value, ok := _u.mutation.AddedWeeklyLimitUsd(); ok { + _spec.AddField(userplatformquota.FieldWeeklyLimitUsd, field.TypeFloat64, value) + } + if _u.mutation.WeeklyLimitUsdCleared() { + _spec.ClearField(userplatformquota.FieldWeeklyLimitUsd, field.TypeFloat64) + } + if value, ok := _u.mutation.MonthlyLimitUsd(); ok { + _spec.SetField(userplatformquota.FieldMonthlyLimitUsd, field.TypeFloat64, value) + } + if value, ok := _u.mutation.AddedMonthlyLimitUsd(); ok { + _spec.AddField(userplatformquota.FieldMonthlyLimitUsd, field.TypeFloat64, value) + } + if _u.mutation.MonthlyLimitUsdCleared() { + _spec.ClearField(userplatformquota.FieldMonthlyLimitUsd, field.TypeFloat64) + } + if value, ok := _u.mutation.DailyUsageUsd(); ok { + _spec.SetField(userplatformquota.FieldDailyUsageUsd, field.TypeFloat64, value) + } + if value, ok := _u.mutation.AddedDailyUsageUsd(); ok { + _spec.AddField(userplatformquota.FieldDailyUsageUsd, field.TypeFloat64, value) + } + if value, ok := _u.mutation.WeeklyUsageUsd(); ok { + _spec.SetField(userplatformquota.FieldWeeklyUsageUsd, field.TypeFloat64, value) + } + if value, ok := _u.mutation.AddedWeeklyUsageUsd(); ok { + _spec.AddField(userplatformquota.FieldWeeklyUsageUsd, field.TypeFloat64, value) + } + if value, ok := _u.mutation.MonthlyUsageUsd(); ok { + _spec.SetField(userplatformquota.FieldMonthlyUsageUsd, field.TypeFloat64, value) + } + if value, ok := _u.mutation.AddedMonthlyUsageUsd(); ok { + _spec.AddField(userplatformquota.FieldMonthlyUsageUsd, field.TypeFloat64, value) + } + if value, ok := _u.mutation.DailyWindowStart(); ok { + _spec.SetField(userplatformquota.FieldDailyWindowStart, field.TypeTime, value) + } + if _u.mutation.DailyWindowStartCleared() { + _spec.ClearField(userplatformquota.FieldDailyWindowStart, field.TypeTime) + } + if value, ok := _u.mutation.WeeklyWindowStart(); ok { + _spec.SetField(userplatformquota.FieldWeeklyWindowStart, field.TypeTime, value) + } + if _u.mutation.WeeklyWindowStartCleared() { + _spec.ClearField(userplatformquota.FieldWeeklyWindowStart, field.TypeTime) + } + if value, ok := _u.mutation.MonthlyWindowStart(); ok { + _spec.SetField(userplatformquota.FieldMonthlyWindowStart, field.TypeTime, value) + } + if _u.mutation.MonthlyWindowStartCleared() { + _spec.ClearField(userplatformquota.FieldMonthlyWindowStart, field.TypeTime) + } + if _u.mutation.UserCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: userplatformquota.UserTable, + Columns: []string{userplatformquota.UserColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.UserIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: userplatformquota.UserTable, + Columns: []string{userplatformquota.UserColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{userplatformquota.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return 0, err + } + _u.mutation.done = true + return _node, nil +} + +// UserPlatformQuotaUpdateOne is the builder for updating a single UserPlatformQuota entity. +type UserPlatformQuotaUpdateOne struct { + config + fields []string + hooks []Hook + mutation *UserPlatformQuotaMutation +} + +// SetUpdatedAt sets the "updated_at" field. +func (_u *UserPlatformQuotaUpdateOne) SetUpdatedAt(v time.Time) *UserPlatformQuotaUpdateOne { + _u.mutation.SetUpdatedAt(v) + return _u +} + +// SetDeletedAt sets the "deleted_at" field. +func (_u *UserPlatformQuotaUpdateOne) SetDeletedAt(v time.Time) *UserPlatformQuotaUpdateOne { + _u.mutation.SetDeletedAt(v) + return _u +} + +// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil. +func (_u *UserPlatformQuotaUpdateOne) SetNillableDeletedAt(v *time.Time) *UserPlatformQuotaUpdateOne { + if v != nil { + _u.SetDeletedAt(*v) + } + return _u +} + +// ClearDeletedAt clears the value of the "deleted_at" field. +func (_u *UserPlatformQuotaUpdateOne) ClearDeletedAt() *UserPlatformQuotaUpdateOne { + _u.mutation.ClearDeletedAt() + return _u +} + +// SetUserID sets the "user_id" field. +func (_u *UserPlatformQuotaUpdateOne) SetUserID(v int64) *UserPlatformQuotaUpdateOne { + _u.mutation.SetUserID(v) + return _u +} + +// SetNillableUserID sets the "user_id" field if the given value is not nil. +func (_u *UserPlatformQuotaUpdateOne) SetNillableUserID(v *int64) *UserPlatformQuotaUpdateOne { + if v != nil { + _u.SetUserID(*v) + } + return _u +} + +// SetPlatform sets the "platform" field. +func (_u *UserPlatformQuotaUpdateOne) SetPlatform(v string) *UserPlatformQuotaUpdateOne { + _u.mutation.SetPlatform(v) + return _u +} + +// SetNillablePlatform sets the "platform" field if the given value is not nil. +func (_u *UserPlatformQuotaUpdateOne) SetNillablePlatform(v *string) *UserPlatformQuotaUpdateOne { + if v != nil { + _u.SetPlatform(*v) + } + return _u +} + +// SetDailyLimitUsd sets the "daily_limit_usd" field. +func (_u *UserPlatformQuotaUpdateOne) SetDailyLimitUsd(v float64) *UserPlatformQuotaUpdateOne { + _u.mutation.ResetDailyLimitUsd() + _u.mutation.SetDailyLimitUsd(v) + return _u +} + +// SetNillableDailyLimitUsd sets the "daily_limit_usd" field if the given value is not nil. +func (_u *UserPlatformQuotaUpdateOne) SetNillableDailyLimitUsd(v *float64) *UserPlatformQuotaUpdateOne { + if v != nil { + _u.SetDailyLimitUsd(*v) + } + return _u +} + +// AddDailyLimitUsd adds value to the "daily_limit_usd" field. +func (_u *UserPlatformQuotaUpdateOne) AddDailyLimitUsd(v float64) *UserPlatformQuotaUpdateOne { + _u.mutation.AddDailyLimitUsd(v) + return _u +} + +// ClearDailyLimitUsd clears the value of the "daily_limit_usd" field. +func (_u *UserPlatformQuotaUpdateOne) ClearDailyLimitUsd() *UserPlatformQuotaUpdateOne { + _u.mutation.ClearDailyLimitUsd() + return _u +} + +// SetWeeklyLimitUsd sets the "weekly_limit_usd" field. +func (_u *UserPlatformQuotaUpdateOne) SetWeeklyLimitUsd(v float64) *UserPlatformQuotaUpdateOne { + _u.mutation.ResetWeeklyLimitUsd() + _u.mutation.SetWeeklyLimitUsd(v) + return _u +} + +// SetNillableWeeklyLimitUsd sets the "weekly_limit_usd" field if the given value is not nil. +func (_u *UserPlatformQuotaUpdateOne) SetNillableWeeklyLimitUsd(v *float64) *UserPlatformQuotaUpdateOne { + if v != nil { + _u.SetWeeklyLimitUsd(*v) + } + return _u +} + +// AddWeeklyLimitUsd adds value to the "weekly_limit_usd" field. +func (_u *UserPlatformQuotaUpdateOne) AddWeeklyLimitUsd(v float64) *UserPlatformQuotaUpdateOne { + _u.mutation.AddWeeklyLimitUsd(v) + return _u +} + +// ClearWeeklyLimitUsd clears the value of the "weekly_limit_usd" field. +func (_u *UserPlatformQuotaUpdateOne) ClearWeeklyLimitUsd() *UserPlatformQuotaUpdateOne { + _u.mutation.ClearWeeklyLimitUsd() + return _u +} + +// SetMonthlyLimitUsd sets the "monthly_limit_usd" field. +func (_u *UserPlatformQuotaUpdateOne) SetMonthlyLimitUsd(v float64) *UserPlatformQuotaUpdateOne { + _u.mutation.ResetMonthlyLimitUsd() + _u.mutation.SetMonthlyLimitUsd(v) + return _u +} + +// SetNillableMonthlyLimitUsd sets the "monthly_limit_usd" field if the given value is not nil. +func (_u *UserPlatformQuotaUpdateOne) SetNillableMonthlyLimitUsd(v *float64) *UserPlatformQuotaUpdateOne { + if v != nil { + _u.SetMonthlyLimitUsd(*v) + } + return _u +} + +// AddMonthlyLimitUsd adds value to the "monthly_limit_usd" field. +func (_u *UserPlatformQuotaUpdateOne) AddMonthlyLimitUsd(v float64) *UserPlatformQuotaUpdateOne { + _u.mutation.AddMonthlyLimitUsd(v) + return _u +} + +// ClearMonthlyLimitUsd clears the value of the "monthly_limit_usd" field. +func (_u *UserPlatformQuotaUpdateOne) ClearMonthlyLimitUsd() *UserPlatformQuotaUpdateOne { + _u.mutation.ClearMonthlyLimitUsd() + return _u +} + +// SetDailyUsageUsd sets the "daily_usage_usd" field. +func (_u *UserPlatformQuotaUpdateOne) SetDailyUsageUsd(v float64) *UserPlatformQuotaUpdateOne { + _u.mutation.ResetDailyUsageUsd() + _u.mutation.SetDailyUsageUsd(v) + return _u +} + +// SetNillableDailyUsageUsd sets the "daily_usage_usd" field if the given value is not nil. +func (_u *UserPlatformQuotaUpdateOne) SetNillableDailyUsageUsd(v *float64) *UserPlatformQuotaUpdateOne { + if v != nil { + _u.SetDailyUsageUsd(*v) + } + return _u +} + +// AddDailyUsageUsd adds value to the "daily_usage_usd" field. +func (_u *UserPlatformQuotaUpdateOne) AddDailyUsageUsd(v float64) *UserPlatformQuotaUpdateOne { + _u.mutation.AddDailyUsageUsd(v) + return _u +} + +// SetWeeklyUsageUsd sets the "weekly_usage_usd" field. +func (_u *UserPlatformQuotaUpdateOne) SetWeeklyUsageUsd(v float64) *UserPlatformQuotaUpdateOne { + _u.mutation.ResetWeeklyUsageUsd() + _u.mutation.SetWeeklyUsageUsd(v) + return _u +} + +// SetNillableWeeklyUsageUsd sets the "weekly_usage_usd" field if the given value is not nil. +func (_u *UserPlatformQuotaUpdateOne) SetNillableWeeklyUsageUsd(v *float64) *UserPlatformQuotaUpdateOne { + if v != nil { + _u.SetWeeklyUsageUsd(*v) + } + return _u +} + +// AddWeeklyUsageUsd adds value to the "weekly_usage_usd" field. +func (_u *UserPlatformQuotaUpdateOne) AddWeeklyUsageUsd(v float64) *UserPlatformQuotaUpdateOne { + _u.mutation.AddWeeklyUsageUsd(v) + return _u +} + +// SetMonthlyUsageUsd sets the "monthly_usage_usd" field. +func (_u *UserPlatformQuotaUpdateOne) SetMonthlyUsageUsd(v float64) *UserPlatformQuotaUpdateOne { + _u.mutation.ResetMonthlyUsageUsd() + _u.mutation.SetMonthlyUsageUsd(v) + return _u +} + +// SetNillableMonthlyUsageUsd sets the "monthly_usage_usd" field if the given value is not nil. +func (_u *UserPlatformQuotaUpdateOne) SetNillableMonthlyUsageUsd(v *float64) *UserPlatformQuotaUpdateOne { + if v != nil { + _u.SetMonthlyUsageUsd(*v) + } + return _u +} + +// AddMonthlyUsageUsd adds value to the "monthly_usage_usd" field. +func (_u *UserPlatformQuotaUpdateOne) AddMonthlyUsageUsd(v float64) *UserPlatformQuotaUpdateOne { + _u.mutation.AddMonthlyUsageUsd(v) + return _u +} + +// SetDailyWindowStart sets the "daily_window_start" field. +func (_u *UserPlatformQuotaUpdateOne) SetDailyWindowStart(v time.Time) *UserPlatformQuotaUpdateOne { + _u.mutation.SetDailyWindowStart(v) + return _u +} + +// SetNillableDailyWindowStart sets the "daily_window_start" field if the given value is not nil. +func (_u *UserPlatformQuotaUpdateOne) SetNillableDailyWindowStart(v *time.Time) *UserPlatformQuotaUpdateOne { + if v != nil { + _u.SetDailyWindowStart(*v) + } + return _u +} + +// ClearDailyWindowStart clears the value of the "daily_window_start" field. +func (_u *UserPlatformQuotaUpdateOne) ClearDailyWindowStart() *UserPlatformQuotaUpdateOne { + _u.mutation.ClearDailyWindowStart() + return _u +} + +// SetWeeklyWindowStart sets the "weekly_window_start" field. +func (_u *UserPlatformQuotaUpdateOne) SetWeeklyWindowStart(v time.Time) *UserPlatformQuotaUpdateOne { + _u.mutation.SetWeeklyWindowStart(v) + return _u +} + +// SetNillableWeeklyWindowStart sets the "weekly_window_start" field if the given value is not nil. +func (_u *UserPlatformQuotaUpdateOne) SetNillableWeeklyWindowStart(v *time.Time) *UserPlatformQuotaUpdateOne { + if v != nil { + _u.SetWeeklyWindowStart(*v) + } + return _u +} + +// ClearWeeklyWindowStart clears the value of the "weekly_window_start" field. +func (_u *UserPlatformQuotaUpdateOne) ClearWeeklyWindowStart() *UserPlatformQuotaUpdateOne { + _u.mutation.ClearWeeklyWindowStart() + return _u +} + +// SetMonthlyWindowStart sets the "monthly_window_start" field. +func (_u *UserPlatformQuotaUpdateOne) SetMonthlyWindowStart(v time.Time) *UserPlatformQuotaUpdateOne { + _u.mutation.SetMonthlyWindowStart(v) + return _u +} + +// SetNillableMonthlyWindowStart sets the "monthly_window_start" field if the given value is not nil. +func (_u *UserPlatformQuotaUpdateOne) SetNillableMonthlyWindowStart(v *time.Time) *UserPlatformQuotaUpdateOne { + if v != nil { + _u.SetMonthlyWindowStart(*v) + } + return _u +} + +// ClearMonthlyWindowStart clears the value of the "monthly_window_start" field. +func (_u *UserPlatformQuotaUpdateOne) ClearMonthlyWindowStart() *UserPlatformQuotaUpdateOne { + _u.mutation.ClearMonthlyWindowStart() + return _u +} + +// SetUser sets the "user" edge to the User entity. +func (_u *UserPlatformQuotaUpdateOne) SetUser(v *User) *UserPlatformQuotaUpdateOne { + return _u.SetUserID(v.ID) +} + +// Mutation returns the UserPlatformQuotaMutation object of the builder. +func (_u *UserPlatformQuotaUpdateOne) Mutation() *UserPlatformQuotaMutation { + return _u.mutation +} + +// ClearUser clears the "user" edge to the User entity. +func (_u *UserPlatformQuotaUpdateOne) ClearUser() *UserPlatformQuotaUpdateOne { + _u.mutation.ClearUser() + return _u +} + +// Where appends a list predicates to the UserPlatformQuotaUpdate builder. +func (_u *UserPlatformQuotaUpdateOne) Where(ps ...predicate.UserPlatformQuota) *UserPlatformQuotaUpdateOne { + _u.mutation.Where(ps...) + return _u +} + +// Select allows selecting one or more fields (columns) of the returned entity. +// The default is selecting all fields defined in the entity schema. +func (_u *UserPlatformQuotaUpdateOne) Select(field string, fields ...string) *UserPlatformQuotaUpdateOne { + _u.fields = append([]string{field}, fields...) + return _u +} + +// Save executes the query and returns the updated UserPlatformQuota entity. +func (_u *UserPlatformQuotaUpdateOne) Save(ctx context.Context) (*UserPlatformQuota, error) { + if err := _u.defaults(); err != nil { + return nil, err + } + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (_u *UserPlatformQuotaUpdateOne) SaveX(ctx context.Context) *UserPlatformQuota { + node, err := _u.Save(ctx) + if err != nil { + panic(err) + } + return node +} + +// Exec executes the query on the entity. +func (_u *UserPlatformQuotaUpdateOne) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_u *UserPlatformQuotaUpdateOne) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (_u *UserPlatformQuotaUpdateOne) defaults() error { + if _, ok := _u.mutation.UpdatedAt(); !ok { + if userplatformquota.UpdateDefaultUpdatedAt == nil { + return fmt.Errorf("ent: uninitialized userplatformquota.UpdateDefaultUpdatedAt (forgotten import ent/runtime?)") + } + v := userplatformquota.UpdateDefaultUpdatedAt() + _u.mutation.SetUpdatedAt(v) + } + return nil +} + +// check runs all checks and user-defined validators on the builder. +func (_u *UserPlatformQuotaUpdateOne) check() error { + if v, ok := _u.mutation.Platform(); ok { + if err := userplatformquota.PlatformValidator(v); err != nil { + return &ValidationError{Name: "platform", err: fmt.Errorf(`ent: validator failed for field "UserPlatformQuota.platform": %w`, err)} + } + } + if _u.mutation.UserCleared() && len(_u.mutation.UserIDs()) > 0 { + return errors.New(`ent: clearing a required unique edge "UserPlatformQuota.user"`) + } + return nil +} + +func (_u *UserPlatformQuotaUpdateOne) sqlSave(ctx context.Context) (_node *UserPlatformQuota, err error) { + if err := _u.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(userplatformquota.Table, userplatformquota.Columns, sqlgraph.NewFieldSpec(userplatformquota.FieldID, field.TypeInt64)) + id, ok := _u.mutation.ID() + if !ok { + return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "UserPlatformQuota.id" for update`)} + } + _spec.Node.ID.Value = id + if fields := _u.fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, userplatformquota.FieldID) + for _, f := range fields { + if !userplatformquota.ValidColumn(f) { + return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + if f != userplatformquota.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, f) + } + } + } + if ps := _u.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := _u.mutation.UpdatedAt(); ok { + _spec.SetField(userplatformquota.FieldUpdatedAt, field.TypeTime, value) + } + if value, ok := _u.mutation.DeletedAt(); ok { + _spec.SetField(userplatformquota.FieldDeletedAt, field.TypeTime, value) + } + if _u.mutation.DeletedAtCleared() { + _spec.ClearField(userplatformquota.FieldDeletedAt, field.TypeTime) + } + if value, ok := _u.mutation.Platform(); ok { + _spec.SetField(userplatformquota.FieldPlatform, field.TypeString, value) + } + if value, ok := _u.mutation.DailyLimitUsd(); ok { + _spec.SetField(userplatformquota.FieldDailyLimitUsd, field.TypeFloat64, value) + } + if value, ok := _u.mutation.AddedDailyLimitUsd(); ok { + _spec.AddField(userplatformquota.FieldDailyLimitUsd, field.TypeFloat64, value) + } + if _u.mutation.DailyLimitUsdCleared() { + _spec.ClearField(userplatformquota.FieldDailyLimitUsd, field.TypeFloat64) + } + if value, ok := _u.mutation.WeeklyLimitUsd(); ok { + _spec.SetField(userplatformquota.FieldWeeklyLimitUsd, field.TypeFloat64, value) + } + if value, ok := _u.mutation.AddedWeeklyLimitUsd(); ok { + _spec.AddField(userplatformquota.FieldWeeklyLimitUsd, field.TypeFloat64, value) + } + if _u.mutation.WeeklyLimitUsdCleared() { + _spec.ClearField(userplatformquota.FieldWeeklyLimitUsd, field.TypeFloat64) + } + if value, ok := _u.mutation.MonthlyLimitUsd(); ok { + _spec.SetField(userplatformquota.FieldMonthlyLimitUsd, field.TypeFloat64, value) + } + if value, ok := _u.mutation.AddedMonthlyLimitUsd(); ok { + _spec.AddField(userplatformquota.FieldMonthlyLimitUsd, field.TypeFloat64, value) + } + if _u.mutation.MonthlyLimitUsdCleared() { + _spec.ClearField(userplatformquota.FieldMonthlyLimitUsd, field.TypeFloat64) + } + if value, ok := _u.mutation.DailyUsageUsd(); ok { + _spec.SetField(userplatformquota.FieldDailyUsageUsd, field.TypeFloat64, value) + } + if value, ok := _u.mutation.AddedDailyUsageUsd(); ok { + _spec.AddField(userplatformquota.FieldDailyUsageUsd, field.TypeFloat64, value) + } + if value, ok := _u.mutation.WeeklyUsageUsd(); ok { + _spec.SetField(userplatformquota.FieldWeeklyUsageUsd, field.TypeFloat64, value) + } + if value, ok := _u.mutation.AddedWeeklyUsageUsd(); ok { + _spec.AddField(userplatformquota.FieldWeeklyUsageUsd, field.TypeFloat64, value) + } + if value, ok := _u.mutation.MonthlyUsageUsd(); ok { + _spec.SetField(userplatformquota.FieldMonthlyUsageUsd, field.TypeFloat64, value) + } + if value, ok := _u.mutation.AddedMonthlyUsageUsd(); ok { + _spec.AddField(userplatformquota.FieldMonthlyUsageUsd, field.TypeFloat64, value) + } + if value, ok := _u.mutation.DailyWindowStart(); ok { + _spec.SetField(userplatformquota.FieldDailyWindowStart, field.TypeTime, value) + } + if _u.mutation.DailyWindowStartCleared() { + _spec.ClearField(userplatformquota.FieldDailyWindowStart, field.TypeTime) + } + if value, ok := _u.mutation.WeeklyWindowStart(); ok { + _spec.SetField(userplatformquota.FieldWeeklyWindowStart, field.TypeTime, value) + } + if _u.mutation.WeeklyWindowStartCleared() { + _spec.ClearField(userplatformquota.FieldWeeklyWindowStart, field.TypeTime) + } + if value, ok := _u.mutation.MonthlyWindowStart(); ok { + _spec.SetField(userplatformquota.FieldMonthlyWindowStart, field.TypeTime, value) + } + if _u.mutation.MonthlyWindowStartCleared() { + _spec.ClearField(userplatformquota.FieldMonthlyWindowStart, field.TypeTime) + } + if _u.mutation.UserCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: userplatformquota.UserTable, + Columns: []string{userplatformquota.UserColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.UserIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: userplatformquota.UserTable, + Columns: []string{userplatformquota.UserColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + _node = &UserPlatformQuota{config: _u.config} + _spec.Assign = _node.assignValues + _spec.ScanValues = _node.scanValues + if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{userplatformquota.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + _u.mutation.done = true + return _node, nil +} diff --git a/backend/go.mod b/backend/go.mod index caf35ea4..587d5370 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -5,12 +5,14 @@ go 1.26.3 require ( entgo.io/ent v0.14.5 github.com/DATA-DOG/go-sqlmock v1.5.2 + github.com/alicebob/miniredis/v2 v2.38.0 github.com/alitto/pond/v2 v2.6.2 github.com/andybalholm/brotli v1.2.0 github.com/aws/aws-sdk-go-v2 v1.41.3 github.com/aws/aws-sdk-go-v2/config v1.32.10 github.com/aws/aws-sdk-go-v2/credentials v1.19.10 github.com/aws/aws-sdk-go-v2/service/s3 v1.96.2 + github.com/aws/smithy-go v1.24.2 github.com/cespare/xxhash/v2 v2.3.0 github.com/coder/websocket v1.8.14 github.com/dgraph-io/ristretto v0.2.0 @@ -71,7 +73,6 @@ require ( github.com/aws/aws-sdk-go-v2/service/sso v1.30.11 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.15 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.41.7 // indirect - github.com/aws/smithy-go v1.24.2 // indirect github.com/bmatcuk/doublestar v1.3.4 // indirect github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect github.com/bytedance/sonic v1.9.1 // indirect @@ -158,6 +159,7 @@ require ( github.com/tklauser/numcpus v0.6.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.11 // indirect + github.com/yuin/gopher-lua v1.1.1 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect github.com/zclconf/go-cty v1.14.4 // indirect github.com/zclconf/go-cty-yaml v1.1.0 // indirect diff --git a/backend/go.sum b/backend/go.sum index 35cfdb03..7735fda2 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -16,6 +16,8 @@ github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7l github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/agiledragon/gomonkey v2.0.2+incompatible h1:eXKi9/piiC3cjJD1658mEE2o3NjkJ5vDLgYjCQu0Xlw= github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw= +github.com/alicebob/miniredis/v2 v2.38.0 h1:nZAzCR+Lj+Vxk4ZXzm2NuKq2O33RXj1XxJ2e2uP9jiw= +github.com/alicebob/miniredis/v2 v2.38.0/go.mod h1:TcL7YfarKPGDAthEtl5NBeHZfeUQj6OXMm/+iu5cLMM= github.com/alitto/pond/v2 v2.6.2 h1:Sphe40g0ILeM1pA2c2K+Th0DGU+pt0A/Kprr+WB24Pw= github.com/alitto/pond/v2 v2.6.2/go.mod h1:xkjYEgQ05RSpWdfSd1nM3OVv7TBhLdy7rMp3+2Nq+yE= github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ= @@ -162,8 +164,6 @@ github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs= github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= -github.com/google/subcommands v1.2.0 h1:vWQspBTo2nEqTUFita5/KeEWlUL8kQObDFbub/EN9oE= -github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/wire v0.7.0 h1:JxUKI6+CVBgCO2WToKy/nQk0sS+amI9z9EjVmdaocj4= @@ -370,6 +370,8 @@ github.com/wechatpay-apiv3/wechatpay-go v0.2.21 h1:uIyMpzvcaHA33W/QPtHstccw+X52H github.com/wechatpay-apiv3/wechatpay-go v0.2.21/go.mod h1:A254AUBVB6R+EqQFo3yTgeh7HtyqRRtN2w9hQSOrd4Q= github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= +github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= +github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= diff --git a/backend/internal/config/config.go b/backend/internal/config/config.go index 661e3296..b2764f87 100644 --- a/backend/internal/config/config.go +++ b/backend/internal/config/config.go @@ -643,6 +643,12 @@ type ProxyProbeConfig struct { type BillingConfig struct { CircuitBreaker CircuitBreakerConfig `mapstructure:"circuit_breaker"` + // UserPlatformQuotaCacheTTLSeconds 用户 × 平台 quota 缓存 TTL(秒),默认 86400=1天,覆盖典型 daily 窗口。 + // 消费点: + // - billing_cache_service.cacheWriteWorker 异步累加 + // - billing_cache_service.checkUserPlatformQuotaEligibility 首次缓存装载 + // 读写两端必须共用同一 TTL,避免缓存生命周期不一致导致 quota 计数漂移。 + UserPlatformQuotaCacheTTLSeconds int `mapstructure:"user_platform_quota_cache_ttl_seconds"` } type CircuitBreakerConfig struct { @@ -1544,6 +1550,7 @@ func setDefaults() { viper.SetDefault("billing.circuit_breaker.failure_threshold", 5) viper.SetDefault("billing.circuit_breaker.reset_timeout_seconds", 30) viper.SetDefault("billing.circuit_breaker.half_open_requests", 3) + viper.SetDefault("billing.user_platform_quota_cache_ttl_seconds", 86400) // Turnstile viper.SetDefault("turnstile.required", false) diff --git a/backend/internal/handler/admin/admin_basic_handlers_test.go b/backend/internal/handler/admin/admin_basic_handlers_test.go index ddeaab02..7b74bafc 100644 --- a/backend/internal/handler/admin/admin_basic_handlers_test.go +++ b/backend/internal/handler/admin/admin_basic_handlers_test.go @@ -16,7 +16,7 @@ func setupAdminRouter() (*gin.Engine, *stubAdminService) { router := gin.New() adminSvc := newStubAdminService() - userHandler := NewUserHandler(adminSvc, nil) + userHandler := NewUserHandler(adminSvc, nil, nil, nil) groupHandler := NewGroupHandler(adminSvc, nil, nil) proxyHandler := NewProxyHandler(adminSvc) redeemHandler := NewRedeemHandler(adminSvc, nil) diff --git a/backend/internal/handler/admin/admin_service_stub_test.go b/backend/internal/handler/admin/admin_service_stub_test.go index 2fef94f1..d00c2259 100644 --- a/backend/internal/handler/admin/admin_service_stub_test.go +++ b/backend/internal/handler/admin/admin_service_stub_test.go @@ -24,6 +24,7 @@ type stubAdminService struct { updatedProxyIDs []int64 updatedProxies []*service.UpdateProxyInput testedProxyIDs []int64 + getUserErr error createAccountErr error updateAccountErr error bulkUpdateAccountErr error @@ -147,6 +148,9 @@ func (s *stubAdminService) ListUsers(ctx context.Context, page, pageSize int, fi } func (s *stubAdminService) GetUser(ctx context.Context, id int64) (*service.User, error) { + if s.getUserErr != nil { + return nil, s.getUserErr + } for i := range s.users { if s.users[i].ID == id { return &s.users[i], nil diff --git a/backend/internal/handler/admin/setting_handler.go b/backend/internal/handler/admin/setting_handler.go index 36a60c23..3c7fe581 100644 --- a/backend/internal/handler/admin/setting_handler.go +++ b/backend/internal/handler/admin/setting_handler.go @@ -305,6 +305,13 @@ func (h *SettingHandler) GetSettings(c *gin.Context) { payload.OpenAIFastPolicySettings = openaiFastPolicySettingsToDTO(fastPolicy) } + // Default platform quotas(JSON map) + if platformQuotas, err := h.settingService.GetDefaultPlatformQuotas(c.Request.Context()); err != nil { + slog.Error("default_platform_quotas_get_failed", "error", err) + } else { + payload.DefaultPlatformQuotas = platformQuotas + } + response.Success(c, systemSettingsResponseData(payload, authSourceDefaults)) } @@ -637,6 +644,18 @@ type UpdateSettingsRequest struct { // OpenAI fast/flex policy (optional, only updated when provided) OpenAIFastPolicySettings *dto.OpenAIFastPolicySettings `json:"openai_fast_policy_settings,omitempty"` + + // 系统全局 platform quota 默认值(整体替换语义:nil = 不修改,non-nil = 整体覆盖)。 + DefaultPlatformQuotas map[string]*service.DefaultPlatformQuotaSetting `json:"default_platform_quotas"` + + // auth-source 层 platform quota 覆盖(override 语义:nil = 不修改,non-nil = 整体覆盖该 source 的 quota 配置)。 + AuthSourceEmailPlatformQuotas map[string]*service.DefaultPlatformQuotaSetting `json:"auth_source_default_email_platform_quotas"` + AuthSourceLinuxDoPlatformQuotas map[string]*service.DefaultPlatformQuotaSetting `json:"auth_source_default_linuxdo_platform_quotas"` + AuthSourceOIDCPlatformQuotas map[string]*service.DefaultPlatformQuotaSetting `json:"auth_source_default_oidc_platform_quotas"` + AuthSourceWeChatPlatformQuotas map[string]*service.DefaultPlatformQuotaSetting `json:"auth_source_default_wechat_platform_quotas"` + AuthSourceGitHubPlatformQuotas map[string]*service.DefaultPlatformQuotaSetting `json:"auth_source_default_github_platform_quotas"` + AuthSourceGooglePlatformQuotas map[string]*service.DefaultPlatformQuotaSetting `json:"auth_source_default_google_platform_quotas"` + AuthSourceDingTalkPlatformQuotas map[string]*service.DefaultPlatformQuotaSetting `json:"auth_source_default_dingtalk_platform_quotas"` } // UpdateSettings 更新系统设置 @@ -1438,6 +1457,9 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) { } settings := &service.SystemSettings{ + // 系统全局 platform quota 默认值(整体替换语义) + DefaultPlatformQuotas: req.DefaultPlatformQuotas, + RegistrationEnabled: req.RegistrationEnabled, EmailVerifyEnabled: req.EmailVerifyEnabled, RegistrationEmailSuffixWhitelist: req.RegistrationEmailSuffixWhitelist, @@ -1731,6 +1753,8 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) { }(), } + // req.AuthSourceXxxPlatformQuotas 为 nil 表示本次请求未包含该 source 的 quota 配置(保留 previousAuthSourceDefaults 中的值); + // non-nil(含 empty map)表示整体覆盖:empty map = 清空该 source 的所有 quota 配置。 authSourceDefaults := &service.AuthSourceDefaultSettings{ Email: service.ProviderDefaultGrantSettings{ Balance: float64ValueOrDefault(req.AuthSourceDefaultEmailBalance, previousAuthSourceDefaults.Email.Balance), @@ -1738,6 +1762,7 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) { Subscriptions: defaultSubscriptionsValueOrDefault(req.AuthSourceDefaultEmailSubscriptions, previousAuthSourceDefaults.Email.Subscriptions), GrantOnSignup: boolValueOrDefault(req.AuthSourceDefaultEmailGrantOnSignup, previousAuthSourceDefaults.Email.GrantOnSignup), GrantOnFirstBind: boolValueOrDefault(req.AuthSourceDefaultEmailGrantOnFirstBind, previousAuthSourceDefaults.Email.GrantOnFirstBind), + PlatformQuotas: platformQuotasValueOrDefault(req.AuthSourceEmailPlatformQuotas, previousAuthSourceDefaults.Email.PlatformQuotas), }, LinuxDo: service.ProviderDefaultGrantSettings{ Balance: float64ValueOrDefault(req.AuthSourceDefaultLinuxDoBalance, previousAuthSourceDefaults.LinuxDo.Balance), @@ -1745,6 +1770,7 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) { Subscriptions: defaultSubscriptionsValueOrDefault(req.AuthSourceDefaultLinuxDoSubscriptions, previousAuthSourceDefaults.LinuxDo.Subscriptions), GrantOnSignup: boolValueOrDefault(req.AuthSourceDefaultLinuxDoGrantOnSignup, previousAuthSourceDefaults.LinuxDo.GrantOnSignup), GrantOnFirstBind: boolValueOrDefault(req.AuthSourceDefaultLinuxDoGrantOnFirstBind, previousAuthSourceDefaults.LinuxDo.GrantOnFirstBind), + PlatformQuotas: platformQuotasValueOrDefault(req.AuthSourceLinuxDoPlatformQuotas, previousAuthSourceDefaults.LinuxDo.PlatformQuotas), }, OIDC: service.ProviderDefaultGrantSettings{ Balance: float64ValueOrDefault(req.AuthSourceDefaultOIDCBalance, previousAuthSourceDefaults.OIDC.Balance), @@ -1752,6 +1778,7 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) { Subscriptions: defaultSubscriptionsValueOrDefault(req.AuthSourceDefaultOIDCSubscriptions, previousAuthSourceDefaults.OIDC.Subscriptions), GrantOnSignup: boolValueOrDefault(req.AuthSourceDefaultOIDCGrantOnSignup, previousAuthSourceDefaults.OIDC.GrantOnSignup), GrantOnFirstBind: boolValueOrDefault(req.AuthSourceDefaultOIDCGrantOnFirstBind, previousAuthSourceDefaults.OIDC.GrantOnFirstBind), + PlatformQuotas: platformQuotasValueOrDefault(req.AuthSourceOIDCPlatformQuotas, previousAuthSourceDefaults.OIDC.PlatformQuotas), }, WeChat: service.ProviderDefaultGrantSettings{ Balance: float64ValueOrDefault(req.AuthSourceDefaultWeChatBalance, previousAuthSourceDefaults.WeChat.Balance), @@ -1759,6 +1786,7 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) { Subscriptions: defaultSubscriptionsValueOrDefault(req.AuthSourceDefaultWeChatSubscriptions, previousAuthSourceDefaults.WeChat.Subscriptions), GrantOnSignup: boolValueOrDefault(req.AuthSourceDefaultWeChatGrantOnSignup, previousAuthSourceDefaults.WeChat.GrantOnSignup), GrantOnFirstBind: boolValueOrDefault(req.AuthSourceDefaultWeChatGrantOnFirstBind, previousAuthSourceDefaults.WeChat.GrantOnFirstBind), + PlatformQuotas: platformQuotasValueOrDefault(req.AuthSourceWeChatPlatformQuotas, previousAuthSourceDefaults.WeChat.PlatformQuotas), }, GitHub: service.ProviderDefaultGrantSettings{ Balance: float64ValueOrDefault(req.AuthSourceDefaultGitHubBalance, previousAuthSourceDefaults.GitHub.Balance), @@ -1766,6 +1794,7 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) { Subscriptions: defaultSubscriptionsValueOrDefault(req.AuthSourceDefaultGitHubSubscriptions, previousAuthSourceDefaults.GitHub.Subscriptions), GrantOnSignup: boolValueOrDefault(req.AuthSourceDefaultGitHubGrantOnSignup, previousAuthSourceDefaults.GitHub.GrantOnSignup), GrantOnFirstBind: boolValueOrDefault(req.AuthSourceDefaultGitHubGrantOnFirstBind, previousAuthSourceDefaults.GitHub.GrantOnFirstBind), + PlatformQuotas: platformQuotasValueOrDefault(req.AuthSourceGitHubPlatformQuotas, previousAuthSourceDefaults.GitHub.PlatformQuotas), }, Google: service.ProviderDefaultGrantSettings{ Balance: float64ValueOrDefault(req.AuthSourceDefaultGoogleBalance, previousAuthSourceDefaults.Google.Balance), @@ -1773,6 +1802,7 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) { Subscriptions: defaultSubscriptionsValueOrDefault(req.AuthSourceDefaultGoogleSubscriptions, previousAuthSourceDefaults.Google.Subscriptions), GrantOnSignup: boolValueOrDefault(req.AuthSourceDefaultGoogleGrantOnSignup, previousAuthSourceDefaults.Google.GrantOnSignup), GrantOnFirstBind: boolValueOrDefault(req.AuthSourceDefaultGoogleGrantOnFirstBind, previousAuthSourceDefaults.Google.GrantOnFirstBind), + PlatformQuotas: platformQuotasValueOrDefault(req.AuthSourceGooglePlatformQuotas, previousAuthSourceDefaults.Google.PlatformQuotas), }, DingTalk: service.ProviderDefaultGrantSettings{ Balance: float64ValueOrDefault(req.AuthSourceDefaultDingTalkBalance, previousAuthSourceDefaults.DingTalk.Balance), @@ -1780,6 +1810,7 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) { Subscriptions: defaultSubscriptionsValueOrDefault(req.AuthSourceDefaultDingTalkSubscriptions, previousAuthSourceDefaults.DingTalk.Subscriptions), GrantOnSignup: boolValueOrDefault(req.AuthSourceDefaultDingTalkGrantOnSignup, previousAuthSourceDefaults.DingTalk.GrantOnSignup), GrantOnFirstBind: boolValueOrDefault(req.AuthSourceDefaultDingTalkGrantOnFirstBind, previousAuthSourceDefaults.DingTalk.GrantOnFirstBind), + PlatformQuotas: platformQuotasValueOrDefault(req.AuthSourceDingTalkPlatformQuotas, previousAuthSourceDefaults.DingTalk.PlatformQuotas), }, ForceEmailOnThirdPartySignup: boolValueOrDefault(req.ForceEmailOnThirdPartySignup, previousAuthSourceDefaults.ForceEmailOnThirdPartySignup), } @@ -2047,6 +2078,13 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) { } else if fastPolicy != nil { payload.OpenAIFastPolicySettings = openaiFastPolicySettingsToDTO(fastPolicy) } + + // Default platform quotas(JSON map)—— 与 GetSettings 一致,避免保存后响应缺失该字段 + if platformQuotas, err := h.settingService.GetDefaultPlatformQuotas(c.Request.Context()); err != nil { + slog.Error("default_platform_quotas_get_failed", "error", err) + } else { + payload.DefaultPlatformQuotas = platformQuotas + } response.Success(c, systemSettingsResponseData(payload, updatedAuthSourceDefaults)) } @@ -2511,6 +2549,10 @@ func diffSettings(before *service.SystemSettings, after *service.SystemSettings, if before.RiskControlEnabled != after.RiskControlEnabled { changed = append(changed, "risk_control_enabled") } + // Default platform quotas(JSON map,整体比较) + if !equalPlatformQuotaSettings(before.DefaultPlatformQuotas, after.DefaultPlatformQuotas) { + changed = append(changed, service.SettingKeyDefaultPlatformQuotas) + } changed = appendAuthSourceDefaultChanges(changed, beforeAuthSourceDefaults, afterAuthSourceDefaults) return changed } @@ -2554,6 +2596,10 @@ func appendAuthSourceDefaultChanges(changed []string, before *service.AuthSource if field.before.GrantOnFirstBind != field.after.GrantOnFirstBind { changed = append(changed, "auth_source_default_"+field.name+"_grant_on_first_bind") } + // Platform quotas diff:整体替换语义,发单个 JSON key。 + if !equalPlatformQuotaSettings(field.before.PlatformQuotas, field.after.PlatformQuotas) { + changed = append(changed, service.SettingKeyAuthSourcePlatformQuotas(field.name)) + } } if before.ForceEmailOnThirdPartySignup != after.ForceEmailOnThirdPartySignup { changed = append(changed, "force_email_on_third_party_signup") @@ -2621,6 +2667,17 @@ func defaultSubscriptionsValueOrDefault(input *[]dto.DefaultSubscriptionSetting, return result } +// platformQuotasValueOrDefault 处理 auth-source platform quota 的 nil 语义: +// nil = 请求未包含该字段(保留 fallback),non-nil(含 empty map)= 整体覆盖。 +// 注意:JSON null 与字段省略等价——两者均反序列化为 nil map,因此都保留旧值; +// 若要清空某 source 的所有 quota 配置,须显式发空对象 {}。 +func platformQuotasValueOrDefault(value, fallback map[string]*service.DefaultPlatformQuotaSetting) map[string]*service.DefaultPlatformQuotaSetting { + if value == nil { + return fallback + } + return value +} + func systemSettingsResponseData(settings dto.SystemSettings, authSourceDefaults *service.AuthSourceDefaultSettings) map[string]any { data := make(map[string]any) raw, err := json.Marshal(settings) @@ -2666,6 +2723,13 @@ func systemSettingsResponseData(settings dto.SystemSettings, authSourceDefaults data["auth_source_default_google_subscriptions"] = authSourceDefaults.Google.Subscriptions data["auth_source_default_google_grant_on_signup"] = authSourceDefaults.Google.GrantOnSignup data["auth_source_default_google_grant_on_first_bind"] = authSourceDefaults.Google.GrantOnFirstBind + data["auth_source_default_email_platform_quotas"] = authSourceDefaults.Email.PlatformQuotas + data["auth_source_default_linuxdo_platform_quotas"] = authSourceDefaults.LinuxDo.PlatformQuotas + data["auth_source_default_oidc_platform_quotas"] = authSourceDefaults.OIDC.PlatformQuotas + data["auth_source_default_wechat_platform_quotas"] = authSourceDefaults.WeChat.PlatformQuotas + data["auth_source_default_github_platform_quotas"] = authSourceDefaults.GitHub.PlatformQuotas + data["auth_source_default_google_platform_quotas"] = authSourceDefaults.Google.PlatformQuotas + data["auth_source_default_dingtalk_platform_quotas"] = authSourceDefaults.DingTalk.PlatformQuotas data["force_email_on_third_party_signup"] = authSourceDefaults.ForceEmailOnThirdPartySignup return data @@ -3552,3 +3616,48 @@ func emailTemplatePlaceholderUnion(events []service.NotificationEmailEventInfo) } return placeholders } + +// equalNullableFloat compares two *float64 values treating nil as a distinct case. +func equalNullableFloat(a, b *float64) bool { + if a == nil && b == nil { + return true + } + if a == nil || b == nil { + return false + } + return *a == *b +} + +// slotOf returns the *float64 for the given window from a DefaultPlatformQuotaSetting. +func slotOf(s *service.DefaultPlatformQuotaSetting, win string) *float64 { + if s == nil { + return nil + } + switch win { + case "daily": + return s.DailyLimitUSD + case "weekly": + return s.WeeklyLimitUSD + case "monthly": + return s.MonthlyLimitUSD + } + return nil +} + +// equalPlatformQuotaSettings reports whether two platform-quota maps are identical across all 12 slots. +func equalPlatformQuotaSettings(before, after map[string]*service.DefaultPlatformQuotaSetting) bool { + for _, platform := range service.AllowedQuotaPlatforms { + b := before[platform] + a := after[platform] + if !equalNullableFloat(slotOf(b, "daily"), slotOf(a, "daily")) { + return false + } + if !equalNullableFloat(slotOf(b, "weekly"), slotOf(a, "weekly")) { + return false + } + if !equalNullableFloat(slotOf(b, "monthly"), slotOf(a, "monthly")) { + return false + } + } + return true +} diff --git a/backend/internal/handler/admin/setting_handler_platform_quota_test.go b/backend/internal/handler/admin/setting_handler_platform_quota_test.go new file mode 100644 index 00000000..273b3442 --- /dev/null +++ b/backend/internal/handler/admin/setting_handler_platform_quota_test.go @@ -0,0 +1,188 @@ +//go:build unit + +package admin + +import ( + "bytes" + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + "github.com/Wei-Shaw/sub2api/internal/config" + "github.com/Wei-Shaw/sub2api/internal/pkg/response" + "github.com/Wei-Shaw/sub2api/internal/service" + "github.com/gin-gonic/gin" + "github.com/stretchr/testify/require" +) + +func TestDiffSettings_DetectsGlobalPlatformQuotaChange(t *testing.T) { + five := 5.0 + ten := 10.0 + before := &service.SystemSettings{ + DefaultPlatformQuotas: map[string]*service.DefaultPlatformQuotaSetting{ + "anthropic": {DailyLimitUSD: &five}, + }, + } + after := &service.SystemSettings{ + DefaultPlatformQuotas: map[string]*service.DefaultPlatformQuotaSetting{ + "anthropic": {DailyLimitUSD: &ten}, + }, + } + + changed := diffSettings(before, after, nil, nil, UpdateSettingsRequest{}) + found := false + for _, key := range changed { + if key == service.SettingKeyDefaultPlatformQuotas { + found = true + break + } + } + if !found { + t.Errorf("expected change detection for default platform quotas, got %v", changed) + } +} + +func TestDiffSettings_NoChangeWhenEqual(t *testing.T) { + five := 5.0 + before := &service.SystemSettings{ + DefaultPlatformQuotas: map[string]*service.DefaultPlatformQuotaSetting{ + "anthropic": {DailyLimitUSD: &five}, + }, + } + after := &service.SystemSettings{ + DefaultPlatformQuotas: map[string]*service.DefaultPlatformQuotaSetting{ + "anthropic": {DailyLimitUSD: &five}, + }, + } + + changed := diffSettings(before, after, nil, nil, UpdateSettingsRequest{}) + for _, key := range changed { + if key == service.SettingKeyDefaultPlatformQuotas { + t.Error("equal values should not be detected as changed") + } + } +} + +func TestEqualNullableFloat(t *testing.T) { + five := 5.0 + five2 := 5.0 + ten := 10.0 + cases := []struct { + a, b *float64 + want bool + }{ + {nil, nil, true}, + {&five, nil, false}, + {nil, &five, false}, + {&five, &five2, true}, + {&five, &ten, false}, + } + for _, c := range cases { + if got := equalNullableFloat(c.a, c.b); got != c.want { + t.Errorf("equalNullableFloat(%v, %v) = %v, want %v", c.a, c.b, got, c.want) + } + } +} + +func TestEqualPlatformQuotaSettings_DetectsPerWindowChange(t *testing.T) { + five := 5.0 + ten := 10.0 + before := map[string]*service.DefaultPlatformQuotaSetting{ + "anthropic": {DailyLimitUSD: &five}, + } + after := map[string]*service.DefaultPlatformQuotaSetting{ + "anthropic": {DailyLimitUSD: &ten}, + } + if equalPlatformQuotaSettings(before, after) { + t.Error("expected unequal") + } +} + +func TestAppendAuthSourceDefaultChanges_DetectsPerWindow(t *testing.T) { + five := 5.0 + ten := 10.0 + before := &service.AuthSourceDefaultSettings{ + LinuxDo: service.ProviderDefaultGrantSettings{ + PlatformQuotas: map[string]*service.DefaultPlatformQuotaSetting{ + "anthropic": {DailyLimitUSD: &five}, + }, + }, + } + after := &service.AuthSourceDefaultSettings{ + LinuxDo: service.ProviderDefaultGrantSettings{ + PlatformQuotas: map[string]*service.DefaultPlatformQuotaSetting{ + "anthropic": {DailyLimitUSD: &ten}, + }, + }, + } + + changed := appendAuthSourceDefaultChanges([]string{}, before, after) + // 改动 B5:整体替换语义,审计 log 发单个 JSON key,而非展开 84 个扁平 key。 + key := service.SettingKeyAuthSourcePlatformQuotas("linuxdo") + found := false + for _, k := range changed { + if k == key { + found = true + break + } + } + if !found { + t.Errorf("expected %q in changed, got %v", key, changed) + } +} + +// TestSettingHandler_AuthSourcePlatformQuotas_PutGetRoundTrip 验证 Bug A 修复: +// PUT 发 auth_source_default_email_platform_quotas,GET 能读回相同值(端到端往返)。 +func TestSettingHandler_AuthSourcePlatformQuotas_PutGetRoundTrip(t *testing.T) { + gin.SetMode(gin.TestMode) + repo := &settingHandlerRepoStub{ + values: map[string]string{ + service.SettingKeyPromoCodeEnabled: "true", + }, + } + svc := service.NewSettingService(repo, &config.Config{Default: config.DefaultConfig{UserConcurrency: 5}}) + handler := NewSettingHandler(svc, nil, nil, nil, nil, nil, nil) + + // PUT:发 email platform quota(openai monthly=20) + putBody := map[string]any{ + "auth_source_default_email_platform_quotas": map[string]any{ + "openai": map[string]any{ + "monthly": 20, + }, + }, + } + rawBody, err := json.Marshal(putBody) + require.NoError(t, err) + + rec := httptest.NewRecorder() + c, _ := gin.CreateTestContext(rec) + c.Request = httptest.NewRequest(http.MethodPut, "/api/v1/admin/settings", bytes.NewReader(rawBody)) + c.Request.Header.Set("Content-Type", "application/json") + handler.UpdateSettings(c) + require.Equal(t, http.StatusOK, rec.Code) + + // 验证 DB 中写入了 JSON key + jsonKey := service.SettingKeyAuthSourcePlatformQuotas("email") + require.NotEmpty(t, repo.values[jsonKey], "expected JSON key to be written to DB") + + // GET:验证响应中 auth_source_default_email_platform_quotas.openai.monthly = 20 + rec2 := httptest.NewRecorder() + c2, _ := gin.CreateTestContext(rec2) + c2.Request = httptest.NewRequest(http.MethodGet, "/api/v1/admin/settings", nil) + handler.GetSettings(c2) + require.Equal(t, http.StatusOK, rec2.Code) + + var resp response.Response + require.NoError(t, json.Unmarshal(rec2.Body.Bytes(), &resp)) + data, ok := resp.Data.(map[string]any) + require.True(t, ok) + + emailPQ, ok := data["auth_source_default_email_platform_quotas"].(map[string]any) + require.True(t, ok, "expected auth_source_default_email_platform_quotas to be a map") + openaiPQ, ok := emailPQ["openai"].(map[string]any) + require.True(t, ok, "expected openai entry in email platform quotas") + monthly, ok := openaiPQ["monthly"].(float64) + require.True(t, ok, "expected monthly to be float64") + require.Equal(t, float64(20), monthly, "expected openai monthly=20") +} diff --git a/backend/internal/handler/admin/user_handler.go b/backend/internal/handler/admin/user_handler.go index db35472e..32a21692 100644 --- a/backend/internal/handler/admin/user_handler.go +++ b/backend/internal/handler/admin/user_handler.go @@ -2,10 +2,15 @@ package admin import ( "context" + "errors" + "log/slog" + "math" "strconv" "strings" + "time" "github.com/Wei-Shaw/sub2api/internal/handler/dto" + "github.com/Wei-Shaw/sub2api/internal/handler/quotaview" "github.com/Wei-Shaw/sub2api/internal/pkg/response" "github.com/Wei-Shaw/sub2api/internal/service" @@ -20,15 +25,24 @@ type UserWithConcurrency struct { // UserHandler handles admin user management type UserHandler struct { - adminService service.AdminService - concurrencyService *service.ConcurrencyService + adminService service.AdminService + concurrencyService *service.ConcurrencyService + userPlatformQuotaRepo service.UserPlatformQuotaRepository // T13 admin quota view + billingCache service.BillingCache // T17/T18 缓存失效(PUT/POST 路径) } // NewUserHandler creates a new admin user handler -func NewUserHandler(adminService service.AdminService, concurrencyService *service.ConcurrencyService) *UserHandler { +func NewUserHandler( + adminService service.AdminService, + concurrencyService *service.ConcurrencyService, + userPlatformQuotaRepo service.UserPlatformQuotaRepository, + billingCache service.BillingCache, +) *UserHandler { return &UserHandler{ - adminService: adminService, - concurrencyService: concurrencyService, + adminService: adminService, + concurrencyService: concurrencyService, + userPlatformQuotaRepo: userPlatformQuotaRepo, + billingCache: billingCache, } } @@ -537,3 +551,294 @@ func (h *UserHandler) BatchUpdateConcurrency(c *gin.Context) { } response.Success(c, gin.H{"affected": affected}) } + +// GetUserPlatformQuotas GET /admin/users/:id/platform-quotas +// admin 视角:D14 lazy 归零 + 暴露 *_window_start 调试字段 +func (h *UserHandler) GetUserPlatformQuotas(c *gin.Context) { + idStr := c.Param("id") + userID, err := strconv.ParseInt(idStr, 10, 64) + if err != nil { + response.BadRequest(c, "invalid user id") + return + } + if h.userPlatformQuotaRepo == nil { + response.Success(c, map[string]any{"platform_quotas": []any{}}) + return + } + // 校验用户存在:与 PUT/POST 路径一致,不存在返回 404 而非空数组(避免 admin 界面误判用户存在)。 + if _, err := h.adminService.GetUser(c.Request.Context(), userID); err != nil { + response.ErrorFrom(c, err) + return + } + records, err := h.userPlatformQuotaRepo.ListByUser(c.Request.Context(), userID) + if err != nil { + response.ErrorFrom(c, err) + return + } + now := time.Now().UTC() + out := make([]map[string]any, 0, len(records)) + for _, r := range records { + out = append(out, quotaview.LazyZeroQuotaForResponse(r, now, true)) // true = 暴露 window_start + } + response.Success(c, map[string]any{"platform_quotas": out}) +} + +// UpdateUserPlatformQuotasRequest is the body for PUT /admin/users/:id/platform-quotas. +type UpdateUserPlatformQuotasRequest struct { + Quotas []PlatformQuotaInput `json:"quotas" binding:"required"` +} + +// PlatformQuotaInput 单平台限额输入;limit 字段为 nil 表示不限制。 +type PlatformQuotaInput struct { + Platform string `json:"platform" binding:"required"` + DailyLimitUSD *float64 `json:"daily_limit_usd"` + WeeklyLimitUSD *float64 `json:"weekly_limit_usd"` + MonthlyLimitUSD *float64 `json:"monthly_limit_usd"` +} + +// platform 合法性由 service.IsAllowedQuotaPlatform / service.AllowedQuotaPlatforms 统一判断(单一源)。 + +// UpdateUserPlatformQuotas PUT /admin/users/:id/platform-quotas +// 全量替换该用户所有平台限额。 +func (h *UserHandler) UpdateUserPlatformQuotas(c *gin.Context) { + if h.userPlatformQuotaRepo == nil { + response.Error(c, 503, "platform quota service not available") + return + } + + userID, err := strconv.ParseInt(c.Param("id"), 10, 64) + if err != nil { + response.BadRequest(c, "Invalid user ID") + return + } + + var req UpdateUserPlatformQuotasRequest + if err := c.ShouldBindJSON(&req); err != nil { + response.BadRequest(c, "Invalid request: "+err.Error()) + return + } + + if len(req.Quotas) > 4 { + response.BadRequest(c, "quotas length must be <= 4") + return + } + seen := make(map[string]struct{}, len(req.Quotas)) + for _, q := range req.Quotas { + if !service.IsAllowedQuotaPlatform(q.Platform) { + response.BadRequest(c, "invalid platform: "+q.Platform) + return + } + if _, dup := seen[q.Platform]; dup { + response.BadRequest(c, "duplicate platform: "+q.Platform) + return + } + seen[q.Platform] = struct{}{} + // daily_limit_usd / weekly_limit_usd / monthly_limit_usd 的语义: + // nil / not set → 无限额(完全放行) + // 0 → 完全禁用(任何请求都会被拒绝,因为 usage >= 0 恒成立) + // > 0 → USD 限额上限 + // 拦截 NaN / ±Inf:客户端可发送超大数(如 1e308 × 2)使 JSON 反序列化得到 +Inf, + // 进入 DB 后 cache check 中 usage >= limit 永不成立,limit 等同失效。 + for _, f := range []struct { + name string + val *float64 + }{ + {"daily_limit_usd", q.DailyLimitUSD}, + {"weekly_limit_usd", q.WeeklyLimitUSD}, + {"monthly_limit_usd", q.MonthlyLimitUSD}, + } { + if f.val == nil { + continue + } + v := *f.val + if v < 0 { + response.BadRequest(c, f.name+" must be >= 0") + return + } + if math.IsNaN(v) || math.IsInf(v, 0) { + response.BadRequest(c, f.name+" must be a finite number") + return + } + } + } + + records := make([]service.UserPlatformQuotaRecord, 0, len(req.Quotas)) + for _, q := range req.Quotas { + records = append(records, service.UserPlatformQuotaRecord{ + UserID: userID, + Platform: q.Platform, + DailyLimitUSD: q.DailyLimitUSD, + WeeklyLimitUSD: q.WeeklyLimitUSD, + MonthlyLimitUSD: q.MonthlyLimitUSD, + }) + } + + ctx := c.Request.Context() + // 校验用户是否存在,避免 FK 违反导致 500;用户不存在时返回 404。 + if _, err := h.adminService.GetUser(ctx, userID); err != nil { + response.ErrorFrom(c, err) + return + } + // 在 UpsertForUser 之前抓取 before snapshot 用于审计 before/after 对比。 + // ListByUser 失败不阻断主操作(best-effort),仅记录降级 warn。 + beforeRecords, beforeErr := h.userPlatformQuotaRepo.ListByUser(ctx, userID) + if beforeErr != nil { + slog.Warn("quota audit before snapshot failed", "user_id", userID, "err", beforeErr) + } + if err := h.userPlatformQuotaRepo.UpsertForUser(ctx, userID, records); err != nil { + response.ErrorFrom(c, err) + return + } + + beforeByPlatform := make(map[string]service.UserPlatformQuotaRecord, len(beforeRecords)) + for _, r := range beforeRecords { + beforeByPlatform[r.Platform] = r + } + afterPlatforms := make(map[string]struct{}, len(records)) + for _, r := range records { + afterPlatforms[r.Platform] = struct{}{} + } + changes := make([]map[string]any, 0, len(records)) + for _, r := range records { + entry := map[string]any{ + "platform": r.Platform, + "daily_limit_usd": r.DailyLimitUSD, + "weekly_limit_usd": r.WeeklyLimitUSD, + "monthly_limit_usd": r.MonthlyLimitUSD, + } + if prev, ok := beforeByPlatform[r.Platform]; ok { + entry["before_daily_limit_usd"] = prev.DailyLimitUSD + entry["before_weekly_limit_usd"] = prev.WeeklyLimitUSD + entry["before_monthly_limit_usd"] = prev.MonthlyLimitUSD + } + changes = append(changes, entry) + } + // 补 removed 条目:before 存在但 after 缺失 = 该平台被软删除。 + // 缺少这条记录,审计消费方无法察觉"管理员把某平台从配额列表移除"的操作(合规盲区)。 + for _, prev := range beforeRecords { + if _, kept := afterPlatforms[prev.Platform]; kept { + continue + } + changes = append(changes, map[string]any{ + "platform": prev.Platform, + "removed": true, + "before_daily_limit_usd": prev.DailyLimitUSD, + "before_weekly_limit_usd": prev.WeeklyLimitUSD, + "before_monthly_limit_usd": prev.MonthlyLimitUSD, + }) + } + // before_snapshot_available 让审计消费方能识别 changes 中是否带 before_* 字段; + // false 时所有 entry 都会缺失 before_*_limit_usd,仅有 after 视图。 + slog.Info("admin.quota_updated", + "actor_admin_id", getAdminIDFromContext(c), + "target_user_id", userID, + "platform_count", len(records), + "before_snapshot_available", beforeErr == nil, + "changes", changes) + + // 失效 cache:对全部允许的 platform 统一 invalidate。 + // Trade-off:精确失效(仅 req 涉及平台 + 被软删平台)需 upsert 前额外 ListByUser, + // 增加一次 DB 查询和逻辑复杂度。由于 AllowedQuotaPlatforms 只有 4 个元素, + // 全量 invalidate 的额外开销可接受,且能可靠覆盖软删除场景。 + if h.billingCache != nil { + for _, p := range service.AllowedQuotaPlatforms { + if err := h.billingCache.DeleteUserPlatformQuotaCache(ctx, userID, p); err != nil { + slog.Warn("quota cache invalidation failed", "user_id", userID, "platform", p, "err", err) + } + } + } + + // 返回最新状态 + now := time.Now().UTC() + records2, err := h.userPlatformQuotaRepo.ListByUser(ctx, userID) + if err != nil { + response.ErrorFrom(c, err) + return + } + out := make([]map[string]any, 0, len(records2)) + for i := range records2 { + out = append(out, quotaview.LazyZeroQuotaForResponse(records2[i], now, true)) + } + response.Success(c, map[string]any{"platform_quotas": out}) +} + +// ResetUserPlatformQuotaWindowRequest is the body for POST /admin/users/:id/platform-quotas/reset. +type ResetUserPlatformQuotaWindowRequest struct { + Platform string `json:"platform" binding:"required"` + Window string `json:"window" binding:"required"` +} + +var allowedWindowsForQuotaReset = map[string]struct{}{ + "daily": {}, + "weekly": {}, + "monthly": {}, +} + +// ResetUserPlatformQuotaWindow POST /admin/users/:id/platform-quotas/reset +// 立即归零指定 (platform, window) 的用量并更新 window_start。 +func (h *UserHandler) ResetUserPlatformQuotaWindow(c *gin.Context) { + if h.userPlatformQuotaRepo == nil { + response.Error(c, 503, "platform quota service not available") + return + } + + userID, err := strconv.ParseInt(c.Param("id"), 10, 64) + if err != nil { + response.BadRequest(c, "Invalid user ID") + return + } + + var req ResetUserPlatformQuotaWindowRequest + if err := c.ShouldBindJSON(&req); err != nil { + response.BadRequest(c, "Invalid request: "+err.Error()) + return + } + + if !service.IsAllowedQuotaPlatform(req.Platform) { + response.BadRequest(c, "invalid platform: "+req.Platform) + return + } + if _, ok := allowedWindowsForQuotaReset[req.Window]; !ok { + response.BadRequest(c, "invalid window: "+req.Window) + return + } + + ctx := c.Request.Context() + // 校验用户是否存在,避免对不存在的用户执行操作返回误导性的 500。 + if _, err := h.adminService.GetUser(ctx, userID); err != nil { + response.ErrorFrom(c, err) + return + } + now := time.Now().UTC() + if err := h.userPlatformQuotaRepo.ResetExpiredWindow(ctx, userID, req.Platform, req.Window, now); err != nil { + if errors.Is(err, service.ErrUserPlatformQuotaNotFound) { + response.NotFound(c, "user platform quota not found") + return + } + response.ErrorFrom(c, err) + return + } + + slog.Info("admin.quota_window_reset", + "actor_admin_id", getAdminIDFromContext(c), + "target_user_id", userID, + "platform", req.Platform, + "window", req.Window) + + if h.billingCache != nil { + if err := h.billingCache.DeleteUserPlatformQuotaCache(ctx, userID, req.Platform); err != nil { + slog.Warn("quota cache invalidation failed", "user_id", userID, "platform", req.Platform, "err", err) + } + } + + records, err := h.userPlatformQuotaRepo.ListByUser(ctx, userID) + if err != nil { + response.ErrorFrom(c, err) + return + } + out := make([]map[string]any, 0, len(records)) + for i := range records { + out = append(out, quotaview.LazyZeroQuotaForResponse(records[i], now, true)) + } + response.Success(c, map[string]any{"platform_quotas": out}) +} diff --git a/backend/internal/handler/admin/user_handler_activity_test.go b/backend/internal/handler/admin/user_handler_activity_test.go index bfba2408..a9fdc48a 100644 --- a/backend/internal/handler/admin/user_handler_activity_test.go +++ b/backend/internal/handler/admin/user_handler_activity_test.go @@ -35,7 +35,7 @@ func TestUserHandlerListIncludesActivityFieldsAndSortParams(t *testing.T) { UpdatedAt: lastLoginAt, }, } - handler := NewUserHandler(adminSvc, nil) + handler := NewUserHandler(adminSvc, nil, nil, nil) recorder := httptest.NewRecorder() c, _ := gin.CreateTestContext(recorder) @@ -89,7 +89,7 @@ func TestUserHandlerGetByIDIncludesActivityFields(t *testing.T) { UpdatedAt: lastLoginAt, }, } - handler := NewUserHandler(adminSvc, nil) + handler := NewUserHandler(adminSvc, nil, nil, nil) recorder := httptest.NewRecorder() c, _ := gin.CreateTestContext(recorder) diff --git a/backend/internal/handler/admin/user_platform_quota_admin_test.go b/backend/internal/handler/admin/user_platform_quota_admin_test.go new file mode 100644 index 00000000..fe33d36c --- /dev/null +++ b/backend/internal/handler/admin/user_platform_quota_admin_test.go @@ -0,0 +1,301 @@ +//go:build unit + +package admin + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "net/http" + "net/http/httptest" + "strings" + "testing" + "time" + + "github.com/gin-gonic/gin" + + "github.com/Wei-Shaw/sub2api/internal/service" +) + +// upsertCapturingQuotaRepo 实现 service.UserPlatformQuotaRepository,捕获 UpsertForUser 调用。 +type upsertCapturingQuotaRepo struct { + service.UserPlatformQuotaRepository + listRecords []service.UserPlatformQuotaRecord + listErr error + upsertCalls []upsertCall + upsertErr error + resetCalls []resetCall + resetErr error +} + +type upsertCall struct { + userID int64 + records []service.UserPlatformQuotaRecord +} +type resetCall struct { + userID int64 + platform string + window string + newStart time.Time +} + +func (r *upsertCapturingQuotaRepo) ListByUser(_ context.Context, _ int64) ([]service.UserPlatformQuotaRecord, error) { + return r.listRecords, r.listErr +} +func (r *upsertCapturingQuotaRepo) UpsertForUser(_ context.Context, userID int64, records []service.UserPlatformQuotaRecord) error { + cloned := make([]service.UserPlatformQuotaRecord, len(records)) + copy(cloned, records) + r.upsertCalls = append(r.upsertCalls, upsertCall{userID: userID, records: cloned}) + return r.upsertErr +} +func (r *upsertCapturingQuotaRepo) ResetExpiredWindow(_ context.Context, userID int64, platform string, window string, newStart time.Time) error { + r.resetCalls = append(r.resetCalls, resetCall{userID, platform, window, newStart}) + return r.resetErr +} + +// billingCacheStub 实现 service.BillingCache 中本测试关心的 Delete 方法;其他方法 panic。 +type billingCacheStub struct { + service.BillingCache + deleteCalls []deleteCall + deleteErr error +} + +type deleteCall struct { + userID int64 + platform string +} + +func (b *billingCacheStub) DeleteUserPlatformQuotaCache(_ context.Context, userID int64, platform string) error { + b.deleteCalls = append(b.deleteCalls, deleteCall{userID, platform}) + return b.deleteErr +} + +func buildTestHandler(repo service.UserPlatformQuotaRepository, cache service.BillingCache) *UserHandler { + return &UserHandler{ + userPlatformQuotaRepo: repo, + billingCache: cache, + adminService: newStubAdminService(), + } +} + +func putReq(t *testing.T, body string) (*gin.Context, *httptest.ResponseRecorder) { + t.Helper() + gin.SetMode(gin.TestMode) + w := httptest.NewRecorder() + c, _ := gin.CreateTestContext(w) + req, _ := http.NewRequest(http.MethodPut, "/", bytes.NewBufferString(body)) + req.Header.Set("Content-Type", "application/json") + c.Request = req + c.Params = []gin.Param{{Key: "id", Value: "42"}} + return c, w +} + +func TestUpdateUserPlatformQuotas_Success(t *testing.T) { + repo := &upsertCapturingQuotaRepo{} + cache := &billingCacheStub{} + h := buildTestHandler(repo, cache) + + body := `{"quotas":[ + {"platform":"anthropic","daily_limit_usd":10.0,"weekly_limit_usd":null,"monthly_limit_usd":100.0}, + {"platform":"openai","daily_limit_usd":null,"weekly_limit_usd":null,"monthly_limit_usd":null} + ]}` + c, w := putReq(t, body) + h.UpdateUserPlatformQuotas(c) + + if w.Code != http.StatusOK { + t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String()) + } + if len(repo.upsertCalls) != 1 { + t.Fatalf("UpsertForUser should be called once, got %d", len(repo.upsertCalls)) + } + if repo.upsertCalls[0].userID != 42 || len(repo.upsertCalls[0].records) != 2 { + t.Errorf("unexpected upsert call: %+v", repo.upsertCalls[0]) + } + // 缓存失效:请求中 2 个 platform + 软删除的 2 个 platform(gemini, antigravity)= 4 次 + if len(cache.deleteCalls) != 4 { + t.Errorf("expected 4 cache delete calls, got %d: %+v", len(cache.deleteCalls), cache.deleteCalls) + } +} + +func TestUpdateUserPlatformQuotas_RejectsDuplicatePlatform(t *testing.T) { + h := buildTestHandler(&upsertCapturingQuotaRepo{}, &billingCacheStub{}) + body := `{"quotas":[ + {"platform":"anthropic","daily_limit_usd":1}, + {"platform":"anthropic","daily_limit_usd":2} + ]}` + c, w := putReq(t, body) + h.UpdateUserPlatformQuotas(c) + if w.Code != http.StatusBadRequest { + t.Errorf("expected 400, got %d: %s", w.Code, w.Body.String()) + } +} + +func TestUpdateUserPlatformQuotas_RejectsInvalidPlatform(t *testing.T) { + h := buildTestHandler(&upsertCapturingQuotaRepo{}, &billingCacheStub{}) + body := `{"quotas":[{"platform":"unknown","daily_limit_usd":1}]}` + c, w := putReq(t, body) + h.UpdateUserPlatformQuotas(c) + if w.Code != http.StatusBadRequest { + t.Errorf("expected 400, got %d: %s", w.Code, w.Body.String()) + } +} + +func TestUpdateUserPlatformQuotas_RejectsNegativeLimit(t *testing.T) { + h := buildTestHandler(&upsertCapturingQuotaRepo{}, &billingCacheStub{}) + body := `{"quotas":[{"platform":"anthropic","daily_limit_usd":-1}]}` + c, w := putReq(t, body) + h.UpdateUserPlatformQuotas(c) + if w.Code != http.StatusBadRequest { + t.Errorf("expected 400, got %d: %s", w.Code, w.Body.String()) + } +} + +func TestUpdateUserPlatformQuotas_RejectsTooManyEntries(t *testing.T) { + h := buildTestHandler(&upsertCapturingQuotaRepo{}, &billingCacheStub{}) + body := `{"quotas":[ + {"platform":"anthropic"},{"platform":"openai"},{"platform":"gemini"},{"platform":"antigravity"},{"platform":"anthropic"} + ]}` + c, w := putReq(t, body) + h.UpdateUserPlatformQuotas(c) + if w.Code != http.StatusBadRequest { + t.Errorf("expected 400, got %d: %s", w.Code, w.Body.String()) + } +} + +func TestUpdateUserPlatformQuotas_ReturnsLatestState(t *testing.T) { + repo := &upsertCapturingQuotaRepo{ + listRecords: []service.UserPlatformQuotaRecord{ + {UserID: 42, Platform: "anthropic"}, + }, + } + cache := &billingCacheStub{} + h := buildTestHandler(repo, cache) + + body := `{"quotas":[{"platform":"anthropic","daily_limit_usd":10}]}` + c, w := putReq(t, body) + h.UpdateUserPlatformQuotas(c) + if !strings.Contains(w.Body.String(), `"platform_quotas"`) { + t.Errorf("response should contain platform_quotas array: %s", w.Body.String()) + } +} + +// ───────── T4: Reset 测试 ───────── + +func postReq(t *testing.T, body string) (*gin.Context, *httptest.ResponseRecorder) { + t.Helper() + gin.SetMode(gin.TestMode) + w := httptest.NewRecorder() + c, _ := gin.CreateTestContext(w) + req, _ := http.NewRequest(http.MethodPost, "/", bytes.NewBufferString(body)) + req.Header.Set("Content-Type", "application/json") + c.Request = req + c.Params = []gin.Param{{Key: "id", Value: "42"}} + return c, w +} + +func TestResetUserPlatformQuotaWindow_Success(t *testing.T) { + repo := &upsertCapturingQuotaRepo{} + cache := &billingCacheStub{} + h := buildTestHandler(repo, cache) + body := `{"platform":"anthropic","window":"daily"}` + c, w := postReq(t, body) + h.ResetUserPlatformQuotaWindow(c) + if w.Code != http.StatusOK { + t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String()) + } + if len(repo.resetCalls) != 1 { + t.Fatalf("ResetExpiredWindow should be called once, got %d", len(repo.resetCalls)) + } + if repo.resetCalls[0].userID != 42 || + repo.resetCalls[0].platform != "anthropic" || + repo.resetCalls[0].window != "daily" { + t.Errorf("unexpected reset call: %+v", repo.resetCalls[0]) + } + if len(cache.deleteCalls) != 1 || + cache.deleteCalls[0].userID != 42 || + cache.deleteCalls[0].platform != "anthropic" { + t.Errorf("expected 1 cache delete for anthropic, got %+v", cache.deleteCalls) + } +} + +func TestResetUserPlatformQuotaWindow_RejectsInvalidWindow(t *testing.T) { + h := buildTestHandler(&upsertCapturingQuotaRepo{}, &billingCacheStub{}) + c, w := postReq(t, `{"platform":"anthropic","window":"yearly"}`) + h.ResetUserPlatformQuotaWindow(c) + if w.Code != http.StatusBadRequest { + t.Errorf("expected 400, got %d", w.Code) + } +} + +func TestResetUserPlatformQuotaWindow_RejectsInvalidPlatform(t *testing.T) { + h := buildTestHandler(&upsertCapturingQuotaRepo{}, &billingCacheStub{}) + c, w := postReq(t, `{"platform":"unknown","window":"daily"}`) + h.ResetUserPlatformQuotaWindow(c) + if w.Code != http.StatusBadRequest { + t.Errorf("expected 400, got %d", w.Code) + } +} + +func TestResetUserPlatformQuotaWindow_NotFound(t *testing.T) { + // handler 检查 service.ErrUserPlatformQuotaNotFound(由 adapter 包装而来) + repo := &upsertCapturingQuotaRepo{resetErr: service.ErrUserPlatformQuotaNotFound} + h := buildTestHandler(repo, &billingCacheStub{}) + c, w := postReq(t, `{"platform":"anthropic","window":"daily"}`) + h.ResetUserPlatformQuotaWindow(c) + if w.Code != http.StatusNotFound { + t.Errorf("expected 404, got %d: %s", w.Code, w.Body.String()) + } +} + +func TestUpdateUserPlatformQuotas_JSONErrorOnRepoFailure(t *testing.T) { + repo := &upsertCapturingQuotaRepo{upsertErr: errors.New("db down")} + cache := &billingCacheStub{} + h := buildTestHandler(repo, cache) + body := `{"quotas":[{"platform":"anthropic","daily_limit_usd":10}]}` + c, w := putReq(t, body) + h.UpdateUserPlatformQuotas(c) + if w.Code < 500 { + t.Errorf("expected 5xx, got %d", w.Code) + } + // 返回 JSON 错误响应 + var body2 map[string]any + if err := json.Unmarshal(w.Body.Bytes(), &body2); err != nil { + t.Errorf("expected JSON error body, got: %s", w.Body.String()) + } +} + +func TestUpdateUserPlatformQuotas_UserNotFound(t *testing.T) { + repo := &upsertCapturingQuotaRepo{} + cache := &billingCacheStub{} + adminSvc := newStubAdminService() + adminSvc.getUserErr = service.ErrUserNotFound + h := &UserHandler{ + userPlatformQuotaRepo: repo, + billingCache: cache, + adminService: adminSvc, + } + body := `{"quotas":[{"platform":"anthropic","daily_limit_usd":10}]}` + c, w := putReq(t, body) + h.UpdateUserPlatformQuotas(c) + if w.Code != http.StatusNotFound { + t.Errorf("expected 404 when user not found, got %d: %s", w.Code, w.Body.String()) + } +} + +func TestResetUserPlatformQuotaWindow_UserNotFound(t *testing.T) { + repo := &upsertCapturingQuotaRepo{} + cache := &billingCacheStub{} + adminSvc := newStubAdminService() + adminSvc.getUserErr = service.ErrUserNotFound + h := &UserHandler{ + userPlatformQuotaRepo: repo, + billingCache: cache, + adminService: adminSvc, + } + c, w := postReq(t, `{"platform":"anthropic","window":"daily"}`) + h.ResetUserPlatformQuotaWindow(c) + if w.Code != http.StatusNotFound { + t.Errorf("expected 404 when user not found, got %d: %s", w.Code, w.Body.String()) + } +} diff --git a/backend/internal/handler/admin/user_platform_quotas_handler_test.go b/backend/internal/handler/admin/user_platform_quotas_handler_test.go new file mode 100644 index 00000000..1927a6e8 --- /dev/null +++ b/backend/internal/handler/admin/user_platform_quotas_handler_test.go @@ -0,0 +1,124 @@ +//go:build unit + +package admin + +import ( + "context" + "encoding/json" + "net/http" + "net/http/httptest" + "strings" + "testing" + "time" + + infraerrors "github.com/Wei-Shaw/sub2api/internal/pkg/errors" + "github.com/Wei-Shaw/sub2api/internal/service" + "github.com/gin-gonic/gin" +) + +type fakeQuotaRepoForAdmin struct { + service.UserPlatformQuotaRepository + records []service.UserPlatformQuotaRecord + err error +} + +func (f *fakeQuotaRepoForAdmin) ListByUser(_ context.Context, _ int64) ([]service.UserPlatformQuotaRecord, error) { + return f.records, f.err +} + +func newAdminQuotaTestContext(w *httptest.ResponseRecorder) *gin.Context { + c, _ := gin.CreateTestContext(w) + req, _ := http.NewRequest(http.MethodGet, "/", nil) + c.Request = req + return c +} + +func TestAdminGetUserPlatformQuotas_IncludesWindowStart(t *testing.T) { + start := time.Now().Add(-1 * time.Hour) + repo := &fakeQuotaRepoForAdmin{records: []service.UserPlatformQuotaRecord{{ + UserID: 99, Platform: "anthropic", + DailyUsageUSD: 1.0, DailyWindowStart: &start, + }}} + h := &UserHandler{userPlatformQuotaRepo: repo, adminService: newStubAdminService()} + gin.SetMode(gin.TestMode) + w := httptest.NewRecorder() + c := newAdminQuotaTestContext(w) + c.Params = []gin.Param{{Key: "id", Value: "99"}} + h.GetUserPlatformQuotas(c) + + if w.Code != 200 { + t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String()) + } + if !strings.Contains(w.Body.String(), `"daily_window_start"`) { + t.Errorf("admin response missing daily_window_start, got: %s", w.Body.String()) + } +} + +func TestAdminGetUserPlatformQuotas_InvalidIDReturns400(t *testing.T) { + h := &UserHandler{userPlatformQuotaRepo: &fakeQuotaRepoForAdmin{}} + gin.SetMode(gin.TestMode) + w := httptest.NewRecorder() + c := newAdminQuotaTestContext(w) + c.Params = []gin.Param{{Key: "id", Value: "abc"}} + h.GetUserPlatformQuotas(c) + if w.Code < 400 || w.Code >= 500 { + t.Errorf("invalid id should yield 4xx, got %d", w.Code) + } +} + +func TestAdminGetUserPlatformQuotas_EmptyReturnsEmptyArray(t *testing.T) { + repo := &fakeQuotaRepoForAdmin{records: nil} + h := &UserHandler{userPlatformQuotaRepo: repo, adminService: newStubAdminService()} + gin.SetMode(gin.TestMode) + w := httptest.NewRecorder() + c := newAdminQuotaTestContext(w) + c.Params = []gin.Param{{Key: "id", Value: "99"}} + h.GetUserPlatformQuotas(c) + if w.Code != 200 { + t.Errorf("empty list should be 200, got %d", w.Code) + } + var body map[string]any + if err := json.Unmarshal(w.Body.Bytes(), &body); err != nil { + t.Fatalf("response is not valid JSON: %v", err) + } + data, ok := body["data"].(map[string]any) + if !ok { + t.Fatalf("response missing data object: %v", body) + } + quotas, ok := data["platform_quotas"].([]any) + if !ok { + t.Fatalf("data.platform_quotas missing or wrong type: %v", data) + } + if len(quotas) != 0 { + t.Errorf("expected empty platform_quotas, got %d entries: %v", len(quotas), quotas) + } +} + +func TestAdminGetUserPlatformQuotas_NilRepoReturnsEmpty(t *testing.T) { + h := &UserHandler{userPlatformQuotaRepo: nil} + gin.SetMode(gin.TestMode) + w := httptest.NewRecorder() + c := newAdminQuotaTestContext(w) + c.Params = []gin.Param{{Key: "id", Value: "1"}} + h.GetUserPlatformQuotas(c) + if w.Code != 200 { + t.Errorf("nil repo should return 200 empty, got %d", w.Code) + } +} + +// TestAdminGetUserPlatformQuotas_UserNotFoundReturns404 验证 GET 在用户不存在时返回 404 +// (与 PUT / POST reset 端点行为一致;review fix:原实现返回空数组会让 admin 界面误判用户存在) +func TestAdminGetUserPlatformQuotas_UserNotFoundReturns404(t *testing.T) { + adminSvc := newStubAdminService() + adminSvc.getUserErr = infraerrors.NotFound("USER_NOT_FOUND", "user not found") + repo := &fakeQuotaRepoForAdmin{records: nil} + h := &UserHandler{userPlatformQuotaRepo: repo, adminService: adminSvc} + gin.SetMode(gin.TestMode) + w := httptest.NewRecorder() + c := newAdminQuotaTestContext(w) + c.Params = []gin.Param{{Key: "id", Value: "999"}} + h.GetUserPlatformQuotas(c) + if w.Code != http.StatusNotFound { + t.Errorf("expected 404 for non-existent user, got %d: %s", w.Code, w.Body.String()) + } +} diff --git a/backend/internal/handler/auth_oauth_pending_flow_test.go b/backend/internal/handler/auth_oauth_pending_flow_test.go index 4081b9e4..70fb160a 100644 --- a/backend/internal/handler/auth_oauth_pending_flow_test.go +++ b/backend/internal/handler/auth_oauth_pending_flow_test.go @@ -2233,6 +2233,7 @@ CREATE TABLE IF NOT EXISTS user_affiliates ( nil, options.defaultSubAssigner, affiliateService, + nil, ) userSvc := service.NewUserService(userRepo, nil, nil, nil) var totpSvc *service.TotpService diff --git a/backend/internal/handler/auth_session_revocation_test.go b/backend/internal/handler/auth_session_revocation_test.go index f1c6d87d..922bf9c3 100644 --- a/backend/internal/handler/auth_session_revocation_test.go +++ b/backend/internal/handler/auth_session_revocation_test.go @@ -35,7 +35,7 @@ func TestAuthHandlerRevokeAllSessionsInvalidatesAccessTokens(t *testing.T) { ExpireHour: 1, }, } - authService := service.NewAuthService(nil, repo, nil, refreshTokenCache, cfg, nil, nil, nil, nil, nil, nil, nil) + authService := service.NewAuthService(nil, repo, nil, refreshTokenCache, cfg, nil, nil, nil, nil, nil, nil, nil, nil) handler := &AuthHandler{authService: authService} recorder := httptest.NewRecorder() diff --git a/backend/internal/handler/auth_wechat_oauth_test.go b/backend/internal/handler/auth_wechat_oauth_test.go index b3c7786d..e291b7e7 100644 --- a/backend/internal/handler/auth_wechat_oauth_test.go +++ b/backend/internal/handler/auth_wechat_oauth_test.go @@ -1400,6 +1400,7 @@ func newWeChatOAuthTestHandlerWithSettings(t *testing.T, invitationEnabled bool, nil, nil, nil, + nil, ) return &AuthHandler{ diff --git a/backend/internal/handler/dto/settings.go b/backend/internal/handler/dto/settings.go index fac60573..eecf98ac 100644 --- a/backend/internal/handler/dto/settings.go +++ b/backend/internal/handler/dto/settings.go @@ -3,6 +3,8 @@ package dto import ( "encoding/json" "strings" + + "github.com/Wei-Shaw/sub2api/internal/service" ) // CustomMenuItem represents a user-configured custom menu entry. @@ -246,6 +248,9 @@ type SystemSettings struct { // OpenAI fast/flex policy OpenAIFastPolicySettings *OpenAIFastPolicySettings `json:"openai_fast_policy_settings,omitempty"` + + // 系统全局默认平台配额(key = platform,nil/缺省 = 不限制) + DefaultPlatformQuotas map[string]*service.DefaultPlatformQuotaSetting `json:"default_platform_quotas,omitempty"` } type DefaultSubscriptionSetting struct { diff --git a/backend/internal/handler/gateway_handler.go b/backend/internal/handler/gateway_handler.go index 51c2d94e..11915aa7 100644 --- a/backend/internal/handler/gateway_handler.go +++ b/backend/internal/handler/gateway_handler.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "math" "net/http" "strconv" "strings" @@ -250,7 +251,7 @@ func (h *GatewayHandler) Messages(c *gin.Context) { } // 2. 【新增】Wait后二次检查余额/订阅 - if err := h.billingCacheService.CheckBillingEligibility(c.Request.Context(), apiKey.User, apiKey, apiKey.Group, subscription); err != nil { + if err := h.billingCacheService.CheckBillingEligibility(c.Request.Context(), apiKey.User, apiKey, apiKey.Group, subscription, service.QuotaPlatform(c.Request.Context(), apiKey)); err != nil { reqLog.Info("gateway.billing_eligibility_check_failed", zap.Error(err)) status, code, message, retryAfter := billingErrorDetails(err) if retryAfter > 0 { @@ -508,10 +509,12 @@ func (h *GatewayHandler) Messages(c *gin.Context) { } // 使用量记录通过有界 worker 池提交,避免请求热路径创建无界 goroutine。 + quotaPlatform := service.QuotaPlatform(c.Request.Context(), apiKey) h.submitUsageRecordTask(func(ctx context.Context) { if err := h.gatewayService.RecordUsage(ctx, &service.RecordUsageInput{ Result: result, ParsedRequest: parsedReq, + QuotaPlatform: quotaPlatform, APIKey: apiKey, User: apiKey.User, Account: account, @@ -808,7 +811,7 @@ func (h *GatewayHandler) Messages(c *gin.Context) { return } fallbackAPIKey := cloneAPIKeyWithGroup(apiKey, fallbackGroup) - if err := h.billingCacheService.CheckBillingEligibility(c.Request.Context(), fallbackAPIKey.User, fallbackAPIKey, fallbackGroup, nil); err != nil { + if err := h.billingCacheService.CheckBillingEligibility(c.Request.Context(), fallbackAPIKey.User, fallbackAPIKey, fallbackGroup, nil, service.PlatformFromAPIKey(fallbackAPIKey)); err != nil { status, code, message, retryAfter := billingErrorDetails(err) if retryAfter > 0 { c.Header("Retry-After", strconv.Itoa(retryAfter)) @@ -900,10 +903,12 @@ func (h *GatewayHandler) Messages(c *gin.Context) { } // 使用量记录通过有界 worker 池提交,避免请求热路径创建无界 goroutine。 + quotaPlatform := service.QuotaPlatform(c.Request.Context(), currentAPIKey) h.submitUsageRecordTask(func(ctx context.Context) { if err := h.gatewayService.RecordUsage(ctx, &service.RecordUsageInput{ Result: result, ParsedRequest: parsedReq, + QuotaPlatform: quotaPlatform, APIKey: currentAPIKey, User: currentAPIKey.User, Account: account, @@ -1582,7 +1587,7 @@ func (h *GatewayHandler) CountTokens(c *gin.Context) { // 校验 billing eligibility(订阅/余额) // 【注意】不计算并发,但需要校验订阅/余额 - if err := h.billingCacheService.CheckBillingEligibility(c.Request.Context(), apiKey.User, apiKey, apiKey.Group, subscription); err != nil { + if err := h.billingCacheService.CheckBillingEligibility(c.Request.Context(), apiKey.User, apiKey, apiKey.Group, subscription, service.QuotaPlatform(c.Request.Context(), apiKey)); err != nil { status, code, message, retryAfter := billingErrorDetails(err) if retryAfter > 0 { c.Header("Retry-After", strconv.Itoa(retryAfter)) @@ -1830,6 +1835,36 @@ func sendMockInterceptResponse(c *gin.Context, model string, interceptType Inter c.JSON(http.StatusOK, response) } +// extractQuotaResetSeconds 从 quota 错误的 metadata 中提取 window_resets_at 并计算 +// 距重置剩余秒数。fallback 路径必须返回 ≥1 秒,避免客户端立即重试无限循环。 +func extractQuotaResetSeconds(err error) int { + const fallback = 60 + appErr := pkgerrors.FromError(err) + if appErr == nil { + return fallback + } + raw, ok := appErr.Metadata["window_resets_at"] + if !ok || raw == "" { + return fallback + } + resetAt, parseErr := time.Parse(time.RFC3339, raw) + if parseErr != nil { + logger.L().With( + zap.String("component", "handler.gateway.billing"), + zap.String("raw", raw), + zap.Error(parseErr), + ).Warn("quota.invalid_window_resets_at_format") + return fallback + } + secs := time.Until(resetAt).Seconds() + if secs <= 0 { + // reset 时间已过:cache 与 DB 应该正在自愈,返回 fallback 让客户端按常规节奏退避, + // 避免返回 1 秒导致客户端立即重试仍触发限额的退避循环。 + return fallback + } + return int(math.Ceil(secs)) +} + func billingErrorDetails(err error) (status int, code, message string, retryAfter int) { if errors.Is(err, service.ErrBillingServiceUnavailable) { msg := pkgerrors.Message(err) @@ -1857,6 +1892,14 @@ func billingErrorDetails(err error) (status int, code, message string, retryAfte retrySeconds := 60 - int(time.Now().Unix()%60) return http.StatusTooManyRequests, "rate_limit_exceeded", msg, retrySeconds } + if errors.Is(err, service.ErrUserPlatformDailyQuotaExhausted) || + errors.Is(err, service.ErrUserPlatformWeeklyQuotaExhausted) || + errors.Is(err, service.ErrUserPlatformMonthlyQuotaExhausted) { + // 与 RPM 超限一致映射 429 + Retry-After,让 SDK 自动退避(而非 403 直接失败)。 + // 错误码用 rate_limit_exceeded 与 OpenAI 兼容客户端一致;细分类型由 ErrCode + window_resets_at metadata 区分。 + msg := pkgerrors.Message(err) + return http.StatusTooManyRequests, "rate_limit_exceeded", msg, extractQuotaResetSeconds(err) + } msg := pkgerrors.Message(err) if msg == "" { logger.L().With( diff --git a/backend/internal/handler/gateway_handler_billing_error_test.go b/backend/internal/handler/gateway_handler_billing_error_test.go index e8a88802..eaf48d1e 100644 --- a/backend/internal/handler/gateway_handler_billing_error_test.go +++ b/backend/internal/handler/gateway_handler_billing_error_test.go @@ -1,8 +1,10 @@ package handler import ( + "errors" "net/http" "testing" + "time" "github.com/Wei-Shaw/sub2api/internal/service" "github.com/stretchr/testify/require" @@ -52,3 +54,75 @@ func TestBillingErrorDetails_UnknownErrorFallsBackTo403(t *testing.T) { require.Equal(t, "billing_error", code) require.NotEmpty(t, msg) } + +func TestExtractQuotaResetSeconds_T19_HappyPath(t *testing.T) { + err := service.ErrUserPlatformDailyQuotaExhausted.WithMetadata(map[string]string{ + "window_resets_at": time.Now().Add(10 * time.Second).UTC().Format(time.RFC3339), + }) + got := extractQuotaResetSeconds(err) + if got < 10 || got > 11 { + t.Errorf("T19: got %d, want 10 or 11 (math.Ceil boundary)", got) + } +} + +func TestExtractQuotaResetSeconds_T20_NoMetadataFallback(t *testing.T) { + if got := extractQuotaResetSeconds(errors.New("naked error")); got != 60 { + t.Errorf("T20: got %d, want 60 fallback", got) + } +} + +func TestExtractQuotaResetSeconds_T21_BadFormatFallback(t *testing.T) { + err := service.ErrUserPlatformDailyQuotaExhausted.WithMetadata(map[string]string{ + "window_resets_at": "not-a-time", + }) + if got := extractQuotaResetSeconds(err); got != 60 { + t.Errorf("T21: got %d, want 60 fallback", got) + } +} + +func TestExtractQuotaResetSeconds_T22_PastResetFallsBackToDefault(t *testing.T) { + // 当 window_resets_at 已过去时返回 fallback (60s) 而非 1s: + // 1 秒会导致客户端立即重试仍触发限额的退避循环; + // 60s 让客户端按常规节奏退避,cache/DB 自愈期间不会反复打抖。 + err := service.ErrUserPlatformDailyQuotaExhausted.WithMetadata(map[string]string{ + "window_resets_at": time.Now().Add(-5 * time.Second).UTC().Format(time.RFC3339), + }) + if got := extractQuotaResetSeconds(err); got != 60 { + t.Errorf("T22: got %d, want 60 (fallback on past reset)", got) + } +} + +func TestBillingErrorDetails_T10_QuotaExhaustedReturns429WithRetryAfter(t *testing.T) { + // quota 超限映射 429 + Retry-After(RFC 6585 / 与 RPM 一致), + // 让 SDK(OpenAI 兼容客户端等)能按 Retry-After 自动退避。 + // 旧实现用 403 导致客户端不退避直接报错。 + // 三个窗口共用同一映射分支,循环覆盖避免漏测某个窗口的 status/code。 + cases := []struct { + name string + err error + }{ + {"daily", service.ErrUserPlatformDailyQuotaExhausted.WithMetadata(map[string]string{ + "window_resets_at": time.Now().Add(60 * time.Minute).UTC().Format(time.RFC3339), + })}, + {"weekly", service.ErrUserPlatformWeeklyQuotaExhausted.WithMetadata(map[string]string{ + "window_resets_at": time.Now().Add(60 * time.Minute).UTC().Format(time.RFC3339), + })}, + {"monthly", service.ErrUserPlatformMonthlyQuotaExhausted.WithMetadata(map[string]string{ + "window_resets_at": time.Now().Add(60 * time.Minute).UTC().Format(time.RFC3339), + })}, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + status, code, _, retryAfter := billingErrorDetails(tc.err) + if status != http.StatusTooManyRequests { + t.Errorf("status = %d, want 429", status) + } + if code != "rate_limit_exceeded" { + t.Errorf("code = %q, want rate_limit_exceeded", code) + } + if retryAfter < 3599 || retryAfter > 3601 { + t.Errorf("retryAfter = %d, want ~3600", retryAfter) + } + }) + } +} diff --git a/backend/internal/handler/gateway_handler_chat_completions.go b/backend/internal/handler/gateway_handler_chat_completions.go index 9a091fcd..acbdc261 100644 --- a/backend/internal/handler/gateway_handler_chat_completions.go +++ b/backend/internal/handler/gateway_handler_chat_completions.go @@ -140,7 +140,7 @@ func (h *GatewayHandler) ChatCompletions(c *gin.Context) { } // 2. Re-check billing - if err := h.billingCacheService.CheckBillingEligibility(c.Request.Context(), apiKey.User, apiKey, apiKey.Group, subscription); err != nil { + if err := h.billingCacheService.CheckBillingEligibility(c.Request.Context(), apiKey.User, apiKey, apiKey.Group, subscription, service.QuotaPlatform(c.Request.Context(), apiKey)); err != nil { reqLog.Info("gateway.cc.billing_check_failed", zap.Error(err)) status, code, message, retryAfter := billingErrorDetails(err) if retryAfter > 0 { @@ -291,9 +291,11 @@ func (h *GatewayHandler) ChatCompletions(c *gin.Context) { inboundEndpoint := GetInboundEndpoint(c) upstreamEndpoint := GetUpstreamEndpoint(c, account.Platform) + quotaPlatform := service.QuotaPlatform(c.Request.Context(), apiKey) h.submitUsageRecordTask(func(ctx context.Context) { if err := h.gatewayService.RecordUsage(ctx, &service.RecordUsageInput{ Result: result, + QuotaPlatform: quotaPlatform, APIKey: apiKey, User: apiKey.User, Account: account, diff --git a/backend/internal/handler/gateway_handler_responses.go b/backend/internal/handler/gateway_handler_responses.go index e1a5b723..6a083f31 100644 --- a/backend/internal/handler/gateway_handler_responses.go +++ b/backend/internal/handler/gateway_handler_responses.go @@ -145,7 +145,7 @@ func (h *GatewayHandler) Responses(c *gin.Context) { } // 2. Re-check billing - if err := h.billingCacheService.CheckBillingEligibility(c.Request.Context(), apiKey.User, apiKey, apiKey.Group, subscription); err != nil { + if err := h.billingCacheService.CheckBillingEligibility(c.Request.Context(), apiKey.User, apiKey, apiKey.Group, subscription, service.QuotaPlatform(c.Request.Context(), apiKey)); err != nil { reqLog.Info("gateway.responses.billing_check_failed", zap.Error(err)) status, code, message, retryAfter := billingErrorDetails(err) if retryAfter > 0 { @@ -266,9 +266,11 @@ func (h *GatewayHandler) Responses(c *gin.Context) { inboundEndpoint := GetInboundEndpoint(c) upstreamEndpoint := GetUpstreamEndpoint(c, account.Platform) + quotaPlatform := service.QuotaPlatform(c.Request.Context(), apiKey) h.submitUsageRecordTask(func(ctx context.Context) { if err := h.gatewayService.RecordUsage(ctx, &service.RecordUsageInput{ Result: result, + QuotaPlatform: quotaPlatform, APIKey: apiKey, User: apiKey.User, Account: account, diff --git a/backend/internal/handler/gateway_handler_warmup_intercept_unit_test.go b/backend/internal/handler/gateway_handler_warmup_intercept_unit_test.go index 57554cf9..09b20722 100644 --- a/backend/internal/handler/gateway_handler_warmup_intercept_unit_test.go +++ b/backend/internal/handler/gateway_handler_warmup_intercept_unit_test.go @@ -172,11 +172,12 @@ func newTestGatewayHandler(t *testing.T, group *service.Group, accounts []*servi nil, // channelService nil, // resolver nil, // balanceNotifyService + nil, // userPlatformQuotaRepo ) // RunModeSimple:跳过计费检查,避免引入 repo/cache 依赖。 cfg := &config.Config{RunMode: config.RunModeSimple} - billingCacheSvc := service.NewBillingCacheService(nil, nil, nil, nil, nil, nil, cfg) + billingCacheSvc := service.NewBillingCacheService(nil, nil, nil, nil, nil, nil, cfg, nil) concurrencySvc := service.NewConcurrencyService(&fakeConcurrencyCache{}) concurrencyHelper := NewConcurrencyHelper(concurrencySvc, SSEPingFormatClaude, 0) diff --git a/backend/internal/handler/gateway_models_test.go b/backend/internal/handler/gateway_models_test.go index af52ae23..78b07a1a 100644 --- a/backend/internal/handler/gateway_models_test.go +++ b/backend/internal/handler/gateway_models_test.go @@ -43,7 +43,7 @@ func newGatewayModelsHandlerForTest(repo service.AccountRepository) *GatewayHand gatewayService: service.NewGatewayService( repo, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, ), } } diff --git a/backend/internal/handler/gemini_v1beta_handler.go b/backend/internal/handler/gemini_v1beta_handler.go index 665c0677..27ea4404 100644 --- a/backend/internal/handler/gemini_v1beta_handler.go +++ b/backend/internal/handler/gemini_v1beta_handler.go @@ -247,7 +247,7 @@ func (h *GatewayHandler) GeminiV1BetaModels(c *gin.Context) { } // 2) billing eligibility check (after wait) - if err := h.billingCacheService.CheckBillingEligibility(c.Request.Context(), apiKey.User, apiKey, apiKey.Group, subscription); err != nil { + if err := h.billingCacheService.CheckBillingEligibility(c.Request.Context(), apiKey.User, apiKey, apiKey.Group, subscription, service.QuotaPlatform(c.Request.Context(), apiKey)); err != nil { reqLog.Info("gemini.billing_eligibility_check_failed", zap.Error(err)) status, _, message, retryAfter := billingErrorDetails(err) if retryAfter > 0 { @@ -527,9 +527,11 @@ func (h *GatewayHandler) GeminiV1BetaModels(c *gin.Context) { requestPayloadHash := service.HashUsageRequestPayload(body) inboundEndpoint := GetInboundEndpoint(c) upstreamEndpoint := GetUpstreamEndpoint(c, account.Platform) + quotaPlatform := service.QuotaPlatform(c.Request.Context(), apiKey) h.submitUsageRecordTask(func(ctx context.Context) { if err := h.gatewayService.RecordUsageWithLongContext(ctx, &service.RecordUsageLongContextInput{ Result: result, + QuotaPlatform: quotaPlatform, APIKey: apiKey, User: apiKey.User, Account: account, diff --git a/backend/internal/handler/image_concurrency_limiter_test.go b/backend/internal/handler/image_concurrency_limiter_test.go index 20147f16..723c26d0 100644 --- a/backend/internal/handler/image_concurrency_limiter_test.go +++ b/backend/internal/handler/image_concurrency_limiter_test.go @@ -206,7 +206,7 @@ func TestOpenAIGatewayHandlerResponses_TextOnlyNotRejectedByImageConcurrency(t * h := &OpenAIGatewayHandler{ gatewayService: &service.OpenAIGatewayService{}, - billingCacheService: service.NewBillingCacheService(nil, nil, nil, nil, nil, nil, &config.Config{RunMode: config.RunModeSimple}), + billingCacheService: service.NewBillingCacheService(nil, nil, nil, nil, nil, nil, &config.Config{RunMode: config.RunModeSimple}, nil), apiKeyService: &service.APIKeyService{}, concurrencyHelper: &ConcurrencyHelper{concurrencyService: service.NewConcurrencyService(&helperConcurrencyCacheStub{userSeq: []bool{true}})}, cfg: &config.Config{Gateway: config.GatewayConfig{ImageConcurrency: config.ImageConcurrencyConfig{ diff --git a/backend/internal/handler/openai_chat_completions.go b/backend/internal/handler/openai_chat_completions.go index 4d523dba..17f0d47e 100644 --- a/backend/internal/handler/openai_chat_completions.go +++ b/backend/internal/handler/openai_chat_completions.go @@ -106,7 +106,7 @@ func (h *OpenAIGatewayHandler) ChatCompletions(c *gin.Context) { defer userReleaseFunc() } - if err := h.billingCacheService.CheckBillingEligibility(c.Request.Context(), apiKey.User, apiKey, apiKey.Group, subscription); err != nil { + if err := h.billingCacheService.CheckBillingEligibility(c.Request.Context(), apiKey.User, apiKey, apiKey.Group, subscription, service.QuotaPlatform(c.Request.Context(), apiKey)); err != nil { reqLog.Info("openai_chat_completions.billing_eligibility_check_failed", zap.Error(err)) status, code, message, retryAfter := billingErrorDetails(err) if retryAfter > 0 { diff --git a/backend/internal/handler/openai_gateway_handler.go b/backend/internal/handler/openai_gateway_handler.go index 5464d654..88ece8e7 100644 --- a/backend/internal/handler/openai_gateway_handler.go +++ b/backend/internal/handler/openai_gateway_handler.go @@ -243,7 +243,7 @@ func (h *OpenAIGatewayHandler) Responses(c *gin.Context) { } // 2. Re-check billing eligibility after wait - if err := h.billingCacheService.CheckBillingEligibility(c.Request.Context(), apiKey.User, apiKey, apiKey.Group, subscription); err != nil { + if err := h.billingCacheService.CheckBillingEligibility(c.Request.Context(), apiKey.User, apiKey, apiKey.Group, subscription, service.QuotaPlatform(c.Request.Context(), apiKey)); err != nil { reqLog.Info("openai.billing_eligibility_check_failed", zap.Error(err)) status, code, message, retryAfter := billingErrorDetails(err) if retryAfter > 0 { @@ -648,7 +648,7 @@ func (h *OpenAIGatewayHandler) Messages(c *gin.Context) { defer userReleaseFunc() } - if err := h.billingCacheService.CheckBillingEligibility(c.Request.Context(), apiKey.User, apiKey, apiKey.Group, subscription); err != nil { + if err := h.billingCacheService.CheckBillingEligibility(c.Request.Context(), apiKey.User, apiKey, apiKey.Group, subscription, service.QuotaPlatform(c.Request.Context(), apiKey)); err != nil { reqLog.Info("openai_messages.billing_eligibility_check_failed", zap.Error(err)) status, code, message, retryAfter := billingErrorDetails(err) if retryAfter > 0 { @@ -1235,7 +1235,7 @@ func (h *OpenAIGatewayHandler) ResponsesWebSocket(c *gin.Context) { currentUserRelease = wrapReleaseOnDone(ctx, userReleaseFunc) subscription, _ := middleware2.GetSubscriptionFromContext(c) - if err := h.billingCacheService.CheckBillingEligibility(ctx, apiKey.User, apiKey, apiKey.Group, subscription); err != nil { + if err := h.billingCacheService.CheckBillingEligibility(ctx, apiKey.User, apiKey, apiKey.Group, subscription, service.QuotaPlatform(c.Request.Context(), apiKey)); err != nil { reqLog.Info("openai.websocket_billing_eligibility_check_failed", zap.Error(err)) closeOpenAIClientWS(wsConn, coderws.StatusPolicyViolation, "billing check failed") return diff --git a/backend/internal/handler/openai_gateway_handler_test.go b/backend/internal/handler/openai_gateway_handler_test.go index 49b7b9ec..b304640e 100644 --- a/backend/internal/handler/openai_gateway_handler_test.go +++ b/backend/internal/handler/openai_gateway_handler_test.go @@ -1201,7 +1201,7 @@ func runOpenAIResponsesWebSocketUsageLogCase(t *testing.T, tc openAIResponsesWSU }, nil, nil, nil) } - billingCacheSvc := service.NewBillingCacheService(nil, nil, nil, nil, nil, nil, cfg) + billingCacheSvc := service.NewBillingCacheService(nil, nil, nil, nil, nil, nil, cfg, nil) gatewaySvc := service.NewOpenAIGatewayService( accountRepo, usageRepo, @@ -1223,6 +1223,7 @@ func runOpenAIResponsesWebSocketUsageLogCase(t *testing.T, tc openAIResponsesWSU channelSvc, nil, nil, + nil, // userPlatformQuotaRepo ) cache := &concurrencyCacheMock{ diff --git a/backend/internal/handler/openai_images.go b/backend/internal/handler/openai_images.go index e6c37272..bbb08014 100644 --- a/backend/internal/handler/openai_images.go +++ b/backend/internal/handler/openai_images.go @@ -123,7 +123,7 @@ func (h *OpenAIGatewayHandler) Images(c *gin.Context) { defer userReleaseFunc() } - if err := h.billingCacheService.CheckBillingEligibility(c.Request.Context(), apiKey.User, apiKey, apiKey.Group, subscription); err != nil { + if err := h.billingCacheService.CheckBillingEligibility(c.Request.Context(), apiKey.User, apiKey, apiKey.Group, subscription, service.QuotaPlatform(c.Request.Context(), apiKey)); err != nil { reqLog.Info("openai.images.billing_eligibility_check_failed", zap.Error(err)) status, code, message, retryAfter := billingErrorDetails(err) if retryAfter > 0 { diff --git a/backend/internal/handler/quotaview/helpers.go b/backend/internal/handler/quotaview/helpers.go new file mode 100644 index 00000000..ff4e44a1 --- /dev/null +++ b/backend/internal/handler/quotaview/helpers.go @@ -0,0 +1,104 @@ +// Package quotaview provides shared quota response helpers for user and admin handlers. +// Extracted to avoid import cycles between handler and handler/admin packages. +package quotaview + +import ( + "time" + + "github.com/Wei-Shaw/sub2api/internal/pkg/timezone" + "github.com/Wei-Shaw/sub2api/internal/service" +) + +// LazyZeroQuotaForResponse 按 D14 规则把过期档位归零(不写 DB)。 +// includeWindowStart=true 时输出 *_window_start 字段(admin 视角调试用) +func LazyZeroQuotaForResponse(r service.UserPlatformQuotaRecord, now time.Time, includeWindowStart bool) map[string]any { + daily := buildWindowSlice(r.DailyUsageUSD, r.DailyLimitUSD, r.DailyWindowStart, NeedsDailyReset(r.DailyWindowStart, now), nextDailyResetTime(now), includeWindowStart) + weekly := buildWindowSlice(r.WeeklyUsageUSD, r.WeeklyLimitUSD, r.WeeklyWindowStart, NeedsWeeklyReset(r.WeeklyWindowStart, now), nextWeeklyResetTime(now), includeWindowStart) + monthly := buildWindowSlice(r.MonthlyUsageUSD, r.MonthlyLimitUSD, r.MonthlyWindowStart, NeedsMonthlyReset(r.MonthlyWindowStart, now), NextMonthlyResetTimeFrom(r.MonthlyWindowStart, now), includeWindowStart) + out := map[string]any{ + "platform": r.Platform, + "daily_usage_usd": daily.usage, + "daily_limit_usd": daily.limit, + "daily_window_resets_at": daily.resetsAt, + "weekly_usage_usd": weekly.usage, + "weekly_limit_usd": weekly.limit, + "weekly_window_resets_at": weekly.resetsAt, + "monthly_usage_usd": monthly.usage, + "monthly_limit_usd": monthly.limit, + "monthly_window_resets_at": monthly.resetsAt, + } + if includeWindowStart { + out["daily_window_start"] = daily.windowStart + out["weekly_window_start"] = weekly.windowStart + out["monthly_window_start"] = monthly.windowStart + } + return out +} + +type windowSlice struct { + usage float64 + limit *float64 + resetsAt *string + windowStart *string +} + +func buildWindowSlice(usage float64, limit *float64, start *time.Time, expired bool, nextReset time.Time, includeStart bool) windowSlice { + out := windowSlice{usage: usage, limit: limit} + if expired { + out.usage = 0 + out.resetsAt = nil + } else if start != nil { + s := nextReset.Format(time.RFC3339) + out.resetsAt = &s + } + if includeStart && start != nil { + s := start.Format(time.RFC3339) + out.windowStart = &s + } + return out +} + +// NeedsDailyReset 判断日窗口是否已过期:start 早于「全局时区当天 0 点」即过期。 +// 时区跟随 timezone.Location()(全局服务器时区),与 billing / repo 写入的 window_start 同口径。 +func NeedsDailyReset(start *time.Time, now time.Time) bool { + if start == nil { + return false + } + return start.Before(timezone.StartOfDay(now)) +} + +func NeedsWeeklyReset(start *time.Time, now time.Time) bool { + if start == nil { + return false + } + return start.Before(timezone.StartOfWeek(now)) +} + +// NeedsMonthlyReset 30 天滚动窗口语义(与订阅模式 NeedsMonthlyReset 一致)。 +func NeedsMonthlyReset(start *time.Time, now time.Time) bool { + if start == nil { + return false + } + return now.Sub(*start) >= 30*24*time.Hour +} + +func nextDailyResetTime(now time.Time) time.Time { + return timezone.StartOfDay(now).AddDate(0, 0, 1) +} + +func nextWeeklyResetTime(now time.Time) time.Time { + return timezone.StartOfWeek(now).AddDate(0, 0, 7) +} + +// NextMonthlyResetTimeFrom 计算 30 天滚动月度窗口的下次重置时间。 +// 语义: +// - start != nil → 返回 start + 30d(与 billing_cache_service.nextMonthlyResetFrom 一致) +// - start == nil → 退化为 now + 30d(保留旧行为,避免 nil 崩溃) +// +// 导出(首字母大写)以允许测试直接调用。 +func NextMonthlyResetTimeFrom(start *time.Time, now time.Time) time.Time { + if start == nil { + return now.Add(30 * 24 * time.Hour) + } + return start.Add(30 * 24 * time.Hour) +} diff --git a/backend/internal/handler/quotaview/helpers_test.go b/backend/internal/handler/quotaview/helpers_test.go new file mode 100644 index 00000000..ca2fcc4e --- /dev/null +++ b/backend/internal/handler/quotaview/helpers_test.go @@ -0,0 +1,133 @@ +package quotaview + +import ( + "testing" + "time" + + "github.com/Wei-Shaw/sub2api/internal/pkg/timezone" + "github.com/Wei-Shaw/sub2api/internal/service" +) + +// TestNextMonthlyResetTimeFrom_FromStart 验证:start 已知时返回 start+30d,不随 now 漂移。 +func TestNextMonthlyResetTimeFrom_FromStart(t *testing.T) { + t0 := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC) + now := t0.Add(15 * 24 * time.Hour) // t0 + 15d + want := t0.Add(30 * 24 * time.Hour) // t0 + 30d + + got := NextMonthlyResetTimeFrom(&t0, now) + if !got.Equal(want) { + t.Errorf("NextMonthlyResetTimeFrom: want %v, got %v", want, got) + } +} + +// TestNextMonthlyResetTimeFrom_NilStart 验证:start=nil 时退化为 now+30d(不 panic)。 +func TestNextMonthlyResetTimeFrom_NilStart(t *testing.T) { + now := time.Date(2024, 3, 15, 12, 0, 0, 0, time.UTC) + want := now.Add(30 * 24 * time.Hour) + + got := NextMonthlyResetTimeFrom(nil, now) + if !got.Equal(want) { + t.Errorf("NextMonthlyResetTimeFrom(nil): want %v, got %v", want, got) + } +} + +// TestLazyZeroQuotaForResponse_MonthlyResetsAt_NotDrifting 验证: +// 连续两次以不同 now 调用、但 MonthlyWindowStart 相同的 record, +// monthly_window_resets_at 始终等于 windowStart+30d,不随 now 漂移。 +func TestLazyZeroQuotaForResponse_MonthlyResetsAt_NotDrifting(t *testing.T) { + windowStart := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC) + wantResetsAt := windowStart.Add(30 * 24 * time.Hour).Format(time.RFC3339) + + r := service.UserPlatformQuotaRecord{ + Platform: "openai", + MonthlyUsageUSD: 5.0, + MonthlyWindowStart: &windowStart, + } + + // 第一次调用:now = windowStart + 5d + now1 := windowStart.Add(5 * 24 * time.Hour) + out1 := LazyZeroQuotaForResponse(r, now1, false) + resetsAt1, ok1 := out1["monthly_window_resets_at"] + if !ok1 || resetsAt1 == nil { + t.Fatal("first call: monthly_window_resets_at should be set for active window") + } + s1, ok := resetsAt1.(*string) + if !ok || s1 == nil { + t.Fatalf("first call: monthly_window_resets_at should be *string, got %T", resetsAt1) + } + if *s1 != wantResetsAt { + t.Errorf("first call: want %s, got %s", wantResetsAt, *s1) + } + + // 第二次调用:now = windowStart + 10d(不同 now,但 resetsAt 应不变) + now2 := windowStart.Add(10 * 24 * time.Hour) + out2 := LazyZeroQuotaForResponse(r, now2, false) + resetsAt2, ok2 := out2["monthly_window_resets_at"] + if !ok2 || resetsAt2 == nil { + t.Fatal("second call: monthly_window_resets_at should be set for active window") + } + s2, ok := resetsAt2.(*string) + if !ok || s2 == nil { + t.Fatalf("second call: monthly_window_resets_at should be *string, got %T", resetsAt2) + } + if *s2 != wantResetsAt { + t.Errorf("second call: want %s, got %s", wantResetsAt, *s2) + } + + // 两次结果必须相等 + if *s1 != *s2 { + t.Errorf("resetsAt drifted between calls: %s vs %s", *s1, *s2) + } +} + +// TestNeedsDailyReset_FollowsServerTimezone 验证日窗口过期判断按全局时区(北京 0 点)而非 UTC。 +func TestNeedsDailyReset_FollowsServerTimezone(t *testing.T) { + if err := timezone.Init("Asia/Shanghai"); err != nil { + t.Fatalf("Init: %v", err) + } + t.Cleanup(func() { _ = timezone.Init("UTC") }) + + // now = 2026-05-25 23:00 UTC = 2026-05-26 07:00 +08(北京 5/26) + now := time.Date(2026, 5, 25, 23, 0, 0, 0, time.UTC) + + // start = 2026-05-25 10:00 UTC = 2026-05-25 18:00 +08(北京 5/25)→ 应判定为过期 + startPrevBeijingDay := time.Date(2026, 5, 25, 10, 0, 0, 0, time.UTC) + if !NeedsDailyReset(&startPrevBeijingDay, now) { + t.Error("上一个北京日的窗口应判定为过期") + } + + // start = 2026-05-25 20:00 UTC = 2026-05-26 04:00 +08(北京 5/26 同日)→ 不应过期 + startSameBeijingDay := time.Date(2026, 5, 25, 20, 0, 0, 0, time.UTC) + if NeedsDailyReset(&startSameBeijingDay, now) { + t.Error("同一北京日的窗口不应判定为过期") + } +} + +// TestNextDailyResetTime_FollowsServerTimezone 验证下次日重置 = 次日北京 0 点。 +func TestNextDailyResetTime_FollowsServerTimezone(t *testing.T) { + if err := timezone.Init("Asia/Shanghai"); err != nil { + t.Fatalf("Init: %v", err) + } + t.Cleanup(func() { _ = timezone.Init("UTC") }) + + now := time.Date(2026, 5, 25, 23, 0, 0, 0, time.UTC) // 北京 5/26 07:00 + want := time.Date(2026, 5, 27, 0, 0, 0, 0, timezone.Location()) // 北京 5/27 00:00 + if got := nextDailyResetTime(now); !got.Equal(want) { + t.Errorf("nextDailyResetTime = %v, want %v", got, want) + } +} + +// TestNextWeeklyResetTime_FollowsServerTimezone 验证下次周重置 = 下周一北京 0 点。 +func TestNextWeeklyResetTime_FollowsServerTimezone(t *testing.T) { + if err := timezone.Init("Asia/Shanghai"); err != nil { + t.Fatalf("Init: %v", err) + } + t.Cleanup(func() { _ = timezone.Init("UTC") }) + + // 北京 2026-05-26(周二)→ 下周一是 2026-06-01 + now := time.Date(2026, 5, 25, 23, 0, 0, 0, time.UTC) // 北京 5/26 07:00 周二 + want := time.Date(2026, 6, 1, 0, 0, 0, 0, timezone.Location()) + if got := nextWeeklyResetTime(now); !got.Equal(want) { + t.Errorf("nextWeeklyResetTime = %v, want %v", got, want) + } +} diff --git a/backend/internal/handler/user_handler.go b/backend/internal/handler/user_handler.go index 95cb1482..d4b10b2b 100644 --- a/backend/internal/handler/user_handler.go +++ b/backend/internal/handler/user_handler.go @@ -3,8 +3,10 @@ package handler import ( "context" "strings" + "time" "github.com/Wei-Shaw/sub2api/internal/handler/dto" + "github.com/Wei-Shaw/sub2api/internal/handler/quotaview" "github.com/Wei-Shaw/sub2api/internal/pkg/response" middleware2 "github.com/Wei-Shaw/sub2api/internal/server/middleware" "github.com/Wei-Shaw/sub2api/internal/service" @@ -14,11 +16,12 @@ import ( // UserHandler handles user-related requests type UserHandler struct { - userService *service.UserService - authService *service.AuthService - emailService *service.EmailService - emailCache service.EmailCache - affiliateService *service.AffiliateService + userService *service.UserService + authService *service.AuthService + emailService *service.EmailService + emailCache service.EmailCache + affiliateService *service.AffiliateService + userPlatformQuotaRepo service.UserPlatformQuotaRepository } // NewUserHandler creates a new UserHandler @@ -28,16 +31,44 @@ func NewUserHandler( emailService *service.EmailService, emailCache service.EmailCache, affiliateService *service.AffiliateService, + userPlatformQuotaRepo service.UserPlatformQuotaRepository, ) *UserHandler { return &UserHandler{ - userService: userService, - authService: authService, - emailService: emailService, - emailCache: emailCache, - affiliateService: affiliateService, + userService: userService, + authService: authService, + emailService: emailService, + emailCache: emailCache, + affiliateService: affiliateService, + userPlatformQuotaRepo: userPlatformQuotaRepo, } } +// GetMyPlatformQuotas GET /user/platform-quotas +// 返回当前 JWT 用户的 platform quota 状态。 +// D14: 对每条记录逐档判断窗口过期,过期档位 usage=0、window_resets_at=null(不写 DB) +func (h *UserHandler) GetMyPlatformQuotas(c *gin.Context) { + subject, ok := middleware2.GetAuthSubjectFromContext(c) + if !ok { + response.Unauthorized(c, "User not authenticated") + return + } + if h.userPlatformQuotaRepo == nil { + response.Success(c, map[string]any{"platform_quotas": []any{}}) + return + } + records, err := h.userPlatformQuotaRepo.ListByUser(c.Request.Context(), subject.UserID) + if err != nil { + response.ErrorFrom(c, err) + return + } + now := time.Now().UTC() + out := make([]map[string]any, 0, len(records)) + for _, r := range records { + out = append(out, quotaview.LazyZeroQuotaForResponse(r, now, false)) + } + response.Success(c, map[string]any{"platform_quotas": out}) +} + // ChangePasswordRequest represents the change password request payload type ChangePasswordRequest struct { OldPassword string `json:"old_password" binding:"required"` diff --git a/backend/internal/handler/user_handler_test.go b/backend/internal/handler/user_handler_test.go index ffca86dc..41647802 100644 --- a/backend/internal/handler/user_handler_test.go +++ b/backend/internal/handler/user_handler_test.go @@ -87,8 +87,12 @@ func (s *userHandlerRepoStub) ListWithFilters(context.Context, pagination.Pagina func (s *userHandlerRepoStub) UpdateBalance(context.Context, int64, float64) error { return nil } func (s *userHandlerRepoStub) DeductBalance(context.Context, int64, float64) error { return nil } func (s *userHandlerRepoStub) UpdateConcurrency(context.Context, int64, int) error { return nil } -func (s *userHandlerRepoStub) BatchSetConcurrency(context.Context, []int64, int) (int, error) { return 0, nil } -func (s *userHandlerRepoStub) BatchAddConcurrency(context.Context, []int64, int) (int, error) { return 0, nil } +func (s *userHandlerRepoStub) BatchSetConcurrency(context.Context, []int64, int) (int, error) { + return 0, nil +} +func (s *userHandlerRepoStub) BatchAddConcurrency(context.Context, []int64, int) (int, error) { + return 0, nil +} func (s *userHandlerRepoStub) ExistsByEmail(context.Context, string) (bool, error) { return false, nil } func (s *userHandlerRepoStub) RemoveGroupFromAllowedGroups(context.Context, int64) (int64, error) { return 0, nil @@ -144,7 +148,7 @@ func TestUserHandlerUpdateProfileReturnsAvatarURL(t *testing.T) { Status: service.StatusActive, }, } - handler := NewUserHandler(service.NewUserService(repo, nil, nil, nil), nil, nil, nil, nil) + handler := NewUserHandler(service.NewUserService(repo, nil, nil, nil), nil, nil, nil, nil, nil) body := []byte(`{"avatar_url":"https://cdn.example.com/avatar.png"}`) recorder := httptest.NewRecorder() @@ -202,7 +206,7 @@ func TestUserHandlerGetProfileReturnsIdentitySummaries(t *testing.T) { }, }, } - handler := NewUserHandler(service.NewUserService(repo, nil, nil, nil), nil, nil, nil, nil) + handler := NewUserHandler(service.NewUserService(repo, nil, nil, nil), nil, nil, nil, nil, nil) recorder := httptest.NewRecorder() c, _ := gin.CreateTestContext(recorder) @@ -272,20 +276,20 @@ func TestUserHandlerGetProfileReturnsLegacyCompatibilityFields(t *testing.T) { AvatarURL: "https://cdn.example.com/linuxdo.png", AvatarSource: "remote_url", }, - identities: []service.UserAuthIdentityRecord{ - { - ProviderType: "linuxdo", - ProviderKey: "linuxdo", - ProviderSubject: "linuxdo-subject-21", - VerifiedAt: &verifiedAt, - Metadata: map[string]any{ - "username": "linuxdo-handle", - "avatar_url": "https://cdn.example.com/linuxdo.png", - }, + identities: []service.UserAuthIdentityRecord{ + { + ProviderType: "linuxdo", + ProviderKey: "linuxdo", + ProviderSubject: "linuxdo-subject-21", + VerifiedAt: &verifiedAt, + Metadata: map[string]any{ + "username": "linuxdo-handle", + "avatar_url": "https://cdn.example.com/linuxdo.png", }, }, - } - handler := NewUserHandler(service.NewUserService(repo, nil, nil, nil), nil, nil, nil, nil) + }, + } + handler := NewUserHandler(service.NewUserService(repo, nil, nil, nil), nil, nil, nil, nil, nil) recorder := httptest.NewRecorder() c, _ := gin.CreateTestContext(recorder) @@ -364,7 +368,7 @@ func TestUserHandlerGetProfileDoesNotInferEditedProfileSourcesWithoutMatchingIde }, }, } - handler := NewUserHandler(service.NewUserService(repo, nil, nil, nil), nil, nil, nil, nil) + handler := NewUserHandler(service.NewUserService(repo, nil, nil, nil), nil, nil, nil, nil, nil) recorder := httptest.NewRecorder() c, _ := gin.CreateTestContext(recorder) @@ -513,8 +517,8 @@ func TestUserHandlerBindEmailIdentityReturnsProfileResponse(t *testing.T) { }, } emailService := service.NewEmailService(nil, emailCache) - authService := service.NewAuthService(nil, repo, nil, nil, cfg, nil, emailService, nil, nil, nil, nil, nil) - handler := NewUserHandler(service.NewUserService(repo, nil, nil, nil), authService, nil, nil, nil) + authService := service.NewAuthService(nil, repo, nil, nil, cfg, nil, emailService, nil, nil, nil, nil, nil, nil) + handler := NewUserHandler(service.NewUserService(repo, nil, nil, nil), authService, nil, nil, nil, nil) body := []byte(`{"email":"new@example.com","verify_code":"123456","password":"new-password"}`) recorder := httptest.NewRecorder() @@ -568,7 +572,7 @@ func TestUserHandlerUnbindIdentityReturnsUpdatedProfile(t *testing.T) { }, }, } - handler := NewUserHandler(service.NewUserService(repo, nil, nil, nil), nil, nil, nil, nil) + handler := NewUserHandler(service.NewUserService(repo, nil, nil, nil), nil, nil, nil, nil, nil) recorder := httptest.NewRecorder() c, _ := gin.CreateTestContext(recorder) @@ -627,8 +631,8 @@ func TestUserHandlerUnbindIdentityRevokesAllUserSessionsWhenAuthServiceConfigure ExpireHour: 1, }, } - authService := service.NewAuthService(nil, repo, nil, refreshTokenCache, cfg, nil, nil, nil, nil, nil, nil, nil) - handler := NewUserHandler(service.NewUserService(repo, nil, nil, nil), authService, nil, nil, nil) + authService := service.NewAuthService(nil, repo, nil, refreshTokenCache, cfg, nil, nil, nil, nil, nil, nil, nil, nil) + handler := NewUserHandler(service.NewUserService(repo, nil, nil, nil), authService, nil, nil, nil, nil) recorder := httptest.NewRecorder() c, _ := gin.CreateTestContext(recorder) @@ -670,8 +674,8 @@ func TestUserHandlerUnbindIdentityDoesNotRevokeSessionsWhenNothingWasUnbound(t * ExpireHour: 1, }, } - authService := service.NewAuthService(nil, repo, nil, refreshTokenCache, cfg, nil, nil, nil, nil, nil, nil, nil) - handler := NewUserHandler(service.NewUserService(repo, nil, nil, nil), authService, nil, nil, nil) + authService := service.NewAuthService(nil, repo, nil, refreshTokenCache, cfg, nil, nil, nil, nil, nil, nil, nil, nil) + handler := NewUserHandler(service.NewUserService(repo, nil, nil, nil), authService, nil, nil, nil, nil) recorder := httptest.NewRecorder() c, _ := gin.CreateTestContext(recorder) @@ -714,8 +718,8 @@ func TestUserHandlerBindEmailIdentityRejectsWrongCurrentPasswordForBoundEmail(t }, } emailService := service.NewEmailService(nil, emailCache) - authService := service.NewAuthService(nil, repo, nil, nil, cfg, nil, emailService, nil, nil, nil, nil, nil) - handler := NewUserHandler(service.NewUserService(repo, nil, nil, nil), authService, nil, nil, nil) + authService := service.NewAuthService(nil, repo, nil, nil, cfg, nil, emailService, nil, nil, nil, nil, nil, nil) + handler := NewUserHandler(service.NewUserService(repo, nil, nil, nil), authService, nil, nil, nil, nil) body := []byte(`{"email":"new@example.com","verify_code":"123456","password":"wrong-password"}`) recorder := httptest.NewRecorder() @@ -752,7 +756,7 @@ func TestUserHandlerStartIdentityBindingReturnsAuthorizeURL(t *testing.T) { Status: service.StatusActive, }, } - handler := NewUserHandler(service.NewUserService(repo, nil, nil, nil), nil, nil, nil, nil) + handler := NewUserHandler(service.NewUserService(repo, nil, nil, nil), nil, nil, nil, nil, nil) body := []byte(`{"provider":"wechat","redirect_to":"/settings/profile"}`) recorder := httptest.NewRecorder() diff --git a/backend/internal/handler/user_platform_quotas_handler_test.go b/backend/internal/handler/user_platform_quotas_handler_test.go new file mode 100644 index 00000000..96d13fd3 --- /dev/null +++ b/backend/internal/handler/user_platform_quotas_handler_test.go @@ -0,0 +1,212 @@ +//go:build unit + +package handler + +import ( + "context" + "encoding/json" + "net/http" + "net/http/httptest" + "strings" + "testing" + "time" + + "github.com/Wei-Shaw/sub2api/internal/handler/quotaview" + "github.com/Wei-Shaw/sub2api/internal/pkg/timezone" + middleware2 "github.com/Wei-Shaw/sub2api/internal/server/middleware" + "github.com/Wei-Shaw/sub2api/internal/service" + "github.com/gin-gonic/gin" +) + +// fakeQuotaRepoForUserHandler 实现 service.UserPlatformQuotaRepository 最小子集 +type fakeQuotaRepoForUserHandler struct { + service.UserPlatformQuotaRepository + records []service.UserPlatformQuotaRecord +} + +func (f *fakeQuotaRepoForUserHandler) ListByUser(_ context.Context, _ int64) ([]service.UserPlatformQuotaRecord, error) { + return f.records, nil +} + +func TestGetMyPlatformQuotas_EmptyReturns200WithEmptyArray(t *testing.T) { + repo := &fakeQuotaRepoForUserHandler{records: nil} + h := &UserHandler{userPlatformQuotaRepo: repo} + gin.SetMode(gin.TestMode) + w := httptest.NewRecorder() + c, _ := gin.CreateTestContext(w) + c.Request = httptest.NewRequest(http.MethodGet, "/user/platform-quotas", nil) + c.Set(string(middleware2.ContextKeyUser), middleware2.AuthSubject{UserID: 42}) + h.GetMyPlatformQuotas(c) + if w.Code != 200 { + t.Fatalf("expected 200, got %d. body: %s", w.Code, w.Body.String()) + } + var body struct { + Code int `json:"code"` + Data struct { + PlatformQuotas []any `json:"platform_quotas"` + } `json:"data"` + } + if err := json.Unmarshal(w.Body.Bytes(), &body); err != nil { + t.Fatalf("unmarshal error: %v, body: %s", err, w.Body.String()) + } + if body.Code != 0 { + t.Errorf("expected code=0, got %d", body.Code) + } + if body.Data.PlatformQuotas == nil { + // nil 和 empty slice 均视为可接受(JSON 可能序列化为 null 或 []) + // 此断言只验证 HTTP 200 + code=0 即可 + } +} + +func TestGetMyPlatformQuotas_D14_LazyZeroForExpiredWindow(t *testing.T) { + pastStart := time.Now().UTC().AddDate(0, 0, -2) + daily := 5.0 + repo := &fakeQuotaRepoForUserHandler{records: []service.UserPlatformQuotaRecord{{ + UserID: 42, + Platform: "anthropic", + DailyLimitUSD: &daily, + DailyUsageUSD: 3.0, + DailyWindowStart: &pastStart, + }}} + h := &UserHandler{userPlatformQuotaRepo: repo} + gin.SetMode(gin.TestMode) + w := httptest.NewRecorder() + c, _ := gin.CreateTestContext(w) + c.Request = httptest.NewRequest(http.MethodGet, "/user/platform-quotas", nil) + c.Set(string(middleware2.ContextKeyUser), middleware2.AuthSubject{UserID: 42}) + h.GetMyPlatformQuotas(c) + + if w.Code != 200 { + t.Fatalf("expected 200, got %d. body: %s", w.Code, w.Body.String()) + } + + // 解析 response,验证过期 daily 的 usage_usd=0 且 window_resets_at=null + body := w.Body.String() + if !strings.Contains(body, `"daily_usage_usd":0`) { + t.Errorf("expected daily_usage_usd:0 in body, got: %s", body) + } + if !strings.Contains(body, `"daily_window_resets_at":null`) { + t.Errorf("expected daily_window_resets_at:null in body, got: %s", body) + } +} + +func TestGetMyPlatformQuotas_NilRepo_Returns200Empty(t *testing.T) { + h := &UserHandler{userPlatformQuotaRepo: nil} + gin.SetMode(gin.TestMode) + w := httptest.NewRecorder() + c, _ := gin.CreateTestContext(w) + c.Request = httptest.NewRequest(http.MethodGet, "/user/platform-quotas", nil) + c.Set(string(middleware2.ContextKeyUser), middleware2.AuthSubject{UserID: 99}) + h.GetMyPlatformQuotas(c) + if w.Code != 200 { + t.Fatalf("expected 200, got %d", w.Code) + } +} + +func TestGetMyPlatformQuotas_NoAuth_Returns401(t *testing.T) { + h := &UserHandler{userPlatformQuotaRepo: nil} + gin.SetMode(gin.TestMode) + w := httptest.NewRecorder() + c, _ := gin.CreateTestContext(w) + c.Request = httptest.NewRequest(http.MethodGet, "/user/platform-quotas", nil) + // 不设置 auth subject + h.GetMyPlatformQuotas(c) + if w.Code != 401 { + t.Fatalf("expected 401, got %d", w.Code) + } +} + +func TestLazyZeroQuotaForResponse_UserViewStripsWindowStart(t *testing.T) { + start := time.Now().UTC().Add(-1 * time.Hour) + r := service.UserPlatformQuotaRecord{ + Platform: "anthropic", + DailyUsageUSD: 1.0, + DailyWindowStart: &start, + } + out := quotaview.LazyZeroQuotaForResponse(r, time.Now().UTC(), false) + if _, ok := out["daily_window_start"]; ok { + t.Error("user view should not include daily_window_start") + } +} + +func TestLazyZeroQuotaForResponse_AdminViewIncludesWindowStart(t *testing.T) { + start := time.Now().UTC().Add(-1 * time.Hour) + r := service.UserPlatformQuotaRecord{ + Platform: "anthropic", + DailyWindowStart: &start, + } + out := quotaview.LazyZeroQuotaForResponse(r, time.Now().UTC(), true) + if _, ok := out["daily_window_start"]; !ok { + t.Error("admin view should include daily_window_start") + } +} + +func TestLazyZeroQuotaForResponse_ActiveWindowPreservesUsage(t *testing.T) { + // 今天的窗口起始时间(不过期):按全局时区取当天 0 点,与 view 层同口径 + now := time.Now() + today := timezone.StartOfDay(now) + usage := 2.5 + r := service.UserPlatformQuotaRecord{ + Platform: "openai", + DailyUsageUSD: usage, + DailyWindowStart: &today, + } + out := quotaview.LazyZeroQuotaForResponse(r, now, false) + if out["daily_usage_usd"] != usage { + t.Errorf("expected daily_usage_usd=%v, got %v", usage, out["daily_usage_usd"]) + } + // 活跃窗口应有 resets_at(非 nil) + if out["daily_window_resets_at"] == nil { + t.Error("active window should have daily_window_resets_at set") + } +} + +func TestNeedsDailyReset_NilStart_ReturnsFalse(t *testing.T) { + if quotaview.NeedsDailyReset(nil, time.Now().UTC()) { + t.Error("nil start should not need reset") + } +} + +func TestNeedsDailyReset_OldStart_ReturnsTrue(t *testing.T) { + old := time.Now().UTC().AddDate(0, 0, -1) + if !quotaview.NeedsDailyReset(&old, time.Now().UTC()) { + t.Error("yesterday start should need daily reset") + } +} + +func TestNeedsWeeklyReset_NilStart_ReturnsFalse(t *testing.T) { + if quotaview.NeedsWeeklyReset(nil, time.Now().UTC()) { + t.Error("nil start should not need weekly reset") + } +} + +func TestNeedsMonthlyReset_NilStart_ReturnsFalse(t *testing.T) { + if quotaview.NeedsMonthlyReset(nil, time.Now().UTC()) { + t.Error("nil start should not need monthly reset") + } +} + +// TestNeedsMonthlyReset_30DayRolling 验证 30 天滚动语义(C-NEW-1)。 +func TestNeedsMonthlyReset_30DayRolling_Expired(t *testing.T) { + start := time.Now().UTC().Add(-31 * 24 * time.Hour) // 31 天前,已过期 + if !quotaview.NeedsMonthlyReset(&start, time.Now().UTC()) { + t.Error("31 days ago should need monthly reset (30-day rolling)") + } +} + +func TestNeedsMonthlyReset_30DayRolling_Active(t *testing.T) { + start := time.Now().UTC().Add(-15 * 24 * time.Hour) // 15 天前,窗口有效 + if quotaview.NeedsMonthlyReset(&start, time.Now().UTC()) { + t.Error("15 days ago should NOT need monthly reset (30-day rolling, still active)") + } +} + +// TestNeedsMonthlyReset_CrossMonthBoundary 验证跨自然月时 30 天未满不重置(旧自然月语义会提前重置)。 +func TestNeedsMonthlyReset_CrossMonthBoundary(t *testing.T) { + // 窗口起始 4 月 20 日;5 月 1 日仅过了 11 天,不足 30 天,不应重置 + windowStart := time.Date(2026, 4, 20, 0, 0, 0, 0, time.UTC) + now := time.Date(2026, 5, 1, 0, 0, 0, 0, time.UTC) + if quotaview.NeedsMonthlyReset(&windowStart, now) { + t.Error("cross-month boundary within 30 days should NOT trigger reset (30-day rolling)") + } +} diff --git a/backend/internal/pkg/timezone/timezone_test.go b/backend/internal/pkg/timezone/timezone_test.go index ac9cdde6..610b1bb9 100644 --- a/backend/internal/pkg/timezone/timezone_test.go +++ b/backend/internal/pkg/timezone/timezone_test.go @@ -135,3 +135,29 @@ func TestDSTAwareness(t *testing.T) { _ = Now() _ = StartOfDay(Now()) } + +func TestStartOfWeek_Boundaries(t *testing.T) { + if err := Init("Asia/Shanghai"); err != nil { + t.Fatalf("Init: %v", err) + } + t.Cleanup(func() { _ = Init("UTC") }) + + loc := Location() + wantMon := time.Date(2026, 5, 18, 0, 0, 0, 0, loc) // 2026-05-18 是周一 + + cases := []struct { + name string + in time.Time + }{ + {"friday", time.Date(2026, 5, 22, 14, 30, 0, 0, loc)}, + {"sunday", time.Date(2026, 5, 24, 10, 0, 0, 0, loc)}, + {"monday-self", time.Date(2026, 5, 18, 9, 15, 30, 0, loc)}, + } + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + if got := StartOfWeek(c.in); !got.Equal(wantMon) { + t.Errorf("StartOfWeek(%v) = %v, want %v", c.in, got, wantMon) + } + }) + } +} diff --git a/backend/internal/repository/billing_cache.go b/backend/internal/repository/billing_cache.go index 6922b4c8..60dae954 100644 --- a/backend/internal/repository/billing_cache.go +++ b/backend/internal/repository/billing_cache.go @@ -328,3 +328,174 @@ func (c *billingCache) InvalidateAPIKeyRateLimit(ctx context.Context, keyID int6 key := billingRateLimitKey(keyID) return c.rdb.Del(ctx, key).Err() } + +// ============================================ +// user × platform quota 缓存 +// ============================================ + +// userPlatformQuotaCacheKey 构造 Redis key +func userPlatformQuotaCacheKey(userID int64, platform string) string { + return fmt.Sprintf("billing:user_platform_quota:%d:%s", userID, platform) +} + +func (c *billingCache) GetUserPlatformQuotaCache(ctx context.Context, userID int64, platform string) (*service.UserPlatformQuotaCacheEntry, bool, error) { + key := userPlatformQuotaCacheKey(userID, platform) + fields := []string{ + "daily_usage", "weekly_usage", "monthly_usage", "version", "schema_version", + "daily_limit", "weekly_limit", "monthly_limit", + "daily_window_start", "weekly_window_start", "monthly_window_start", + } + vals, err := c.rdb.HMGet(ctx, key, fields...).Result() + if err != nil { + return nil, false, err + } + // 前4个全为nil → key 不存在 + if vals[0] == nil && vals[1] == nil && vals[2] == nil && vals[3] == nil { + return nil, false, nil + } + parseFloat := func(v any) float64 { + if v == nil { + return 0 + } + s, ok := v.(string) + if !ok { + return 0 + } + f, _ := strconv.ParseFloat(s, 64) + return f + } + parseFloatPtr := func(v any) *float64 { + if v == nil { + return nil + } + s, ok := v.(string) + if !ok || s == "" { + return nil + } + f, err := strconv.ParseFloat(s, 64) + if err != nil { + return nil + } + return &f + } + parseTimePtr := func(v any) *time.Time { + if v == nil { + return nil + } + s, ok := v.(string) + if !ok || s == "" { + return nil + } + n, err := strconv.ParseInt(s, 10, 64) + if err != nil { + return nil + } + t := time.Unix(n, 0).UTC() + return &t + } + parseInt64 := func(v any) int64 { + if v == nil { + return 0 + } + s, ok := v.(string) + if !ok { + return 0 + } + n, _ := strconv.ParseInt(s, 10, 64) + return n + } + return &service.UserPlatformQuotaCacheEntry{ + DailyUsageUSD: parseFloat(vals[0]), + WeeklyUsageUSD: parseFloat(vals[1]), + MonthlyUsageUSD: parseFloat(vals[2]), + Version: parseInt64(vals[3]), + SchemaVersion: parseInt64(vals[4]), + DailyLimitUSD: parseFloatPtr(vals[5]), + WeeklyLimitUSD: parseFloatPtr(vals[6]), + MonthlyLimitUSD: parseFloatPtr(vals[7]), + DailyWindowStart: parseTimePtr(vals[8]), + WeeklyWindowStart: parseTimePtr(vals[9]), + MonthlyWindowStart: parseTimePtr(vals[10]), + }, true, nil +} + +func (c *billingCache) SetUserPlatformQuotaCache(ctx context.Context, userID int64, platform string, entry *service.UserPlatformQuotaCacheEntry, ttl time.Duration) error { + if entry == nil { + return nil + } + key := userPlatformQuotaCacheKey(userID, platform) + pipe := c.rdb.TxPipeline() + + // 浮点可空字段:nil → 空字符串(读取时 parseFloatPtr 返回 nil,表示无限额) + fmtFloatPtr := func(p *float64) string { + if p == nil { + return "" + } + return strconv.FormatFloat(*p, 'f', -1, 64) + } + // time.Time 可空字段:nil → 空字符串;有值 → unix 秒 + fmtTimePtr := func(p *time.Time) string { + if p == nil { + return "" + } + return strconv.FormatInt(p.Unix(), 10) + } + + pipe.HSet(ctx, key, + "daily_usage", entry.DailyUsageUSD, + "weekly_usage", entry.WeeklyUsageUSD, + "monthly_usage", entry.MonthlyUsageUSD, + "version", entry.Version, + "schema_version", entry.SchemaVersion, + "daily_limit", fmtFloatPtr(entry.DailyLimitUSD), + "weekly_limit", fmtFloatPtr(entry.WeeklyLimitUSD), + "monthly_limit", fmtFloatPtr(entry.MonthlyLimitUSD), + "daily_window_start", fmtTimePtr(entry.DailyWindowStart), + "weekly_window_start", fmtTimePtr(entry.WeeklyWindowStart), + "monthly_window_start", fmtTimePtr(entry.MonthlyWindowStart), + ) + pipe.Expire(ctx, key, ttl) + _, err := pipe.Exec(ctx) + return err +} + +func (c *billingCache) DeleteUserPlatformQuotaCache(ctx context.Context, userID int64, platform string) error { + return c.rdb.Del(ctx, userPlatformQuotaCacheKey(userID, platform)).Err() +} + +// updateUserPlatformQuotaUsageScript 缓存累加:EXISTS + schema_version 双重守卫。 +// 旧版 entry(schema_version != ARGV[3],包括缺字段的 0 值)不参与累加,由上层走 DB fallback 后 +// SetCache 重建为新版 entry —— 若此处仍累加,上层覆盖时会丢失这部分增量,导致 Redis usage 比真实偏小。 +// key 不存在同样跳过(由下次 SetCache 重建)。 +// KEYS[1] = hash key +// ARGV[1] = cost (string float) +// ARGV[2] = ttl seconds +// ARGV[3] = expected schema_version (Go 侧 UserPlatformQuotaCacheSchemaV1) +const updateUserPlatformQuotaUsageScript = ` +if redis.call("EXISTS", KEYS[1]) == 0 then + return 0 +end +local ver = redis.call("HGET", KEYS[1], "schema_version") +if ver == false or tonumber(ver) ~= tonumber(ARGV[3]) then + return 0 +end +redis.call("HINCRBYFLOAT", KEYS[1], "daily_usage", ARGV[1]) +redis.call("HINCRBYFLOAT", KEYS[1], "weekly_usage", ARGV[1]) +redis.call("HINCRBYFLOAT", KEYS[1], "monthly_usage", ARGV[1]) +redis.call("HINCRBY", KEYS[1], "version", 1) +redis.call("EXPIRE", KEYS[1], ARGV[2]) +return 1 +` + +func (c *billingCache) IncrUserPlatformQuotaUsageCache(ctx context.Context, userID int64, platform string, cost float64, ttl time.Duration) error { + key := userPlatformQuotaCacheKey(userID, platform) + _, err := c.rdb.Eval(ctx, updateUserPlatformQuotaUsageScript, []string{key}, + strconv.FormatFloat(cost, 'f', -1, 64), + int(ttl.Seconds()), + service.UserPlatformQuotaCacheSchemaV1, + ).Result() + if err != nil && !errors.Is(err, redis.Nil) { + return err + } + return nil +} diff --git a/backend/internal/repository/billing_cache_user_platform_quota_test.go b/backend/internal/repository/billing_cache_user_platform_quota_test.go new file mode 100644 index 00000000..8d49fd31 --- /dev/null +++ b/backend/internal/repository/billing_cache_user_platform_quota_test.go @@ -0,0 +1,134 @@ +//go:build unit + +package repository + +import ( + "context" + "testing" + "time" + + "github.com/alicebob/miniredis/v2" + "github.com/redis/go-redis/v9" + + "github.com/Wei-Shaw/sub2api/internal/service" +) + +func newMiniRedisCache(t *testing.T) (*billingCache, *miniredis.Miniredis) { + t.Helper() + mr := miniredis.RunT(t) + rdb := redis.NewClient(&redis.Options{Addr: mr.Addr()}) + return &billingCache{rdb: rdb}, mr +} + +func TestUserPlatformQuotaCache_GetMissReturnsNotFound(t *testing.T) { + c, _ := newMiniRedisCache(t) + entry, ok, err := c.GetUserPlatformQuotaCache(context.Background(), 1, "anthropic") + if err != nil { + t.Fatal(err) + } + if ok || entry != nil { + t.Errorf("expected miss, got ok=%v entry=%v", ok, entry) + } +} + +func TestUserPlatformQuotaCache_SetThenGet(t *testing.T) { + c, _ := newMiniRedisCache(t) + ctx := context.Background() + dailyLimit := 20.0 + ts := time.Date(2024, 5, 1, 0, 0, 0, 0, time.UTC) + in := &service.UserPlatformQuotaCacheEntry{ + DailyUsageUSD: 1.5, + WeeklyUsageUSD: 3.0, + MonthlyUsageUSD: 10.0, + Version: 7, + SchemaVersion: service.UserPlatformQuotaCacheSchemaV1, + DailyLimitUSD: &dailyLimit, + DailyWindowStart: &ts, + } + if err := c.SetUserPlatformQuotaCache(ctx, 1, "openai", in, time.Minute); err != nil { + t.Fatal(err) + } + got, ok, err := c.GetUserPlatformQuotaCache(ctx, 1, "openai") + if err != nil || !ok { + t.Fatalf("get: ok=%v err=%v", ok, err) + } + if got.DailyUsageUSD != 1.5 || got.WeeklyUsageUSD != 3.0 || got.MonthlyUsageUSD != 10.0 || got.Version != 7 { + t.Errorf("got = %+v, want %+v", got, in) + } + if got.SchemaVersion != service.UserPlatformQuotaCacheSchemaV1 { + t.Errorf("SchemaVersion = %d, want %d", got.SchemaVersion, service.UserPlatformQuotaCacheSchemaV1) + } + if got.DailyLimitUSD == nil || *got.DailyLimitUSD != dailyLimit { + t.Errorf("DailyLimitUSD = %v, want %v", got.DailyLimitUSD, dailyLimit) + } + if got.DailyWindowStart == nil || !got.DailyWindowStart.Equal(ts) { + t.Errorf("DailyWindowStart = %v, want %v", got.DailyWindowStart, ts) + } +} + +func TestUserPlatformQuotaCache_NilLimitSetThenGet(t *testing.T) { + c, _ := newMiniRedisCache(t) + ctx := context.Background() + in := &service.UserPlatformQuotaCacheEntry{ + DailyUsageUSD: 1.0, + SchemaVersion: service.UserPlatformQuotaCacheSchemaV1, + // DailyLimitUSD nil → 无限额 + } + if err := c.SetUserPlatformQuotaCache(ctx, 1, "openai", in, time.Minute); err != nil { + t.Fatal(err) + } + got, ok, err := c.GetUserPlatformQuotaCache(ctx, 1, "openai") + if err != nil || !ok { + t.Fatalf("get: ok=%v err=%v", ok, err) + } + if got.DailyLimitUSD != nil { + t.Errorf("DailyLimitUSD should be nil for unlimited, got %v", got.DailyLimitUSD) + } +} + +func TestUserPlatformQuotaCache_IncrMissIsNoop(t *testing.T) { + c, _ := newMiniRedisCache(t) + if err := c.IncrUserPlatformQuotaUsageCache(context.Background(), 1, "openai", 0.5, time.Minute); err != nil { + t.Fatal(err) + } + _, ok, _ := c.GetUserPlatformQuotaCache(context.Background(), 1, "openai") + if ok { + t.Error("expected key absent after no-op incr") + } +} + +func TestUserPlatformQuotaCache_IncrHitAccumulates(t *testing.T) { + c, _ := newMiniRedisCache(t) + ctx := context.Background() + // SchemaVersion 必须显式设为 V1,否则 Lua 脚本会因 schema 不匹配而 return 0,跳过累加。 + _ = c.SetUserPlatformQuotaCache(ctx, 1, "openai", &service.UserPlatformQuotaCacheEntry{ + Version: 1, + SchemaVersion: service.UserPlatformQuotaCacheSchemaV1, + }, time.Minute) + if err := c.IncrUserPlatformQuotaUsageCache(ctx, 1, "openai", 0.5, time.Minute); err != nil { + t.Fatal(err) + } + if err := c.IncrUserPlatformQuotaUsageCache(ctx, 1, "openai", 0.25, time.Minute); err != nil { + t.Fatal(err) + } + got, _, _ := c.GetUserPlatformQuotaCache(ctx, 1, "openai") + if got.DailyUsageUSD != 0.75 || got.WeeklyUsageUSD != 0.75 || got.MonthlyUsageUSD != 0.75 { + t.Errorf("got %+v, want daily/weekly/monthly=0.75", got) + } + if got.Version != 3 { + t.Errorf("version = %d, want 3 (initial 1 + 2 incr)", got.Version) + } +} + +func TestUserPlatformQuotaCache_Delete(t *testing.T) { + c, _ := newMiniRedisCache(t) + ctx := context.Background() + _ = c.SetUserPlatformQuotaCache(ctx, 1, "openai", &service.UserPlatformQuotaCacheEntry{Version: 1}, time.Minute) + if err := c.DeleteUserPlatformQuotaCache(ctx, 1, "openai"); err != nil { + t.Fatal(err) + } + _, ok, _ := c.GetUserPlatformQuotaCache(ctx, 1, "openai") + if ok { + t.Error("expected miss after delete") + } +} diff --git a/backend/internal/repository/user_platform_quota_adapter_test.go b/backend/internal/repository/user_platform_quota_adapter_test.go new file mode 100644 index 00000000..a55d2e9c --- /dev/null +++ b/backend/internal/repository/user_platform_quota_adapter_test.go @@ -0,0 +1,91 @@ +//go:build unit + +package repository + +import ( + "context" + "errors" + "testing" + "time" +) + +type fakeRepoForAdapter struct { + upsertCalledWith []UserPlatformQuotaRecord + upsertCalledUserID int64 + upsertErr error + resetCalledWith [4]any // userID, platform, window, newStart + resetErr error +} + +func (f *fakeRepoForAdapter) BulkInsertInitial(_ context.Context, _ []UserPlatformQuotaRecord) error { + return nil +} +func (f *fakeRepoForAdapter) GetByUserPlatform(_ context.Context, _ int64, _ string) (*UserPlatformQuotaRecord, error) { + return nil, nil +} +func (f *fakeRepoForAdapter) ListByUser(_ context.Context, _ int64) ([]UserPlatformQuotaRecord, error) { + return nil, nil +} +func (f *fakeRepoForAdapter) IncrementUsageWithReset(_ context.Context, _ int64, _ string, _ float64, _ time.Time) error { + return nil +} +func (f *fakeRepoForAdapter) ResetExpiredWindow(_ context.Context, userID int64, platform string, window string, newStart time.Time) error { + f.resetCalledWith = [4]any{userID, platform, window, newStart} + return f.resetErr +} +func (f *fakeRepoForAdapter) UpsertForUser(_ context.Context, userID int64, records []UserPlatformQuotaRecord) error { + f.upsertCalledUserID = userID + f.upsertCalledWith = records + return f.upsertErr +} + +func TestGenericAdapter_UpsertForUser_ForwardsRecords(t *testing.T) { + fake := &fakeRepoForAdapter{} + adapter := NewUserPlatformQuotaServiceAdapter(fake) + + err := adapter.UpsertForUser(context.Background(), 42, nil) + if err != nil { + t.Fatalf("unexpected err: %v", err) + } + if fake.upsertCalledUserID != 42 { + t.Errorf("forwarded userID = %d, want 42", fake.upsertCalledUserID) + } +} + +func TestGenericAdapter_UpsertForUser_PropagatesError(t *testing.T) { + wantErr := errors.New("boom") + fake := &fakeRepoForAdapter{upsertErr: wantErr} + adapter := NewUserPlatformQuotaServiceAdapter(fake) + + err := adapter.UpsertForUser(context.Background(), 1, nil) + if !errors.Is(err, wantErr) { + t.Errorf("expected %v, got %v", wantErr, err) + } +} + +func TestGenericAdapter_ResetExpiredWindow_ForwardsAllParams(t *testing.T) { + fake := &fakeRepoForAdapter{} + adapter := NewUserPlatformQuotaServiceAdapter(fake) + + now := time.Date(2026, 5, 23, 10, 0, 0, 0, time.UTC) + if err := adapter.ResetExpiredWindow(context.Background(), 7, "openai", "weekly", now); err != nil { + t.Fatalf("unexpected err: %v", err) + } + if fake.resetCalledWith[0].(int64) != 7 || + fake.resetCalledWith[1].(string) != "openai" || + fake.resetCalledWith[2].(string) != "weekly" || + !fake.resetCalledWith[3].(time.Time).Equal(now) { + t.Errorf("forwarded params mismatch: %+v", fake.resetCalledWith) + } +} + +func TestGenericAdapter_ResetExpiredWindow_PropagatesError(t *testing.T) { + wantErr := errors.New("not found") + fake := &fakeRepoForAdapter{resetErr: wantErr} + adapter := NewUserPlatformQuotaServiceAdapter(fake) + + err := adapter.ResetExpiredWindow(context.Background(), 1, "a", "daily", time.Now()) + if !errors.Is(err, wantErr) { + t.Errorf("expected %v, got %v", wantErr, err) + } +} diff --git a/backend/internal/repository/user_platform_quota_repo.go b/backend/internal/repository/user_platform_quota_repo.go new file mode 100644 index 00000000..1e2e7f51 --- /dev/null +++ b/backend/internal/repository/user_platform_quota_repo.go @@ -0,0 +1,416 @@ +package repository + +import ( + "context" + "fmt" + "strings" + "time" + + dbent "github.com/Wei-Shaw/sub2api/ent" + "github.com/Wei-Shaw/sub2api/ent/userplatformquota" + "github.com/Wei-Shaw/sub2api/internal/pkg/timezone" +) + +// UserPlatformQuotaRecord 是 repository 层的传输结构体, +// 与 ent.UserPlatformQuota 实体解耦,供业务层使用。 +type UserPlatformQuotaRecord struct { + UserID int64 + Platform string + DailyLimitUSD *float64 + WeeklyLimitUSD *float64 + MonthlyLimitUSD *float64 + DailyUsageUSD float64 + WeeklyUsageUSD float64 + MonthlyUsageUSD float64 + DailyWindowStart *time.Time + WeeklyWindowStart *time.Time + MonthlyWindowStart *time.Time +} + +// ErrUserPlatformQuotaNotFound 用于 ResetExpiredWindow 等需要"必须命中已有记录"的方法。 +var ErrUserPlatformQuotaNotFound = fmt.Errorf("user platform quota record not found") + +// UserPlatformQuotaRepository 定义用户平台配额的数据访问接口。 +type UserPlatformQuotaRepository interface { + // BulkInsertInitial 幂等批量插入初始配额记录(ON CONFLICT DO NOTHING)。 + BulkInsertInitial(ctx context.Context, records []UserPlatformQuotaRecord) error + // GetByUserPlatform 查询单条配额记录,未找到时返回 (nil, nil)。 + GetByUserPlatform(ctx context.Context, userID int64, platform string) (*UserPlatformQuotaRecord, error) + // ListByUser 查询用户的所有平台配额记录(排除软删除)。 + ListByUser(ctx context.Context, userID int64) ([]UserPlatformQuotaRecord, error) + // IncrementUsageWithReset 原子地累加用量,若窗口已过期则先重置再累加。 + IncrementUsageWithReset(ctx context.Context, userID int64, platform string, cost float64, now time.Time) error + // ResetExpiredWindow 重置指定窗口(daily/weekly/monthly)的用量与起始时间。 + ResetExpiredWindow(ctx context.Context, userID int64, platform string, window string, newStart time.Time) error + // UpsertForUser 全量替换该用户所有平台限额配置(详见 service.UserPlatformQuotaRepository.UpsertForUser)。 + UpsertForUser(ctx context.Context, userID int64, records []UserPlatformQuotaRecord) error +} + +type userPlatformQuotaRepository struct { + client *dbent.Client +} + +// NewUserPlatformQuotaRepository 创建 UserPlatformQuotaRepository 实现。 +func NewUserPlatformQuotaRepository(client *dbent.Client) UserPlatformQuotaRepository { + return &userPlatformQuotaRepository{client: client} +} + +// BulkInsertInitial 用原生 SQL ON CONFLICT 实现幂等批量插入(带条件 limit 覆盖)。 +// 仅插入 limit_usd 与元数据,usage_usd 用 DB 默认 0,window_start 留 NULL。 +// FK 约束要求 user_id 在 users 表中存在,调用方负责保证。 +// +// 冲突策略:CASE WHEN existing.*_limit_usd IS NULL THEN EXCLUDED.*_limit_usd ELSE existing ... +// - 若 IncrementUsageWithReset 因时序问题已先建行(limit 全 NULL), +// 此处会把注册时的默认 limit 写入,避免该用户在该平台永久无限额。 +// - 若管理员已通过 UpsertForUser 设置了非 NULL 个性化 limit,**保留不动** +// —— 旧实现无条件 EXCLUDED 覆盖会丢失个性化配置。 +// - 不会改 usage_usd / window_start,保留累计的用量。 +// - 仅命中 deleted_at IS NULL 的活跃记录(partial unique index 作用域)。 +func (r *userPlatformQuotaRepository) BulkInsertInitial(ctx context.Context, records []UserPlatformQuotaRecord) error { + if len(records) == 0 { + return nil + } + + client := clientFromContext(ctx, r.client) + + var sb strings.Builder + _, _ = sb.WriteString("INSERT INTO user_platform_quotas (user_id, platform, daily_limit_usd, weekly_limit_usd, monthly_limit_usd, daily_usage_usd, weekly_usage_usd, monthly_usage_usd, created_at, updated_at) VALUES ") + args := make([]any, 0, len(records)*6) + // 统一时间戳:避免循环内多次 time.Now() 让同一批记录的 created_at/updated_at + // 出现亚毫秒级偏差(与 UpsertForUser 的 now := time.Now() 风格一致)。 + now := time.Now() + for i, rec := range records { + base := i * 6 + if i > 0 { + _, _ = sb.WriteString(",") + } + fmt.Fprintf(&sb, "($%d,$%d,$%d,$%d,$%d,0,0,0,$%d,$%d)", + base+1, base+2, base+3, base+4, base+5, base+6, base+6) + args = append(args, + rec.UserID, rec.Platform, + rec.DailyLimitUSD, rec.WeeklyLimitUSD, rec.MonthlyLimitUSD, + now, + ) + } + // 精确命中 partial unique index(deleted_at IS NULL),避免对软删记录的歧义冲突。 + // 条件覆盖:仅在现有 limit 为 NULL 时才写入 EXCLUDED,否则保留现有非 NULL 值。 + // - 修复 IncrementUsageWithReset 已用 NULL limit 建行的场景(NULL → 注册默认) + // - 保护管理员通过 UpsertForUser 设置的个性化 limit 不被静默覆盖 + _, _ = sb.WriteString(` ON CONFLICT (user_id, platform) WHERE deleted_at IS NULL + DO UPDATE SET + daily_limit_usd = COALESCE(user_platform_quotas.daily_limit_usd, EXCLUDED.daily_limit_usd), + weekly_limit_usd = COALESCE(user_platform_quotas.weekly_limit_usd, EXCLUDED.weekly_limit_usd), + monthly_limit_usd = COALESCE(user_platform_quotas.monthly_limit_usd, EXCLUDED.monthly_limit_usd), + updated_at = EXCLUDED.updated_at`) + + _, err := client.ExecContext(ctx, sb.String(), args...) + return err +} + +// GetByUserPlatform 通过 ent 查询单条配额(排除软删除)。未找到返回 (nil, nil)。 +func (r *userPlatformQuotaRepository) GetByUserPlatform(ctx context.Context, userID int64, platform string) (*UserPlatformQuotaRecord, error) { + client := clientFromContext(ctx, r.client) + entity, err := client.UserPlatformQuota.Query(). + Where( + userplatformquota.UserIDEQ(userID), + userplatformquota.PlatformEQ(platform), + userplatformquota.DeletedAtIsNil(), + ). + Only(ctx) + if dbent.IsNotFound(err) { + return nil, nil + } + if err != nil { + return nil, err + } + return entQuotaToRecord(entity), nil +} + +// ListByUser 查询用户的所有平台配额记录(排除软删除)。 +func (r *userPlatformQuotaRepository) ListByUser(ctx context.Context, userID int64) ([]UserPlatformQuotaRecord, error) { + client := clientFromContext(ctx, r.client) + rows, err := client.UserPlatformQuota.Query(). + Where( + userplatformquota.UserIDEQ(userID), + userplatformquota.DeletedAtIsNil(), + ). + All(ctx) + if err != nil { + return nil, err + } + out := make([]UserPlatformQuotaRecord, 0, len(rows)) + for _, e := range rows { + out = append(out, *entQuotaToRecord(e)) + } + return out, nil +} + +// IncrementUsageWithReset 原子累加 cost 到 (user, platform) 三个窗口的 *_usage_usd。 +// 行为: +// - 若记录存在:在事务内 SELECT FOR UPDATE,按 (prev_window_start vs current_window_start) +// 判断是否需要重置(不同 = 重置为 cost;相同 = 累加 cost) +// - 若记录不存在(fail-open create 分支):插入新记录,**limit 字段保留 nil(无限制)** +// —— 这是预期行为:billing 链路不能因 quota 表缺失而阻断请求,未注册路径 +// 的用户 quota 默认放行,由调度层指标观测 + 后台对账补建 limit +// +// 上层正常路径(注册时 BulkInsertInitial)保证 limit 在记录创建时就被写入。 +func (r *userPlatformQuotaRepository) IncrementUsageWithReset(ctx context.Context, userID int64, platform string, cost float64, now time.Time) error { + return r.withTx(ctx, func(txCtx context.Context, txClient *dbent.Client) error { + existing, err := txClient.UserPlatformQuota.Query(). + Where( + userplatformquota.UserIDEQ(userID), + userplatformquota.PlatformEQ(platform), + userplatformquota.DeletedAtIsNil(), + ). + ForUpdate(). + Only(txCtx) + if dbent.IsNotFound(err) { + // fail-open 建行:limit_* 保留 NULL(无限额)。 + // 用 ON CONFLICT DO UPDATE 累加,而非裸 INSERT:并发下另一请求可能在本事务 + // SELECT FOR UPDATE 之后、INSERT 之前刚建行,裸 INSERT 会撞 partial unique index + // 致事务回滚、本次 cost 丢失;DO UPDATE 把 cost 累加到既有 usage 上。 + // 写法与本文件 insertLimitsRow / BulkInsertInitial 的 ON CONFLICT 一致。 + const insertSQL = `INSERT INTO user_platform_quotas + (user_id, platform, daily_usage_usd, weekly_usage_usd, monthly_usage_usd, + daily_window_start, weekly_window_start, monthly_window_start, created_at, updated_at) + VALUES ($1, $2, $3, $3, $3, $4, $5, $6, $7, $7) + ON CONFLICT (user_id, platform) WHERE deleted_at IS NULL DO UPDATE SET + daily_usage_usd = user_platform_quotas.daily_usage_usd + EXCLUDED.daily_usage_usd, + weekly_usage_usd = user_platform_quotas.weekly_usage_usd + EXCLUDED.weekly_usage_usd, + monthly_usage_usd = user_platform_quotas.monthly_usage_usd + EXCLUDED.monthly_usage_usd, + updated_at = EXCLUDED.updated_at` + // $6 = now:30 天滚动月度窗口以当前时刻为起始 + _, e := txClient.ExecContext(txCtx, insertSQL, + userID, platform, cost, + timezone.StartOfDay(now), timezone.StartOfWeek(now), now, now) + return e + } + if err != nil { + return err + } + + newDaily := maybeReset(existing.DailyUsageUsd, existing.DailyWindowStart, timezone.StartOfDay(now), cost) + newWeekly := maybeReset(existing.WeeklyUsageUsd, existing.WeeklyWindowStart, timezone.StartOfWeek(now), cost) + // 30 天滚动月度窗口:过期时重置为 cost 并以 now 为新起始,否则累加保留原起始 + newMonthly, newMonthlyStart := monthlyMaybeReset(existing.MonthlyUsageUsd, existing.MonthlyWindowStart, cost, now) + + _, e := existing.Update(). + SetDailyUsageUsd(newDaily). + SetWeeklyUsageUsd(newWeekly). + SetMonthlyUsageUsd(newMonthly). + SetDailyWindowStart(timezone.StartOfDay(now)). + SetWeeklyWindowStart(timezone.StartOfWeek(now)). + SetMonthlyWindowStart(newMonthlyStart). // 30 天滚动:仅过期时更新起始 + Save(txCtx) + return e + }) +} + +// ResetExpiredWindow 无条件重置指定窗口(daily/weekly/monthly)的用量与起始时间。 +// +// ⚠️ 命名警告(NOT a "check-then-reset" helper): +// +// 名字里的 "Expired" 是历史遗留,**实现并不校验窗口是否真的过期**。 +// 任何调用都会无条件把对应窗口的 *_usage_usd 清零并重写 *_window_start。 +// 目前唯一合法 caller 是 admin POST /reset 接口(管理员强制归零)。 +// +// 如果你想要"仅在窗口过期才重置"的语义,请直接使用 IncrementUsageWithReset +// 的内部判断(maybeReset / monthlyMaybeReset),或新增独立函数; +// 不要复用这里的函数,否则会出现"明明窗口未过期,用量却被清零"的隐蔽 bug。 +// +// 未命中活跃记录时返回 ErrUserPlatformQuotaNotFound。 +func (r *userPlatformQuotaRepository) ResetExpiredWindow(ctx context.Context, userID int64, platform string, window string, newStart time.Time) error { + client := clientFromContext(ctx, r.client) + upd := client.UserPlatformQuota.Update(). + Where( + userplatformquota.UserIDEQ(userID), + userplatformquota.PlatformEQ(platform), + userplatformquota.DeletedAtIsNil(), + ) + switch window { + case "daily": + upd = upd.SetDailyUsageUsd(0).SetDailyWindowStart(newStart) + case "weekly": + upd = upd.SetWeeklyUsageUsd(0).SetWeeklyWindowStart(newStart) + case "monthly": + upd = upd.SetMonthlyUsageUsd(0).SetMonthlyWindowStart(newStart) + default: + return fmt.Errorf("unknown window %q", window) + } + n, err := upd.Save(ctx) + if err != nil { + return err + } + if n == 0 { + return ErrUserPlatformQuotaNotFound + } + return nil +} + +// withTx 在事务中执行 fn,若 ctx 中已有事务则复用。 +func (r *userPlatformQuotaRepository) withTx(ctx context.Context, fn func(txCtx context.Context, txClient *dbent.Client) error) error { + if tx := dbent.TxFromContext(ctx); tx != nil { + return fn(ctx, tx.Client()) + } + + tx, err := r.client.Tx(ctx) + if err != nil { + return fmt.Errorf("begin user_platform_quota transaction: %w", err) + } + defer func() { _ = tx.Rollback() }() + + txCtx := dbent.NewTxContext(ctx, tx) + if err := fn(txCtx, tx.Client()); err != nil { + return err + } + + if err := tx.Commit(); err != nil { + return fmt.Errorf("commit user_platform_quota transaction: %w", err) + } + return nil +} + +// entQuotaToRecord 将 ent entity 映射为 repository record。 +// 注意 ent 生成字段名为 DailyLimitUsd(非 DailyLimitUSD)。 +func entQuotaToRecord(e *dbent.UserPlatformQuota) *UserPlatformQuotaRecord { + return &UserPlatformQuotaRecord{ + UserID: e.UserID, + Platform: e.Platform, + DailyLimitUSD: e.DailyLimitUsd, + WeeklyLimitUSD: e.WeeklyLimitUsd, + MonthlyLimitUSD: e.MonthlyLimitUsd, + DailyUsageUSD: e.DailyUsageUsd, + WeeklyUsageUSD: e.WeeklyUsageUsd, + MonthlyUsageUSD: e.MonthlyUsageUsd, + DailyWindowStart: e.DailyWindowStart, + WeeklyWindowStart: e.WeeklyWindowStart, + MonthlyWindowStart: e.MonthlyWindowStart, + } +} + +// maybeReset 判断是否需要重置窗口用量: +// - 若 prevStart 为 nil 或与 currStart 不同,表示窗口已过期,返回 cost(重置) +// - 否则返回 prevUsage + cost(累加) +func maybeReset(prevUsage float64, prevStart *time.Time, currStart time.Time, cost float64) float64 { + if prevStart == nil || !prevStart.Equal(currStart) { + return cost + } + return prevUsage + cost +} + +// monthlyMaybeReset 判断 30 天滚动月度窗口是否需要重置。 +// 过期条件:prevStart 为 nil 或 now - prevStart >= 30×24h(与订阅模式 NeedsMonthlyReset 语义一致)。 +// 过期时重置为 cost,否则累加。返回 (newUsage, newWindowStart)。 +func monthlyMaybeReset(prevUsage float64, prevStart *time.Time, cost float64, now time.Time) (float64, time.Time) { + if prevStart == nil || now.Sub(*prevStart) >= 30*24*time.Hour { + return cost, now + } + return prevUsage + cost, *prevStart +} + +// UpsertForUser 全量替换该用户的所有平台限额(事务内): +// 1. 软删除未在 records 中出现的所有 active 行 +// 2. 对每条 record 尝试 UPDATE(含 deleted_at = NULL 兼容重激活); +// UPDATE 行数为 0 时 INSERT 新行 +// +// 仅改 *_limit_usd + deleted_at + updated_at,保留 *_usage_usd / *_window_start。 +func (r *userPlatformQuotaRepository) UpsertForUser(ctx context.Context, userID int64, records []UserPlatformQuotaRecord) error { + return r.withTx(ctx, func(txCtx context.Context, txClient *dbent.Client) error { + platforms := make([]string, 0, len(records)) + for _, rec := range records { + platforms = append(platforms, rec.Platform) + } + now := time.Now() + if err := softDeleteMissingPlatforms(txCtx, txClient, userID, platforms, now); err != nil { + return err + } + for _, rec := range records { + affected, err := updateLimitsRow(txCtx, txClient, userID, rec, now) + if err != nil { + return err + } + if affected == 0 { + if err := insertLimitsRow(txCtx, txClient, userID, rec, now); err != nil { + return err + } + } + } + return nil + }) +} + +// softDeleteMissingPlatforms 软删除该用户所有不在 keepPlatforms 中的 active 行。 +// keepPlatforms 为空时 → 软删用户所有 active 行。 +// now 由调用方传入,与 updateLimitsRow / insertLimitsRow 共享同一个 Go time.Now(), +// 保证事务内所有时间戳一致(避免 Postgres NOW() 与 Go time.Now() 的微小偏差)。 +func softDeleteMissingPlatforms(ctx context.Context, client *dbent.Client, userID int64, keepPlatforms []string, now time.Time) error { + var ( + query string + args []any + ) + if len(keepPlatforms) == 0 { + query = `UPDATE user_platform_quotas SET deleted_at = $2, updated_at = $2 + WHERE user_id = $1 AND deleted_at IS NULL` + args = []any{userID, now} + } else { + placeholders := make([]string, len(keepPlatforms)) + args = make([]any, 0, len(keepPlatforms)+2) + args = append(args, userID, now) + for i, p := range keepPlatforms { + placeholders[i] = fmt.Sprintf("$%d", i+3) + args = append(args, p) + } + query = fmt.Sprintf(`UPDATE user_platform_quotas SET deleted_at = $2, updated_at = $2 + WHERE user_id = $1 AND deleted_at IS NULL AND platform NOT IN (%s)`, + strings.Join(placeholders, ",")) + } + _, err := client.ExecContext(ctx, query, args...) + return err +} + +// updateLimitsRow 尝试 UPDATE active 行(deleted_at IS NULL),返回受影响行数。 +// 仅更新 active 行:若存在多条历史软删记录,加 deleted_at IS NULL 守卫可避免 +// 批量重激活导致的 partial unique index(userplatformquota_user_id_platform_uq)冲突。 +// affected=0 时由调用方 UpsertForUser 走 insertLimitsRow 路径创建新行。 +func updateLimitsRow(ctx context.Context, client *dbent.Client, userID int64, rec UserPlatformQuotaRecord, now time.Time) (int64, error) { + const query = `UPDATE user_platform_quotas + SET daily_limit_usd = $1, weekly_limit_usd = $2, monthly_limit_usd = $3, + deleted_at = NULL, updated_at = $4 + WHERE user_id = $5 AND platform = $6 AND deleted_at IS NULL` + res, err := client.ExecContext(ctx, query, + rec.DailyLimitUSD, rec.WeeklyLimitUSD, rec.MonthlyLimitUSD, now, + userID, rec.Platform) + if err != nil { + return 0, err + } + return res.RowsAffected() +} + +// insertLimitsRow 插入新限额行(usage 默认 0,window_start 默认 NULL)。 +// 带 ON CONFLICT ... DO NOTHING 守卫:防止两个并发请求同时为同一 user/platform 新建行时 +// 触发 unique constraint 违反(userplatformquota_user_id_platform_uq 部分唯一索引)。 +// affected=0 时说明另一个并发请求刚完成 INSERT,fallback 到 updateLimitsRow 覆写 limits 值。 +func insertLimitsRow(ctx context.Context, client *dbent.Client, userID int64, rec UserPlatformQuotaRecord, now time.Time) error { + const query = `INSERT INTO user_platform_quotas + (user_id, platform, daily_limit_usd, weekly_limit_usd, monthly_limit_usd, + daily_usage_usd, weekly_usage_usd, monthly_usage_usd, created_at, updated_at) + VALUES ($1, $2, $3, $4, $5, 0, 0, 0, $6, $6) + ON CONFLICT (user_id, platform) WHERE deleted_at IS NULL DO NOTHING` + res, err := client.ExecContext(ctx, query, + userID, rec.Platform, + rec.DailyLimitUSD, rec.WeeklyLimitUSD, rec.MonthlyLimitUSD, + now) + if err != nil { + return err + } + affected, err := res.RowsAffected() + if err != nil { + return err + } + if affected == 0 { + // 并发情形:另一请求已插入该行,fallback 到 UPDATE 覆写 limits 值(last-writer-wins)。 + _, err = updateLimitsRow(ctx, client, userID, rec, now) + return err + } + return nil +} diff --git a/backend/internal/repository/user_platform_quota_repo_integration_test.go b/backend/internal/repository/user_platform_quota_repo_integration_test.go new file mode 100644 index 00000000..f02eeaa9 --- /dev/null +++ b/backend/internal/repository/user_platform_quota_repo_integration_test.go @@ -0,0 +1,269 @@ +//go:build integration + +package repository + +import ( + "context" + "errors" + "fmt" + "testing" + "time" + + dbent "github.com/Wei-Shaw/sub2api/ent" + "github.com/Wei-Shaw/sub2api/internal/service" + "github.com/stretchr/testify/require" +) + +// mustCreateUserForQuota 在指定 client 上创建测试用户(满足 FK 约束)。 +func mustCreateUserForQuota(t *testing.T, client *dbent.Client) int64 { + t.Helper() + u := mustCreateUser(t, client, &service.User{ + Email: fmt.Sprintf("quota-test-%d@example.com", time.Now().UnixNano()), + }) + return u.ID +} + +func TestUserPlatformQuotaRepository_BulkInsertInitial_Idempotent(t *testing.T) { + ctx := context.Background() + tx := testEntTx(t) + txCtx := dbent.NewTxContext(ctx, tx) + client := tx.Client() + + userID := mustCreateUserForQuota(t, client) + + repo := NewUserPlatformQuotaRepository(client) + + daily := 5.0 + records := []UserPlatformQuotaRecord{ + {UserID: userID, Platform: "anthropic", DailyLimitUSD: &daily}, + {UserID: userID, Platform: "openai"}, + } + + // 第一次插入 + require.NoError(t, repo.BulkInsertInitial(txCtx, records), "first insert") + // 第二次插入应为 no-op(ON CONFLICT DO NOTHING) + require.NoError(t, repo.BulkInsertInitial(txCtx, records), "second insert (idempotent)") + + list, err := repo.ListByUser(txCtx, userID) + require.NoError(t, err, "list") + require.Len(t, list, 2, "expected 2 records after idempotent insert") + + // 校验 daily_limit_usd 保留 + var anthropicRec *UserPlatformQuotaRecord + for i := range list { + if list[i].Platform == "anthropic" { + anthropicRec = &list[i] + } + } + require.NotNil(t, anthropicRec, "anthropic record should exist") + require.NotNil(t, anthropicRec.DailyLimitUSD, "daily limit should be set") + require.InDelta(t, 5.0, *anthropicRec.DailyLimitUSD, 1e-9, "daily limit should be 5.0") +} + +func TestUserPlatformQuotaRepository_BulkInsertInitial_Empty(t *testing.T) { + ctx := context.Background() + tx := testEntTx(t) + txCtx := dbent.NewTxContext(ctx, tx) + client := tx.Client() + + repo := NewUserPlatformQuotaRepository(client) + // 空切片不应报错 + require.NoError(t, repo.BulkInsertInitial(txCtx, nil)) + require.NoError(t, repo.BulkInsertInitial(txCtx, []UserPlatformQuotaRecord{})) +} + +func TestUserPlatformQuotaRepository_GetByUserPlatform(t *testing.T) { + ctx := context.Background() + tx := testEntTx(t) + txCtx := dbent.NewTxContext(ctx, tx) + client := tx.Client() + + userID := mustCreateUserForQuota(t, client) + + repo := NewUserPlatformQuotaRepository(client) + + // 未插入时应返回 nil + rec, err := repo.GetByUserPlatform(txCtx, userID, "anthropic") + require.NoError(t, err, "get before insert should not error") + require.Nil(t, rec, "get before insert should return nil") + + // 插入后查询 + daily := 10.0 + require.NoError(t, repo.BulkInsertInitial(txCtx, []UserPlatformQuotaRecord{ + {UserID: userID, Platform: "anthropic", DailyLimitUSD: &daily}, + })) + + rec, err = repo.GetByUserPlatform(txCtx, userID, "anthropic") + require.NoError(t, err) + require.NotNil(t, rec) + require.Equal(t, userID, rec.UserID) + require.Equal(t, "anthropic", rec.Platform) + require.NotNil(t, rec.DailyLimitUSD) + require.InDelta(t, 10.0, *rec.DailyLimitUSD, 1e-9) +} + +func TestUserPlatformQuotaRepository_IncrementUsageWithReset_SameWindow(t *testing.T) { + ctx := context.Background() + + // IncrementUsageWithReset 内部自己开事务,使用独立 ent client 确保跨事务可见 + client := testEntClient(t) + + userID := mustCreateUserForQuota(t, client) + + repo := NewUserPlatformQuotaRepository(client) + now := time.Date(2026, 5, 22, 10, 0, 0, 0, time.UTC) // 周五 + + // 首次调用:应新建记录 + require.NoError(t, repo.IncrementUsageWithReset(ctx, userID, "anthropic", 1.5, now)) + + rec, err := repo.GetByUserPlatform(ctx, userID, "anthropic") + require.NoError(t, err) + require.NotNil(t, rec) + require.InDelta(t, 1.5, rec.DailyUsageUSD, 1e-9, "initial daily usage") + require.InDelta(t, 1.5, rec.WeeklyUsageUSD, 1e-9, "initial weekly usage") + require.InDelta(t, 1.5, rec.MonthlyUsageUSD, 1e-9, "initial monthly usage") + + // 同一天再次调用:应累加 + require.NoError(t, repo.IncrementUsageWithReset(ctx, userID, "anthropic", 0.5, now)) + + rec, err = repo.GetByUserPlatform(ctx, userID, "anthropic") + require.NoError(t, err) + require.InDelta(t, 2.0, rec.DailyUsageUSD, 1e-9, "accumulated daily usage") + require.InDelta(t, 2.0, rec.WeeklyUsageUSD, 1e-9, "accumulated weekly usage") + require.InDelta(t, 2.0, rec.MonthlyUsageUSD, 1e-9, "accumulated monthly usage") +} + +func TestUserPlatformQuotaRepository_IncrementUsageWithReset_DailyReset(t *testing.T) { + ctx := context.Background() + client := testEntClient(t) + userID := mustCreateUserForQuota(t, client) + + repo := NewUserPlatformQuotaRepository(client) + + day1 := time.Date(2026, 5, 22, 10, 0, 0, 0, time.UTC) // 周五(同一周、同一月) + day2 := time.Date(2026, 5, 23, 10, 0, 0, 0, time.UTC) // 周六(同一周、同一月) + + require.NoError(t, repo.IncrementUsageWithReset(ctx, userID, "anthropic", 3.0, day1)) + require.NoError(t, repo.IncrementUsageWithReset(ctx, userID, "anthropic", 1.0, day2)) + + rec, err := repo.GetByUserPlatform(ctx, userID, "anthropic") + require.NoError(t, err) + require.InDelta(t, 1.0, rec.DailyUsageUSD, 1e-9, "daily should reset to 1.0") + require.InDelta(t, 4.0, rec.WeeklyUsageUSD, 1e-9, "weekly should accumulate to 4.0 (same week)") + require.InDelta(t, 4.0, rec.MonthlyUsageUSD, 1e-9, "monthly should accumulate to 4.0 (same month)") +} + +func TestUserPlatformQuotaRepository_IncrementUsageWithReset_WeeklyReset(t *testing.T) { + ctx := context.Background() + client := testEntClient(t) + userID := mustCreateUserForQuota(t, client) + + repo := NewUserPlatformQuotaRepository(client) + + // 5月22日(周五)和 5月25日(下周一),不同周 + fri := time.Date(2026, 5, 22, 10, 0, 0, 0, time.UTC) + nextMon := time.Date(2026, 5, 25, 10, 0, 0, 0, time.UTC) // 下一周周一 + + require.NoError(t, repo.IncrementUsageWithReset(ctx, userID, "openai", 5.0, fri)) + require.NoError(t, repo.IncrementUsageWithReset(ctx, userID, "openai", 2.0, nextMon)) + + rec, err := repo.GetByUserPlatform(ctx, userID, "openai") + require.NoError(t, err) + require.InDelta(t, 2.0, rec.DailyUsageUSD, 1e-9, "daily resets to new cost") + require.InDelta(t, 2.0, rec.WeeklyUsageUSD, 1e-9, "weekly resets (new week)") + require.InDelta(t, 7.0, rec.MonthlyUsageUSD, 1e-9, "monthly accumulates (same month)") +} + +func TestUserPlatformQuotaRepository_ResetExpiredWindow(t *testing.T) { + ctx := context.Background() + tx := testEntTx(t) + txCtx := dbent.NewTxContext(ctx, tx) + client := tx.Client() + + userID := mustCreateUserForQuota(t, client) + + repo := NewUserPlatformQuotaRepository(client) + + // 先通过 ent 直接建一条记录 + _, err := client.UserPlatformQuota.Create(). + SetUserID(userID). + SetPlatform("gemini"). + SetDailyUsageUsd(10.0). + SetWeeklyUsageUsd(20.0). + SetMonthlyUsageUsd(50.0). + SetDailyWindowStart(time.Date(2026, 5, 21, 0, 0, 0, 0, time.UTC)). + SetWeeklyWindowStart(time.Date(2026, 5, 18, 0, 0, 0, 0, time.UTC)). + SetMonthlyWindowStart(time.Date(2026, 5, 1, 0, 0, 0, 0, time.UTC)). + Save(txCtx) + require.NoError(t, err) + + newStart := time.Date(2026, 5, 22, 0, 0, 0, 0, time.UTC) + require.NoError(t, repo.ResetExpiredWindow(txCtx, userID, "gemini", "daily", newStart)) + + rec, err := repo.GetByUserPlatform(txCtx, userID, "gemini") + require.NoError(t, err) + require.InDelta(t, 0.0, rec.DailyUsageUSD, 1e-9, "daily usage reset to 0") + require.NotNil(t, rec.DailyWindowStart) + require.True(t, rec.DailyWindowStart.Equal(newStart), "daily window start updated") + // 其他窗口不变 + require.InDelta(t, 20.0, rec.WeeklyUsageUSD, 1e-9, "weekly usage unchanged") + require.InDelta(t, 50.0, rec.MonthlyUsageUSD, 1e-9, "monthly usage unchanged") +} + +func TestUserPlatformQuotaRepository_ResetExpiredWindow_UnknownWindow(t *testing.T) { + ctx := context.Background() + client := testEntClient(t) + + repo := NewUserPlatformQuotaRepository(client) + err := repo.ResetExpiredWindow(ctx, 999, "anthropic", "yearly", time.Now()) + require.Error(t, err, "unknown window should return error") +} + +func TestUserPlatformQuotaRepository_BulkInsertInitial_MultiRow(t *testing.T) { + ctx := context.Background() + tx := testEntTx(t) + txCtx := dbent.NewTxContext(ctx, tx) + client := tx.Client() + + userID := mustCreateUserForQuota(t, client) + repo := NewUserPlatformQuotaRepository(client) + + d1, d2, d3 := 5.0, 10.0, 15.0 + records := []UserPlatformQuotaRecord{ + {UserID: userID, Platform: "anthropic", DailyLimitUSD: &d1}, + {UserID: userID, Platform: "openai", DailyLimitUSD: &d2}, + {UserID: userID, Platform: "gemini", DailyLimitUSD: &d3}, + } + require.NoError(t, repo.BulkInsertInitial(txCtx, records), "multi-row insert failed") + + list, err := repo.ListByUser(txCtx, userID) + require.NoError(t, err) + require.Len(t, list, 3, "expected 3 rows, got %d", len(list)) + + // 验证 limit 值与传入一致(防占位符串位) + byPlatform := map[string]*UserPlatformQuotaRecord{} + for i := range list { + byPlatform[list[i].Platform] = &list[i] + } + require.NotNil(t, byPlatform["anthropic"], "anthropic record should exist") + require.NotNil(t, byPlatform["anthropic"].DailyLimitUSD, "anthropic daily limit should be set") + require.InDelta(t, 5.0, *byPlatform["anthropic"].DailyLimitUSD, 1e-9, "anthropic daily_limit = want 5.0") + + require.NotNil(t, byPlatform["openai"], "openai record should exist") + require.NotNil(t, byPlatform["openai"].DailyLimitUSD, "openai daily limit should be set") + require.InDelta(t, 10.0, *byPlatform["openai"].DailyLimitUSD, 1e-9, "openai daily_limit = want 10.0") + + require.NotNil(t, byPlatform["gemini"], "gemini record should exist") + require.NotNil(t, byPlatform["gemini"].DailyLimitUSD, "gemini daily limit should be set") + require.InDelta(t, 15.0, *byPlatform["gemini"].DailyLimitUSD, 1e-9, "gemini daily_limit = want 15.0") +} + +func TestUserPlatformQuotaRepository_ResetExpiredWindow_NotFoundReturnsSentinel(t *testing.T) { + ctx := context.Background() + client := testEntClient(t) + repo := NewUserPlatformQuotaRepository(client) + + err := repo.ResetExpiredWindow(ctx, 99999, "anthropic", "daily", time.Now()) + require.True(t, errors.Is(err, ErrUserPlatformQuotaNotFound), + "expected ErrUserPlatformQuotaNotFound, got %v", err) +} diff --git a/backend/internal/repository/user_platform_quota_repo_test.go b/backend/internal/repository/user_platform_quota_repo_test.go new file mode 100644 index 00000000..84377353 --- /dev/null +++ b/backend/internal/repository/user_platform_quota_repo_test.go @@ -0,0 +1,103 @@ +//go:build unit + +package repository + +import ( + "os" + "strings" + "testing" + "time" +) + +func TestMaybeReset(t *testing.T) { + start := time.Date(2026, 5, 22, 0, 0, 0, 0, time.UTC) + other := start.AddDate(0, 0, -1) + cases := []struct { + name string + prevUsage float64 + prevStart *time.Time + currStart time.Time + cost float64 + want float64 + }{ + {"nil prev start resets", 10, nil, start, 1.5, 1.5}, + {"different start resets", 10, &other, start, 1.5, 1.5}, + {"same start accumulates", 10, &start, start, 1.5, 11.5}, + } + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + if got := maybeReset(c.prevUsage, c.prevStart, c.currStart, c.cost); got != c.want { + t.Errorf("maybeReset = %v, want %v", got, c.want) + } + }) + } +} + +// TestMonthlyMaybeReset_NilStart 验证 prevStart=nil 时重置。 +func TestMonthlyMaybeReset_NilStart(t *testing.T) { + now := time.Date(2026, 5, 22, 12, 0, 0, 0, time.UTC) + usage, start := monthlyMaybeReset(10.0, nil, 1.5, now) + if usage != 1.5 { + t.Errorf("usage = %v, want 1.5", usage) + } + if !start.Equal(now) { + t.Errorf("start = %v, want %v", start, now) + } +} + +// TestMonthlyMaybeReset_Expired 验证窗口满 30 天时重置(30 天恰好到期)。 +func TestMonthlyMaybeReset_Expired(t *testing.T) { + windowStart := time.Date(2026, 4, 22, 12, 0, 0, 0, time.UTC) + // now = windowStart + 30d(刚好到期) + now := windowStart.Add(30 * 24 * time.Hour) + usage, start := monthlyMaybeReset(8.0, &windowStart, 2.0, now) + if usage != 2.0 { + t.Errorf("usage = %v, want 2.0 (reset)", usage) + } + if !start.Equal(now) { + t.Errorf("start = %v, want %v (new window)", start, now) + } +} + +// TestMonthlyMaybeReset_CrossMonthBoundary 验证跨自然月时也使用 30 天滚动(不提前重置)。 +// 旧行为:5 月 1 日跨月立即重置;新行为:窗口起始 4 月 20 日,5 月 1 日仅过了 11 天,应累加。 +func TestMonthlyMaybeReset_CrossMonthBoundary(t *testing.T) { + windowStart := time.Date(2026, 4, 20, 0, 0, 0, 0, time.UTC) + // 5 月 1 日:距起始 11 天,不足 30 天,应累加 + now := time.Date(2026, 5, 1, 0, 0, 0, 0, time.UTC) + usage, start := monthlyMaybeReset(5.0, &windowStart, 1.0, now) + if usage != 6.0 { + t.Errorf("usage = %v, want 6.0 (accumulate, not reset at month boundary)", usage) + } + if !start.Equal(windowStart) { + t.Errorf("start = %v, want %v (preserved)", start, windowStart) + } +} + +// TestMonthlyMaybeReset_Active 验证窗口内正常累加。 +func TestMonthlyMaybeReset_Active(t *testing.T) { + windowStart := time.Date(2026, 5, 1, 0, 0, 0, 0, time.UTC) + // 15 天内,窗口有效 + now := windowStart.Add(15 * 24 * time.Hour) + usage, start := monthlyMaybeReset(3.0, &windowStart, 0.5, now) + if usage != 3.5 { + t.Errorf("usage = %v, want 3.5", usage) + } + if !start.Equal(windowStart) { + t.Errorf("start = %v, want %v", start, windowStart) + } +} + +// TestUpdateLimitsRowQuery_HasDeletedAtGuard 通过读取源文件验证 updateLimitsRow +// 的 SQL WHERE 子句包含 deleted_at IS NULL 守卫(I-NEW-1)。 +// 此防回归测试可在无 DB 的 CI 环境中运行,防止意外删除该守卫。 +func TestUpdateLimitsRowQuery_HasDeletedAtGuard(t *testing.T) { + src, err := os.ReadFile("user_platform_quota_repo.go") + if err != nil { + t.Fatalf("failed to read source file: %v", err) + } + const guard = "AND deleted_at IS NULL" + if !strings.Contains(string(src), guard) { + t.Errorf("updateLimitsRow SQL must contain %q to prevent bulk reactivation of soft-deleted rows (I-NEW-1)", guard) + } +} diff --git a/backend/internal/repository/user_platform_quota_service_adapter.go b/backend/internal/repository/user_platform_quota_service_adapter.go new file mode 100644 index 00000000..7495cd26 --- /dev/null +++ b/backend/internal/repository/user_platform_quota_service_adapter.go @@ -0,0 +1,206 @@ +package repository + +import ( + "context" + "errors" + "fmt" + "time" + + "github.com/Wei-Shaw/sub2api/internal/service" +) + +// userPlatformQuotaServiceAdapter 将 repository 层的 userPlatformQuotaRepository +// 适配为 service.UserPlatformQuotaRepository 接口(返回 *service.UserPlatformQuotaRecord)。 +type userPlatformQuotaServiceAdapter struct { + inner *userPlatformQuotaRepository +} + +// NewUserPlatformQuotaServiceAdapter 将 UserPlatformQuotaRepository 实现包装为 +// 满足 service.UserPlatformQuotaRepository 接口的适配器。 +func NewUserPlatformQuotaServiceAdapter(repo UserPlatformQuotaRepository) service.UserPlatformQuotaRepository { + impl, ok := repo.(*userPlatformQuotaRepository) + if !ok { + // 非标准实现(如测试 fake),通过通用适配器包装 + return &genericUserPlatformQuotaAdapter{inner: repo} + } + return &userPlatformQuotaServiceAdapter{inner: impl} +} + +func (a *userPlatformQuotaServiceAdapter) GetByUserPlatform(ctx context.Context, userID int64, platform string) (*service.UserPlatformQuotaRecord, error) { + rec, err := a.inner.GetByUserPlatform(ctx, userID, platform) + if err != nil || rec == nil { + return nil, err + } + return toServiceRecord(rec), nil +} + +// IncrementUsageWithReset 原子累加 cost 到 (user, platform) 三个窗口的用量。 +func (a *userPlatformQuotaServiceAdapter) IncrementUsageWithReset(ctx context.Context, userID int64, platform string, cost float64, now time.Time) error { + return a.inner.IncrementUsageWithReset(ctx, userID, platform, cost, now) +} + +// ListByUser 查询用户的所有平台配额记录。 +func (a *userPlatformQuotaServiceAdapter) ListByUser(ctx context.Context, userID int64) ([]service.UserPlatformQuotaRecord, error) { + rows, err := a.inner.ListByUser(ctx, userID) + if err != nil { + return nil, err + } + out := make([]service.UserPlatformQuotaRecord, len(rows)) + for i, r := range rows { + out[i] = service.UserPlatformQuotaRecord{ + UserID: r.UserID, + Platform: r.Platform, + DailyLimitUSD: r.DailyLimitUSD, + WeeklyLimitUSD: r.WeeklyLimitUSD, + MonthlyLimitUSD: r.MonthlyLimitUSD, + DailyUsageUSD: r.DailyUsageUSD, + WeeklyUsageUSD: r.WeeklyUsageUSD, + MonthlyUsageUSD: r.MonthlyUsageUSD, + DailyWindowStart: r.DailyWindowStart, + WeeklyWindowStart: r.WeeklyWindowStart, + MonthlyWindowStart: r.MonthlyWindowStart, + } + } + return out, nil +} + +// BulkInsertInitial 将 service.UserPlatformQuotaRecord 切片转换后调用底层 repo。 +func (a *userPlatformQuotaServiceAdapter) BulkInsertInitial(ctx context.Context, records []service.UserPlatformQuotaRecord) error { + repoRecords := make([]UserPlatformQuotaRecord, len(records)) + for i, r := range records { + repoRecords[i] = UserPlatformQuotaRecord{ + UserID: r.UserID, + Platform: r.Platform, + DailyLimitUSD: r.DailyLimitUSD, + WeeklyLimitUSD: r.WeeklyLimitUSD, + MonthlyLimitUSD: r.MonthlyLimitUSD, + } + } + return a.inner.BulkInsertInitial(ctx, repoRecords) +} + +// UpsertForUser 全量替换该用户所有平台限额。 +func (a *userPlatformQuotaServiceAdapter) UpsertForUser(ctx context.Context, userID int64, records []service.UserPlatformQuotaRecord) error { + repoRecords := toRepoRecords(records) + return a.inner.UpsertForUser(ctx, userID, repoRecords) +} + +// ResetExpiredWindow 转发至 repository.ResetExpiredWindow,并将 repository sentinel 包装为 service sentinel。 +func (a *userPlatformQuotaServiceAdapter) ResetExpiredWindow(ctx context.Context, userID int64, platform string, window string, newStart time.Time) error { + err := a.inner.ResetExpiredWindow(ctx, userID, platform, window, newStart) + if errors.Is(err, ErrUserPlatformQuotaNotFound) { + return fmt.Errorf("%w: %w", service.ErrUserPlatformQuotaNotFound, err) + } + return err +} + +// genericUserPlatformQuotaAdapter 通过通用接口适配(用于测试 fake 或非标准实现)。 +type genericUserPlatformQuotaAdapter struct { + inner UserPlatformQuotaRepository +} + +func (a *genericUserPlatformQuotaAdapter) GetByUserPlatform(ctx context.Context, userID int64, platform string) (*service.UserPlatformQuotaRecord, error) { + rec, err := a.inner.GetByUserPlatform(ctx, userID, platform) + if err != nil || rec == nil { + return nil, err + } + return toServiceRecord(rec), nil +} + +// IncrementUsageWithReset 原子累加 cost(通用 adapter 实现)。 +func (a *genericUserPlatformQuotaAdapter) IncrementUsageWithReset(ctx context.Context, userID int64, platform string, cost float64, now time.Time) error { + return a.inner.IncrementUsageWithReset(ctx, userID, platform, cost, now) +} + +// ListByUser 查询用户的所有平台配额记录(通用 adapter 实现)。 +func (a *genericUserPlatformQuotaAdapter) ListByUser(ctx context.Context, userID int64) ([]service.UserPlatformQuotaRecord, error) { + rows, err := a.inner.ListByUser(ctx, userID) + if err != nil { + return nil, err + } + out := make([]service.UserPlatformQuotaRecord, len(rows)) + for i, r := range rows { + out[i] = service.UserPlatformQuotaRecord{ + UserID: r.UserID, + Platform: r.Platform, + DailyLimitUSD: r.DailyLimitUSD, + WeeklyLimitUSD: r.WeeklyLimitUSD, + MonthlyLimitUSD: r.MonthlyLimitUSD, + DailyUsageUSD: r.DailyUsageUSD, + WeeklyUsageUSD: r.WeeklyUsageUSD, + MonthlyUsageUSD: r.MonthlyUsageUSD, + DailyWindowStart: r.DailyWindowStart, + WeeklyWindowStart: r.WeeklyWindowStart, + MonthlyWindowStart: r.MonthlyWindowStart, + } + } + return out, nil +} + +// BulkInsertInitial 将 service.UserPlatformQuotaRecord 切片转换后调用底层 generic repo。 +func (a *genericUserPlatformQuotaAdapter) BulkInsertInitial(ctx context.Context, records []service.UserPlatformQuotaRecord) error { + repoRecords := make([]UserPlatformQuotaRecord, len(records)) + for i, r := range records { + repoRecords[i] = UserPlatformQuotaRecord{ + UserID: r.UserID, + Platform: r.Platform, + DailyLimitUSD: r.DailyLimitUSD, + WeeklyLimitUSD: r.WeeklyLimitUSD, + MonthlyLimitUSD: r.MonthlyLimitUSD, + } + } + return a.inner.BulkInsertInitial(ctx, repoRecords) +} + +// UpsertForUser 全量替换(通用 adapter 实现)。 +func (a *genericUserPlatformQuotaAdapter) UpsertForUser(ctx context.Context, userID int64, records []service.UserPlatformQuotaRecord) error { + repoRecords := toRepoRecords(records) + return a.inner.UpsertForUser(ctx, userID, repoRecords) +} + +// ResetExpiredWindow 转发至 repository.ResetExpiredWindow(通用 adapter),并包装 sentinel。 +func (a *genericUserPlatformQuotaAdapter) ResetExpiredWindow(ctx context.Context, userID int64, platform string, window string, newStart time.Time) error { + err := a.inner.ResetExpiredWindow(ctx, userID, platform, window, newStart) + if errors.Is(err, ErrUserPlatformQuotaNotFound) { + return fmt.Errorf("%w: %w", service.ErrUserPlatformQuotaNotFound, err) + } + return err +} + +// toServiceRecord 将 repository.UserPlatformQuotaRecord 转换为 service.UserPlatformQuotaRecord。 +func toServiceRecord(rec *UserPlatformQuotaRecord) *service.UserPlatformQuotaRecord { + return &service.UserPlatformQuotaRecord{ + UserID: rec.UserID, + Platform: rec.Platform, + DailyLimitUSD: rec.DailyLimitUSD, + WeeklyLimitUSD: rec.WeeklyLimitUSD, + MonthlyLimitUSD: rec.MonthlyLimitUSD, + DailyUsageUSD: rec.DailyUsageUSD, + WeeklyUsageUSD: rec.WeeklyUsageUSD, + MonthlyUsageUSD: rec.MonthlyUsageUSD, + DailyWindowStart: rec.DailyWindowStart, + WeeklyWindowStart: rec.WeeklyWindowStart, + MonthlyWindowStart: rec.MonthlyWindowStart, + } +} + +// toRepoRecords 将 service.UserPlatformQuotaRecord 切片转换为 repository.UserPlatformQuotaRecord(含 limit 字段,含 usage/window_start)。 +func toRepoRecords(records []service.UserPlatformQuotaRecord) []UserPlatformQuotaRecord { + out := make([]UserPlatformQuotaRecord, len(records)) + for i, r := range records { + out[i] = UserPlatformQuotaRecord{ + UserID: r.UserID, + Platform: r.Platform, + DailyLimitUSD: r.DailyLimitUSD, + WeeklyLimitUSD: r.WeeklyLimitUSD, + MonthlyLimitUSD: r.MonthlyLimitUSD, + DailyUsageUSD: r.DailyUsageUSD, + WeeklyUsageUSD: r.WeeklyUsageUSD, + MonthlyUsageUSD: r.MonthlyUsageUSD, + DailyWindowStart: r.DailyWindowStart, + WeeklyWindowStart: r.WeeklyWindowStart, + MonthlyWindowStart: r.MonthlyWindowStart, + } + } + return out +} diff --git a/backend/internal/repository/user_platform_quota_upsert_test.go b/backend/internal/repository/user_platform_quota_upsert_test.go new file mode 100644 index 00000000..db8e6f47 --- /dev/null +++ b/backend/internal/repository/user_platform_quota_upsert_test.go @@ -0,0 +1,148 @@ +//go:build integration + +package repository + +import ( + "context" + "testing" + "time" + + "github.com/Wei-Shaw/sub2api/ent/userplatformquota" + "github.com/stretchr/testify/require" +) + +func TestUpsertForUser_NewUserInsertsAllRecords(t *testing.T) { + ctx := context.Background() + client := testEntClient(t) + userID := mustCreateUserForQuota(t, client) + repo := NewUserPlatformQuotaRepository(client) + + daily := 10.0 + weekly := 50.0 + monthly := 200.0 + records := []UserPlatformQuotaRecord{ + {UserID: userID, Platform: "anthropic", DailyLimitUSD: &daily, WeeklyLimitUSD: &weekly, MonthlyLimitUSD: &monthly}, + {UserID: userID, Platform: "openai", DailyLimitUSD: &daily}, + } + require.NoError(t, repo.UpsertForUser(ctx, userID, records)) + + got, err := repo.ListByUser(ctx, userID) + require.NoError(t, err) + require.Len(t, got, 2) +} + +func TestUpsertForUser_PartialUpdateSoftDeletesMissingPlatforms(t *testing.T) { + ctx := context.Background() + client := testEntClient(t) + userID := mustCreateUserForQuota(t, client) + repo := NewUserPlatformQuotaRepository(client) + + d1 := 10.0 + d2 := 20.0 + require.NoError(t, repo.UpsertForUser(ctx, userID, []UserPlatformQuotaRecord{ + {UserID: userID, Platform: "anthropic", DailyLimitUSD: &d1}, + {UserID: userID, Platform: "openai", DailyLimitUSD: &d1}, + })) + require.NoError(t, repo.UpsertForUser(ctx, userID, []UserPlatformQuotaRecord{ + {UserID: userID, Platform: "anthropic", DailyLimitUSD: &d2}, + {UserID: userID, Platform: "gemini", DailyLimitUSD: &d1}, + })) + + active, err := repo.ListByUser(ctx, userID) + require.NoError(t, err) + platforms := map[string]float64{} + for _, r := range active { + require.NotNil(t, r.DailyLimitUSD) + platforms[r.Platform] = *r.DailyLimitUSD + } + require.Len(t, platforms, 2) + require.InDelta(t, 20.0, platforms["anthropic"], 1e-9) + require.InDelta(t, 10.0, platforms["gemini"], 1e-9) + _, openaiActive := platforms["openai"] + require.False(t, openaiActive, "openai should be soft-deleted") +} + +func TestUpsertForUser_PreservesUsageAndWindowStart(t *testing.T) { + ctx := context.Background() + client := testEntClient(t) + userID := mustCreateUserForQuota(t, client) + repo := NewUserPlatformQuotaRepository(client) + + d := 10.0 + require.NoError(t, repo.UpsertForUser(ctx, userID, []UserPlatformQuotaRecord{ + {UserID: userID, Platform: "anthropic", DailyLimitUSD: &d}, + })) + + now := time.Date(2026, 5, 22, 10, 0, 0, 0, time.UTC) + require.NoError(t, repo.IncrementUsageWithReset(ctx, userID, "anthropic", 3.5, now)) + + newD := 50.0 + require.NoError(t, repo.UpsertForUser(ctx, userID, []UserPlatformQuotaRecord{ + {UserID: userID, Platform: "anthropic", DailyLimitUSD: &newD}, + })) + + rec, err := repo.GetByUserPlatform(ctx, userID, "anthropic") + require.NoError(t, err) + require.NotNil(t, rec) + require.InDelta(t, 50.0, *rec.DailyLimitUSD, 1e-9, "limit should update") + require.InDelta(t, 3.5, rec.DailyUsageUSD, 1e-9, "usage must be preserved") + require.NotNil(t, rec.DailyWindowStart, "window_start must be preserved") +} + +func TestUpsertForUser_ReactivatesSoftDeleted(t *testing.T) { + ctx := context.Background() + client := testEntClient(t) + userID := mustCreateUserForQuota(t, client) + repo := NewUserPlatformQuotaRepository(client) + + d := 10.0 + require.NoError(t, repo.UpsertForUser(ctx, userID, []UserPlatformQuotaRecord{ + {UserID: userID, Platform: "anthropic", DailyLimitUSD: &d}, + })) + require.NoError(t, repo.UpsertForUser(ctx, userID, []UserPlatformQuotaRecord{})) + + gone, err := repo.GetByUserPlatform(ctx, userID, "anthropic") + require.NoError(t, err) + require.Nil(t, gone, "anthropic should be soft-deleted (not active)") + + d2 := 20.0 + require.NoError(t, repo.UpsertForUser(ctx, userID, []UserPlatformQuotaRecord{ + {UserID: userID, Platform: "anthropic", DailyLimitUSD: &d2}, + })) + + back, err := repo.GetByUserPlatform(ctx, userID, "anthropic") + require.NoError(t, err) + require.NotNil(t, back, "anthropic should be active again") + require.InDelta(t, 20.0, *back.DailyLimitUSD, 1e-9) + + allRows, err := client.UserPlatformQuota.Query(). + Where(userplatformquota.UserIDEQ(userID), userplatformquota.PlatformEQ("anthropic")). + All(ctx) + require.NoError(t, err) + activeCount := 0 + for _, r := range allRows { + if r.DeletedAt == nil { + activeCount++ + } + } + require.Equal(t, 1, activeCount, "should have exactly one active row") +} + +func TestUpsertForUser_EmptyClearsAll(t *testing.T) { + ctx := context.Background() + client := testEntClient(t) + userID := mustCreateUserForQuota(t, client) + repo := NewUserPlatformQuotaRepository(client) + + d := 10.0 + require.NoError(t, repo.UpsertForUser(ctx, userID, []UserPlatformQuotaRecord{ + {UserID: userID, Platform: "anthropic", DailyLimitUSD: &d}, + {UserID: userID, Platform: "openai", DailyLimitUSD: &d}, + })) + + require.NoError(t, repo.UpsertForUser(ctx, userID, []UserPlatformQuotaRecord{})) + + got, err := repo.ListByUser(ctx, userID) + require.NoError(t, err) + require.Empty(t, got) +} diff --git a/backend/internal/repository/wire.go b/backend/internal/repository/wire.go index 3c0ee9cb..2d1b04e3 100644 --- a/backend/internal/repository/wire.go +++ b/backend/internal/repository/wire.go @@ -93,6 +93,8 @@ var ProviderSet = wire.NewSet( NewChannelMonitorRequestTemplateRepository, NewContentModerationRepository, NewAffiliateRepository, + NewUserPlatformQuotaRepository, // T14: user × platform quota + NewUserPlatformQuotaServiceAdapter, // T14: adapter → service.UserPlatformQuotaRepository // Cache implementations NewGatewayCache, diff --git a/backend/internal/server/api_contract_test.go b/backend/internal/server/api_contract_test.go index fcf37ed7..8bc9e280 100644 --- a/backend/internal/server/api_contract_test.go +++ b/backend/internal/server/api_contract_test.go @@ -798,6 +798,14 @@ func TestAPIContracts(t *testing.T) { "force_email_on_third_party_signup": false, "default_concurrency": 5, "default_balance": 1.25, + "default_platform_quotas": {"anthropic":{"daily":null,"weekly":null,"monthly":null},"antigravity":{"daily":null,"weekly":null,"monthly":null},"gemini":{"daily":null,"weekly":null,"monthly":null},"openai":{"daily":null,"weekly":null,"monthly":null}}, + "auth_source_default_email_platform_quotas": null, + "auth_source_default_github_platform_quotas": null, + "auth_source_default_google_platform_quotas": null, + "auth_source_default_linuxdo_platform_quotas": null, + "auth_source_default_oidc_platform_quotas": null, + "auth_source_default_wechat_platform_quotas": null, + "auth_source_default_dingtalk_platform_quotas": null, "affiliate_rebate_rate": 20, "affiliate_rebate_freeze_hours": 0, "affiliate_rebate_duration_days": 0, @@ -1025,6 +1033,14 @@ func TestAPIContracts(t *testing.T) { "purchase_subscription_url": "", "table_default_page_size": 20, "table_page_size_options": [10, 20, 50], + "default_platform_quotas": {"anthropic":{"daily":null,"weekly":null,"monthly":null},"antigravity":{"daily":null,"weekly":null,"monthly":null},"gemini":{"daily":null,"weekly":null,"monthly":null},"openai":{"daily":null,"weekly":null,"monthly":null}}, + "auth_source_default_email_platform_quotas": null, + "auth_source_default_github_platform_quotas": null, + "auth_source_default_google_platform_quotas": null, + "auth_source_default_linuxdo_platform_quotas": null, + "auth_source_default_oidc_platform_quotas": null, + "auth_source_default_wechat_platform_quotas": null, + "auth_source_default_dingtalk_platform_quotas": null, "custom_menu_items": [], "custom_endpoints": [], "default_concurrency": 0, diff --git a/backend/internal/server/middleware/admin_auth_test.go b/backend/internal/server/middleware/admin_auth_test.go index 3fbbb716..303d0db8 100644 --- a/backend/internal/server/middleware/admin_auth_test.go +++ b/backend/internal/server/middleware/admin_auth_test.go @@ -20,7 +20,7 @@ func TestAdminAuthJWTValidatesTokenVersion(t *testing.T) { gin.SetMode(gin.TestMode) cfg := &config.Config{JWT: config.JWTConfig{Secret: "test-secret", ExpireHour: 1}} - authService := service.NewAuthService(nil, nil, nil, nil, cfg, nil, nil, nil, nil, nil, nil, nil) + authService := service.NewAuthService(nil, nil, nil, nil, cfg, nil, nil, nil, nil, nil, nil, nil, nil) admin := &service.User{ ID: 1, diff --git a/backend/internal/server/middleware/jwt_auth_test.go b/backend/internal/server/middleware/jwt_auth_test.go index a643d3bc..e9922e54 100644 --- a/backend/internal/server/middleware/jwt_auth_test.go +++ b/backend/internal/server/middleware/jwt_auth_test.go @@ -60,7 +60,7 @@ func newJWTTestEnv(users map[int64]*service.User) (*gin.Engine, *service.AuthSer cfg.JWT.AccessTokenExpireMinutes = 60 userRepo := &stubJWTUserRepo{users: users} - authSvc := service.NewAuthService(nil, userRepo, nil, nil, cfg, nil, nil, nil, nil, nil, nil, nil) + authSvc := service.NewAuthService(nil, userRepo, nil, nil, cfg, nil, nil, nil, nil, nil, nil, nil, nil) userSvc := service.NewUserService(userRepo, nil, nil, nil) mw := NewJWTAuthMiddleware(authSvc, userSvc) @@ -143,7 +143,7 @@ func TestJWTAuth_ValidToken_TouchesLastActive(t *testing.T) { cfg.JWT.AccessTokenExpireMinutes = 60 userRepo := &stubJWTUserRepo{users: map[int64]*service.User{1: user}} - authSvc := service.NewAuthService(nil, userRepo, nil, nil, cfg, nil, nil, nil, nil, nil, nil, nil) + authSvc := service.NewAuthService(nil, userRepo, nil, nil, cfg, nil, nil, nil, nil, nil, nil, nil, nil) userSvc := service.NewUserService(userRepo, nil, nil, nil) toucher := &recordingActivityToucher{} diff --git a/backend/internal/server/routes/admin.go b/backend/internal/server/routes/admin.go index e036cf32..5d62a7ab 100644 --- a/backend/internal/server/routes/admin.go +++ b/backend/internal/server/routes/admin.go @@ -241,6 +241,9 @@ func registerUserManagementRoutes(admin *gin.RouterGroup, h *handler.Handlers) { users.POST("/:id/replace-group", h.Admin.User.ReplaceGroup) users.GET("/:id/rpm-status", h.Admin.User.GetUserRPMStatus) users.POST("/batch-concurrency", h.Admin.User.BatchUpdateConcurrency) + users.GET("/:id/platform-quotas", h.Admin.User.GetUserPlatformQuotas) + users.PUT("/:id/platform-quotas", h.Admin.User.UpdateUserPlatformQuotas) + users.POST("/:id/platform-quotas/reset", h.Admin.User.ResetUserPlatformQuotaWindow) // User attribute values users.GET("/:id/attributes", h.Admin.UserAttribute.GetUserAttributes) diff --git a/backend/internal/server/routes/user.go b/backend/internal/server/routes/user.go index e79d3ee3..07ae33de 100644 --- a/backend/internal/server/routes/user.go +++ b/backend/internal/server/routes/user.go @@ -32,6 +32,7 @@ func RegisterUserRoutes( user.DELETE("/account-bindings/:provider", h.User.UnbindIdentity) user.POST("/auth-identities/bind/start", h.User.StartIdentityBinding) user.GET("/api-keys/:id/usage/daily", h.Usage.GetMyAPIKeyDailyUsage) + user.GET("/platform-quotas", h.User.GetMyPlatformQuotas) // 通知邮箱管理 notifyEmail := user.Group("/notify-email") diff --git a/backend/internal/service/admin_service_delete_test.go b/backend/internal/service/admin_service_delete_test.go index 2f764d67..d01b11e6 100644 --- a/backend/internal/service/admin_service_delete_test.go +++ b/backend/internal/service/admin_service_delete_test.go @@ -459,6 +459,22 @@ func (s *billingCacheStub) InvalidateAPIKeyRateLimit(ctx context.Context, keyID panic("unexpected InvalidateAPIKeyRateLimit call") } +func (s *billingCacheStub) GetUserPlatformQuotaCache(ctx context.Context, userID int64, platform string) (*UserPlatformQuotaCacheEntry, bool, error) { + panic("unexpected GetUserPlatformQuotaCache call") +} + +func (s *billingCacheStub) SetUserPlatformQuotaCache(ctx context.Context, userID int64, platform string, entry *UserPlatformQuotaCacheEntry, ttl time.Duration) error { + panic("unexpected SetUserPlatformQuotaCache call") +} + +func (s *billingCacheStub) DeleteUserPlatformQuotaCache(ctx context.Context, userID int64, platform string) error { + panic("unexpected DeleteUserPlatformQuotaCache call") +} + +func (s *billingCacheStub) IncrUserPlatformQuotaUsageCache(ctx context.Context, userID int64, platform string, cost float64, ttl time.Duration) error { + panic("unexpected IncrUserPlatformQuotaUsageCache call") +} + func waitForInvalidations(t *testing.T, ch <-chan subscriptionInvalidateCall, expected int) []subscriptionInvalidateCall { t.Helper() calls := make([]subscriptionInvalidateCall, 0, expected) diff --git a/backend/internal/service/auth_email_oauth_auto.go b/backend/internal/service/auth_email_oauth_auto.go index 4db845c2..f86df14c 100644 --- a/backend/internal/service/auth_email_oauth_auto.go +++ b/backend/internal/service/auth_email_oauth_auto.go @@ -189,6 +189,8 @@ func (s *AuthService) createEmailOAuthUser(ctx context.Context, email, username, } s.postAuthUserBootstrap(ctx, user, providerType, false) s.assignSubscriptions(ctx, user.ID, grantPlan.Subscriptions, "auto assigned by signup defaults") + // snapshot user × platform quota(fail-open) + _ = s.snapshotPlatformQuotaDefaults(ctx, user.ID, &grantPlan) s.bindOAuthAffiliate(ctx, user.ID, affiliateCode) if invitationRedeemCode != nil { if err := s.useOAuthRegistrationInvitation(ctx, invitationRedeemCode.ID, user.ID); err != nil { diff --git a/backend/internal/service/auth_email_oauth_auto_test.go b/backend/internal/service/auth_email_oauth_auto_test.go new file mode 100644 index 00000000..d128e6bb --- /dev/null +++ b/backend/internal/service/auth_email_oauth_auto_test.go @@ -0,0 +1,88 @@ +//go:build unit + +package service + +import ( + "context" + "testing" + + "github.com/Wei-Shaw/sub2api/internal/config" + "github.com/stretchr/testify/require" +) + +func newEmailOAuthAutoAuthService( + userRepo UserRepository, + settings map[string]string, + quotaRepo UserPlatformQuotaRepository, +) *AuthService { + cfg := &config.Config{ + JWT: config.JWTConfig{ + Secret: "test-secret", + ExpireHour: 1, + AccessTokenExpireMinutes: 60, + RefreshTokenExpireDays: 7, + }, + Default: config.DefaultConfig{ + UserBalance: 3.5, + UserConcurrency: 2, + }, + } + + settingService := NewSettingService(&settingRepoStub{values: settings}, cfg) + + return NewAuthService( + nil, // entClient — nil, updateUserSignupSource early return + userRepo, + nil, // redeemRepo — invitationCode="" 时不触发 + &refreshTokenCacheStub{}, + cfg, + settingService, + nil, // emailService + nil, // turnstileService + nil, // emailQueueService + nil, // promoService + nil, // defaultSubAssigner — nil, assignSubscriptions early return + nil, // affiliateService — nil, bindOAuthAffiliate early return + quotaRepo, + ) +} + +func TestEmailOAuthAuto_SnapshotsPlatformQuotaDefaults(t *testing.T) { + userRepo := &userRepoStub{nextID: 88} + quotaRepo := &userPlatformQuotaRepoStub{} + + svc := newEmailOAuthAutoAuthService( + userRepo, + map[string]string{ + SettingKeyRegistrationEnabled: "true", + SettingKeyDefaultPlatformQuotas: `{"gemini": {"monthly": 100.0}}`, + }, + quotaRepo, + ) + + user, err := svc.createEmailOAuthUser( + context.Background(), + "newoauth@example.com", + "newoauth", + "github", + "", // invitationCode + "", // affiliateCode + ) + require.NoError(t, err) + require.NotNil(t, user) + require.Equal(t, int64(88), user.ID) + + require.Len(t, quotaRepo.bulkInsertCalls, 1, "createEmailOAuthUser must snapshot platform quotas via BulkInsertInitial") + + records := quotaRepo.bulkInsertCalls[0] + var geminiRecord *UserPlatformQuotaRecord + for i := range records { + if records[i].Platform == "gemini" { + geminiRecord = &records[i] + break + } + } + require.NotNil(t, geminiRecord, "expected gemini platform record") + require.NotNil(t, geminiRecord.MonthlyLimitUSD) + require.InDelta(t, 100.0, *geminiRecord.MonthlyLimitUSD, 0.0001) +} diff --git a/backend/internal/service/auth_oauth_email_flow.go b/backend/internal/service/auth_oauth_email_flow.go index cf0be652..24d0eeee 100644 --- a/backend/internal/service/auth_oauth_email_flow.go +++ b/backend/internal/service/auth_oauth_email_flow.go @@ -283,6 +283,8 @@ func (s *AuthService) FinalizeOAuthEmailAccount( s.updateOAuthSignupSource(ctx, user.ID, signupSource) grantPlan := s.resolveSignupGrantPlan(ctx, signupSource) s.assignSubscriptions(ctx, user.ID, grantPlan.Subscriptions, "auto assigned by signup defaults") + // snapshot user × platform quota(fail-open) + _ = s.snapshotPlatformQuotaDefaults(ctx, user.ID, &grantPlan) s.bindOAuthAffiliate(ctx, user.ID, affiliateCode) return nil } diff --git a/backend/internal/service/auth_oauth_email_flow_test.go b/backend/internal/service/auth_oauth_email_flow_test.go index 3c02587b..5a78a348 100644 --- a/backend/internal/service/auth_oauth_email_flow_test.go +++ b/backend/internal/service/auth_oauth_email_flow_test.go @@ -112,6 +112,7 @@ func newOAuthEmailFlowAuthService( refreshTokenCache RefreshTokenCache, settings map[string]string, emailCache EmailCache, + quotaRepo UserPlatformQuotaRepository, // 新增 ) *AuthService { cfg := &config.Config{ JWT: config.JWTConfig{ @@ -142,6 +143,7 @@ func newOAuthEmailFlowAuthService( nil, nil, nil, + quotaRepo, // 替换原来的 nil ) } @@ -175,6 +177,7 @@ func TestRegisterOAuthEmailAccountRollsBackCreatedUserWhenTokenPairGenerationFai SettingKeyEmailVerifyEnabled: "true", }, emailCache, + nil, ) tokenPair, user, err := authService.RegisterOAuthEmailAccount( @@ -215,6 +218,7 @@ func TestRegisterOAuthEmailAccountSetsNormalizedSignupSourceOnCreatedUser(t *tes SettingKeyEmailVerifyEnabled: "true", }, emailCache, + nil, ) tokenPair, user, err := authService.RegisterOAuthEmailAccount( @@ -274,6 +278,7 @@ func TestRegisterOAuthEmailAccountKeepsGitHubAndGoogleSignupSource(t *testing.T) SettingKeyEmailVerifyEnabled: "true", }, emailCache, + nil, ) tokenPair, user, err := authService.RegisterOAuthEmailAccount( @@ -313,6 +318,7 @@ func TestRegisterOAuthEmailAccountFallsBackUnknownSignupSourceToEmail(t *testing SettingKeyEmailVerifyEnabled: "true", }, emailCache, + nil, ) tokenPair, user, err := authService.RegisterOAuthEmailAccount( @@ -360,6 +366,7 @@ func TestRollbackOAuthEmailAccountCreationRestoresInvitationUsage(t *testing.T) SettingKeyInvitationCodeEnabled: "true", }, &emailCacheStub{}, + nil, ) err := authService.RollbackOAuthEmailAccountCreation(context.Background(), 42, "INVITE123") @@ -382,6 +389,7 @@ func TestRollbackOAuthEmailAccountCreationPropagatesDeleteError(t *testing.T) { SettingKeyRegistrationEnabled: "true", }, &emailCacheStub{}, + nil, ) err := authService.RollbackOAuthEmailAccountCreation(context.Background(), 42, "") @@ -389,3 +397,54 @@ func TestRollbackOAuthEmailAccountCreationPropagatesDeleteError(t *testing.T) { require.Error(t, err) require.Contains(t, err.Error(), "delete created oauth user") } + +func TestFinalizeOAuthEmailAccount_SnapshotsPlatformQuotaDefaults(t *testing.T) { + userRepo := &userRepoStub{nextID: 99} + quotaRepo := &userPlatformQuotaRepoStub{} + + authService := newOAuthEmailFlowAuthService( + userRepo, + nil, + &refreshTokenCacheStub{}, + map[string]string{ + SettingKeyRegistrationEnabled: "true", + SettingKeyEmailVerifyEnabled: "true", + SettingKeyDefaultPlatformQuotas: `{"anthropic": {"daily": 5.5}}`, + }, + &emailCacheStub{}, + quotaRepo, + ) + + user := &User{ + ID: 99, + Email: "newuser@example.com", + Role: RoleUser, + Status: StatusActive, + SignupSource: "oidc", + } + + err := authService.FinalizeOAuthEmailAccount( + context.Background(), + user, + "", + "oidc", + "", + ) + + require.NoError(t, err) + + require.Len(t, quotaRepo.bulkInsertCalls, 1, "snapshotPlatformQuotaDefaults must call BulkInsertInitial once on successful OAuth signup") + + records := quotaRepo.bulkInsertCalls[0] + var anthropicRecord *UserPlatformQuotaRecord + for i := range records { + if records[i].Platform == "anthropic" { + anthropicRecord = &records[i] + break + } + } + require.NotNil(t, anthropicRecord, "expected anthropic platform record") + require.Equal(t, int64(99), anthropicRecord.UserID) + require.NotNil(t, anthropicRecord.DailyLimitUSD) + require.InDelta(t, 5.5, *anthropicRecord.DailyLimitUSD, 0.0001) +} diff --git a/backend/internal/service/auth_service.go b/backend/internal/service/auth_service.go index 4e5b7b94..e4fa876c 100644 --- a/backend/internal/service/auth_service.go +++ b/backend/internal/service/auth_service.go @@ -62,18 +62,19 @@ type JWTClaims struct { // AuthService 认证服务 type AuthService struct { - entClient *dbent.Client - userRepo UserRepository - redeemRepo RedeemCodeRepository - refreshTokenCache RefreshTokenCache - cfg *config.Config - settingService *SettingService - emailService *EmailService - turnstileService *TurnstileService - emailQueueService *EmailQueueService - promoService *PromoService - affiliateService *AffiliateService - defaultSubAssigner DefaultSubscriptionAssigner + entClient *dbent.Client + userRepo UserRepository + redeemRepo RedeemCodeRepository + refreshTokenCache RefreshTokenCache + cfg *config.Config + settingService *SettingService + emailService *EmailService + turnstileService *TurnstileService + emailQueueService *EmailQueueService + promoService *PromoService + affiliateService *AffiliateService + defaultSubAssigner DefaultSubscriptionAssigner + userPlatformQuotaRepo UserPlatformQuotaRepository } type DefaultSubscriptionAssigner interface { @@ -81,9 +82,10 @@ type DefaultSubscriptionAssigner interface { } type signupGrantPlan struct { - Balance float64 - Concurrency int - Subscriptions []DefaultSubscriptionSetting + Balance float64 + Concurrency int + Subscriptions []DefaultSubscriptionSetting + PlatformQuotas map[string]*DefaultPlatformQuotaSetting } // NewAuthService 创建认证服务实例 @@ -100,20 +102,22 @@ func NewAuthService( promoService *PromoService, defaultSubAssigner DefaultSubscriptionAssigner, affiliateService *AffiliateService, + userPlatformQuotaRepo UserPlatformQuotaRepository, ) *AuthService { return &AuthService{ - entClient: entClient, - userRepo: userRepo, - redeemRepo: redeemRepo, - refreshTokenCache: refreshTokenCache, - cfg: cfg, - settingService: settingService, - emailService: emailService, - turnstileService: turnstileService, - emailQueueService: emailQueueService, - promoService: promoService, - affiliateService: affiliateService, - defaultSubAssigner: defaultSubAssigner, + entClient: entClient, + userRepo: userRepo, + redeemRepo: redeemRepo, + refreshTokenCache: refreshTokenCache, + cfg: cfg, + settingService: settingService, + emailService: emailService, + turnstileService: turnstileService, + emailQueueService: emailQueueService, + promoService: promoService, + affiliateService: affiliateService, + defaultSubAssigner: defaultSubAssigner, + userPlatformQuotaRepo: userPlatformQuotaRepo, } } @@ -226,6 +230,8 @@ func (s *AuthService) RegisterWithVerification(ctx context.Context, email, passw } s.postAuthUserBootstrap(ctx, user, "email", true) s.assignSubscriptions(ctx, user.ID, grantPlan.Subscriptions, "auto assigned by signup defaults") + // snapshot user × platform quota(fail-open) + _ = s.snapshotPlatformQuotaDefaults(ctx, user.ID, &grantPlan) if s.affiliateService != nil { if _, err := s.affiliateService.EnsureUserAffiliate(ctx, user.ID); err != nil { logger.LegacyPrintf("service.auth", "[Auth] Failed to initialize affiliate profile for user %d: %v", user.ID, err) @@ -535,6 +541,8 @@ func (s *AuthService) LoginOrRegisterOAuth(ctx context.Context, email, username user = newUser s.postAuthUserBootstrap(ctx, user, signupSource, false) s.assignSubscriptions(ctx, user.ID, grantPlan.Subscriptions, "auto assigned by signup defaults") + // snapshot user × platform quota(fail-open) + _ = s.snapshotPlatformQuotaDefaults(ctx, user.ID, &grantPlan) } } else { logger.LegacyPrintf("service.auth", "[Auth] Database error during oauth login: %v", err) @@ -685,6 +693,8 @@ func (s *AuthService) LoginOrRegisterOAuthWithTokenPair(ctx context.Context, ema user = newUser s.postAuthUserBootstrap(ctx, user, signupSource, false) s.assignSubscriptions(ctx, user.ID, grantPlan.Subscriptions, "auto assigned by signup defaults") + // snapshot user × platform quota(fail-open) + _ = s.snapshotPlatformQuotaDefaults(ctx, user.ID, &grantPlan) s.bindOAuthAffiliate(ctx, user.ID, affiliateCode) } } else { @@ -703,6 +713,8 @@ func (s *AuthService) LoginOrRegisterOAuthWithTokenPair(ctx context.Context, ema user = newUser s.postAuthUserBootstrap(ctx, user, signupSource, false) s.assignSubscriptions(ctx, user.ID, grantPlan.Subscriptions, "auto assigned by signup defaults") + // snapshot user × platform quota(fail-open) + _ = s.snapshotPlatformQuotaDefaults(ctx, user.ID, &grantPlan) s.bindOAuthAffiliate(ctx, user.ID, affiliateCode) if invitationRedeemCode != nil { if err := s.redeemRepo.Use(ctx, invitationRedeemCode.ID, user.ID); err != nil { @@ -764,18 +776,39 @@ func (s *AuthService) resolveSignupGrantPlan(ctx context.Context, signupSource s plan.Concurrency = s.settingService.GetDefaultConcurrency(ctx) plan.Subscriptions = s.settingService.GetDefaultSubscriptions(ctx) + // ============ 全局 quota 装载(必须在 ResolveAuthSourceGrantSettings 之前) ============ + // 无论 auth source 是否 enabled,全局层都要先装载,确保 !enabled 早退路径也携带全局 quota。 + if quotas, err := s.settingService.GetDefaultPlatformQuotas(ctx); err == nil { + plan.PlatformQuotas = quotas + } else { + logger.LegacyPrintf("service.auth", "[Auth] Warning: load default platform quotas failed: %v (fail-open)", err) + } + // ============================================================================================ + resolved, enabled, err := s.settingService.ResolveAuthSourceGrantSettings(ctx, signupSource, false) if err != nil { logger.LegacyPrintf("service.auth", "[Auth] Failed to load auth source signup defaults for %s: %v", signupSource, err) return plan } if !enabled { - return plan + return plan // plan.PlatformQuotas 已含全局层 } plan.Balance = resolved.Balance plan.Concurrency = resolved.Concurrency plan.Subscriptions = resolved.Subscriptions + + // ============ auth source quota merge(仅在 enabled 分支内) ============ + asQuotas := s.settingService.GetAuthSourcePlatformQuotas(ctx, signupSource) + if plan.PlatformQuotas != nil { + for platform, patch := range asQuotas { + if dst := plan.PlatformQuotas[platform]; dst != nil { + mergePlatformQuotaDefaults(dst, patch) + } + } + } + // ============================================================================== + return plan } @@ -1586,3 +1619,29 @@ func resolvedTokenVersion(user *User) int64 { fingerprint := int64(binary.BigEndian.Uint64(sum[:8]) & 0x7fffffffffffffff) return user.TokenVersion ^ fingerprint } + +// snapshotPlatformQuotaDefaults 把 plan.PlatformQuotas(4 platform × 3 window)以 +// BulkInsertInitial 形式写入 user_platform_quotas 表。失败 fail-open(仅 warn log)。 +func (s *AuthService) snapshotPlatformQuotaDefaults(ctx context.Context, userID int64, plan *signupGrantPlan) error { + if s.userPlatformQuotaRepo == nil || plan == nil || len(plan.PlatformQuotas) == 0 { + return nil + } + records := make([]UserPlatformQuotaRecord, 0, len(plan.PlatformQuotas)) + for platform, q := range plan.PlatformQuotas { + rec := UserPlatformQuotaRecord{ + UserID: userID, + Platform: platform, + } + if q != nil { + rec.DailyLimitUSD = q.DailyLimitUSD + rec.WeeklyLimitUSD = q.WeeklyLimitUSD + rec.MonthlyLimitUSD = q.MonthlyLimitUSD + } + records = append(records, rec) + } + if err := s.userPlatformQuotaRepo.BulkInsertInitial(ctx, records); err != nil { + logger.LegacyPrintf("service.auth", "[Auth] Warning: snapshot platform quota failed user=%d: %v (fail-open)", userID, err) + return nil // fail-open:返回 nil,让调用方继续 + } + return nil +} diff --git a/backend/internal/service/auth_service_email_bind_test.go b/backend/internal/service/auth_service_email_bind_test.go index 8f03f857..87867395 100644 --- a/backend/internal/service/auth_service_email_bind_test.go +++ b/backend/internal/service/auth_service_email_bind_test.go @@ -110,7 +110,7 @@ CREATE TABLE IF NOT EXISTS user_provider_default_grants ( emailSvc = service.NewEmailService(settingRepo, emailCache) } - svc := service.NewAuthService(client, repo, nil, refreshTokenCache, cfg, settingSvc, emailSvc, nil, nil, nil, defaultSubAssigner, nil) + svc := service.NewAuthService(client, repo, nil, refreshTokenCache, cfg, settingSvc, emailSvc, nil, nil, nil, defaultSubAssigner, nil, nil) return svc, repo, client } @@ -467,7 +467,7 @@ func TestAuthServiceBindEmailIdentity_RevokesExistingAccessAndRefreshTokens(t *t }, } emailService := service.NewEmailService(nil, cache) - svc := service.NewAuthService(nil, userRepo, nil, refreshTokenCache, cfg, nil, emailService, nil, nil, nil, nil, nil) + svc := service.NewAuthService(nil, userRepo, nil, refreshTokenCache, cfg, nil, emailService, nil, nil, nil, nil, nil, nil) oldTokenPair, err := svc.GenerateTokenPair(ctx, &service.User{ ID: 41, @@ -810,8 +810,8 @@ func (s *emailBindUserRepoStub) UpdateUserLastActiveAt(context.Context, int64, t } func (s *emailBindUserRepoStub) UpdateBalance(context.Context, int64, float64) error { return nil } -func (s *emailBindUserRepoStub) DeductBalance(context.Context, int64, float64) error { return nil } -func (s *emailBindUserRepoStub) UpdateConcurrency(context.Context, int64, int) error { return nil } +func (s *emailBindUserRepoStub) DeductBalance(context.Context, int64, float64) error { return nil } +func (s *emailBindUserRepoStub) UpdateConcurrency(context.Context, int64, int) error { return nil } func (s *emailBindUserRepoStub) ExistsByEmail(_ context.Context, email string) (bool, error) { s.mu.Lock() @@ -820,8 +820,12 @@ func (s *emailBindUserRepoStub) ExistsByEmail(_ context.Context, email string) ( return ok, nil } -func (s *emailBindUserRepoStub) BatchSetConcurrency(context.Context, []int64, int) (int, error) { return 0, nil } -func (s *emailBindUserRepoStub) BatchAddConcurrency(context.Context, []int64, int) (int, error) { return 0, nil } +func (s *emailBindUserRepoStub) BatchSetConcurrency(context.Context, []int64, int) (int, error) { + return 0, nil +} +func (s *emailBindUserRepoStub) BatchAddConcurrency(context.Context, []int64, int) (int, error) { + return 0, nil +} func (s *emailBindUserRepoStub) RemoveGroupFromAllowedGroups(context.Context, int64) (int64, error) { return 0, nil diff --git a/backend/internal/service/auth_service_identity_sync_test.go b/backend/internal/service/auth_service_identity_sync_test.go index 53048b92..59ed8e52 100644 --- a/backend/internal/service/auth_service_identity_sync_test.go +++ b/backend/internal/service/auth_service_identity_sync_test.go @@ -137,7 +137,7 @@ CREATE TABLE IF NOT EXISTS user_provider_default_grants ( values: settings, }, cfg) - svc := service.NewAuthService(client, repo, nil, nil, cfg, settingSvc, nil, nil, nil, nil, defaultSubAssigner, nil) + svc := service.NewAuthService(client, repo, nil, nil, cfg, settingSvc, nil, nil, nil, nil, defaultSubAssigner, nil, nil) return svc, repo, client } diff --git a/backend/internal/service/auth_service_platform_quota_test.go b/backend/internal/service/auth_service_platform_quota_test.go new file mode 100644 index 00000000..f58dc48c --- /dev/null +++ b/backend/internal/service/auth_service_platform_quota_test.go @@ -0,0 +1,157 @@ +//go:build unit + +package service + +import ( + "context" + "fmt" + "testing" + "time" +) + +// fakeInsertRecorder 记录 BulkInsertInitial 调用,实现 UserPlatformQuotaRepository port。 +type fakeInsertRecorder struct { + records []UserPlatformQuotaRecord + err error +} + +func (f *fakeInsertRecorder) GetByUserPlatform(_ context.Context, _ int64, _ string) (*UserPlatformQuotaRecord, error) { + return nil, nil +} + +func (f *fakeInsertRecorder) BulkInsertInitial(_ context.Context, recs []UserPlatformQuotaRecord) error { + if f.err != nil { + return f.err + } + f.records = append(f.records, recs...) + return nil +} + +func (f *fakeInsertRecorder) IncrementUsageWithReset(_ context.Context, _ int64, _ string, _ float64, _ time.Time) error { + return nil +} + +func (f *fakeInsertRecorder) ListByUser(_ context.Context, _ int64) ([]UserPlatformQuotaRecord, error) { + return nil, nil +} + +func (f *fakeInsertRecorder) UpsertForUser(_ context.Context, _ int64, _ []UserPlatformQuotaRecord) error { + return nil +} + +func (f *fakeInsertRecorder) ResetExpiredWindow(_ context.Context, _ int64, _ string, _ string, _ time.Time) error { + return nil +} + +func TestSnapshotPlatformQuotaDefaults_PassesToRepoBulkInsert(t *testing.T) { + fakeRepo := &fakeInsertRecorder{} + s := &AuthService{userPlatformQuotaRepo: fakeRepo} + + five := 5.0 + plan := &signupGrantPlan{ + PlatformQuotas: map[string]*DefaultPlatformQuotaSetting{ + "anthropic": {DailyLimitUSD: &five}, + "openai": {}, + "gemini": {}, + "antigravity": {}, + }, + } + if err := s.snapshotPlatformQuotaDefaults(context.Background(), 999, plan); err != nil { + t.Fatal(err) + } + if len(fakeRepo.records) != 4 { + t.Errorf("expected 4 records, got %d", len(fakeRepo.records)) + } + found := false + for _, r := range fakeRepo.records { + if r.UserID == 999 && r.Platform == "anthropic" && r.DailyLimitUSD != nil && *r.DailyLimitUSD == 5 { + found = true + } + } + if !found { + t.Error("anthropic daily = 5 not snapshotted") + } +} + +func TestSnapshotPlatformQuotaDefaults_NilPlanIsNoop(t *testing.T) { + fakeRepo := &fakeInsertRecorder{} + s := &AuthService{userPlatformQuotaRepo: fakeRepo} + if err := s.snapshotPlatformQuotaDefaults(context.Background(), 1, nil); err != nil { + t.Errorf("nil plan should be noop, got %v", err) + } + if len(fakeRepo.records) != 0 { + t.Errorf("expected no records, got %d", len(fakeRepo.records)) + } +} + +func TestSnapshotPlatformQuotaDefaults_RepoErrorFailsOpen(t *testing.T) { + fakeRepo := &fakeInsertRecorder{err: fmt.Errorf("db down")} + s := &AuthService{userPlatformQuotaRepo: fakeRepo} + five := 5.0 + plan := &signupGrantPlan{ + PlatformQuotas: map[string]*DefaultPlatformQuotaSetting{ + "anthropic": {DailyLimitUSD: &five}, + }, + } + if err := s.snapshotPlatformQuotaDefaults(context.Background(), 1, plan); err != nil { + t.Errorf("fail-open: expected nil even on repo error, got %v", err) + } +} + +func TestSnapshotPlatformQuotaDefaults_NilRepoIsNoop(t *testing.T) { + s := &AuthService{userPlatformQuotaRepo: nil} + five := 5.0 + plan := &signupGrantPlan{ + PlatformQuotas: map[string]*DefaultPlatformQuotaSetting{"a": {DailyLimitUSD: &five}}, + } + if err := s.snapshotPlatformQuotaDefaults(context.Background(), 1, plan); err != nil { + t.Errorf("nil repo should be noop, got %v", err) + } +} + +// resolveSignupGrantPlan 测试:依赖完整的 AuthService 构造,需要 SettingService(含 settingRepoStub)。 +// settingRepoStub 已在 auth_service_register_test.go 中定义,同 package 可直接使用。 +func TestResolveSignupGrantPlan_GlobalQuotaLoadedBeforeAuthSource(t *testing.T) { + // 全局 quota JSON key(新格式) + settings := map[string]string{ + SettingKeyRegistrationEnabled: "true", + SettingKeyDefaultPlatformQuotas: `{ + "anthropic": {"daily": 10, "weekly": 50, "monthly": 200}, + "openai": {"daily": 5, "weekly": 25, "monthly": 100}, + "gemini": {"daily": 5, "weekly": 25, "monthly": 100}, + "antigravity": {"daily": 5, "weekly": 25, "monthly": 100} + }`, + } + svc := newAuthService(nil, settings, nil, nil) + plan := svc.resolveSignupGrantPlan(context.Background(), "email") + if plan.PlatformQuotas == nil { + t.Fatal("expected PlatformQuotas to be non-nil after loading global quota KVs") + } + q := plan.PlatformQuotas["anthropic"] + if q == nil { + t.Fatal("expected anthropic quota to be set") + } + if q.DailyLimitUSD == nil || *q.DailyLimitUSD != 10 { + t.Errorf("expected anthropic daily=10, got %v", q.DailyLimitUSD) + } +} + +// TestResolveSignupGrantPlan_DisabledAuthSourceStillCarriesGlobalQuota 验证 P1 约束: +// !enabled 早退路径仍携带全局 quota(GetDefaultPlatformQuotas 在 ResolveAuthSourceGrantSettings 之前)。 +func TestResolveSignupGrantPlan_DisabledAuthSourceStillCarriesGlobalQuota(t *testing.T) { + settings := map[string]string{ + SettingKeyRegistrationEnabled: "true", + // auth source 不配置(=> !enabled 路径) + SettingKeyDefaultPlatformQuotas: `{"anthropic": {"daily": 10, "weekly": 50, "monthly": 200}}`, + } + svc := newAuthService(nil, settings, nil, nil) + plan := svc.resolveSignupGrantPlan(context.Background(), "email") + // !enabled 路径:plan.PlatformQuotas 应已含全局层(不是 nil) + if plan.PlatformQuotas == nil { + t.Fatal("P1 violated: PlatformQuotas is nil even with global quota KVs set") + } + // P1 核心断言:disabled auth source 路径不能丢失全局 quota + if _, ok := plan.PlatformQuotas["anthropic"]; !ok { + t.Error("P1 violated: disabled auth source path dropped global platform quota") + } +} diff --git a/backend/internal/service/auth_service_register_test.go b/backend/internal/service/auth_service_register_test.go index ece02474..a7c0d260 100644 --- a/backend/internal/service/auth_service_register_test.go +++ b/backend/internal/service/auth_service_register_test.go @@ -73,6 +73,38 @@ type defaultSubscriptionAssignerStub struct { type refreshTokenCacheStub struct{} +type userPlatformQuotaRepoStub struct { + bulkInsertCalls [][]UserPlatformQuotaRecord + bulkInsertErr error +} + +func (s *userPlatformQuotaRepoStub) BulkInsertInitial(_ context.Context, records []UserPlatformQuotaRecord) error { + cloned := make([]UserPlatformQuotaRecord, len(records)) + copy(cloned, records) + s.bulkInsertCalls = append(s.bulkInsertCalls, cloned) + return s.bulkInsertErr +} + +func (s *userPlatformQuotaRepoStub) GetByUserPlatform(context.Context, int64, string) (*UserPlatformQuotaRecord, error) { + panic("unexpected GetByUserPlatform call") +} + +func (s *userPlatformQuotaRepoStub) ListByUser(context.Context, int64) ([]UserPlatformQuotaRecord, error) { + panic("unexpected ListByUser call") +} + +func (s *userPlatformQuotaRepoStub) IncrementUsageWithReset(context.Context, int64, string, float64, time.Time) error { + panic("unexpected IncrementUsageWithReset call") +} + +func (s *userPlatformQuotaRepoStub) UpsertForUser(context.Context, int64, []UserPlatformQuotaRecord) error { + panic("unexpected UpsertForUser call") +} + +func (s *userPlatformQuotaRepoStub) ResetExpiredWindow(context.Context, int64, string, string, time.Time) error { + panic("unexpected ResetExpiredWindow call") +} + func (s *defaultSubscriptionAssignerStub) AssignOrExtendSubscription(_ context.Context, input *AssignSubscriptionInput) (*UserSubscription, bool, error) { if input != nil { s.calls = append(s.calls, *input) @@ -178,7 +210,7 @@ func (s *emailCacheStub) IncrNotifyCodeUserRate(ctx context.Context, userID int6 return 0, nil } -func newAuthService(repo *userRepoStub, settings map[string]string, emailCache EmailCache) *AuthService { +func newAuthService(repo *userRepoStub, settings map[string]string, emailCache EmailCache, quotaRepo UserPlatformQuotaRepository) *AuthService { cfg := &config.Config{ JWT: config.JWTConfig{ Secret: "test-secret", @@ -213,6 +245,7 @@ func newAuthService(repo *userRepoStub, settings map[string]string, emailCache E nil, // promoService nil, // defaultSubAssigner nil, // affiliateService + quotaRepo, ) } @@ -220,7 +253,7 @@ func TestAuthService_Register_Disabled(t *testing.T) { repo := &userRepoStub{} service := newAuthService(repo, map[string]string{ SettingKeyRegistrationEnabled: "false", - }, nil) + }, nil, nil) _, _, err := service.Register(context.Background(), "user@test.com", "password") require.ErrorIs(t, err, ErrRegDisabled) @@ -229,19 +262,62 @@ func TestAuthService_Register_Disabled(t *testing.T) { func TestAuthService_Register_DisabledByDefault(t *testing.T) { // 当 settings 为 nil(设置项不存在)时,注册应该默认关闭 repo := &userRepoStub{} - service := newAuthService(repo, nil, nil) + service := newAuthService(repo, nil, nil, nil) _, _, err := service.Register(context.Background(), "user@test.com", "password") require.ErrorIs(t, err, ErrRegDisabled) } +func TestAuthService_Register_SnapshotsPlatformQuotaDefaults(t *testing.T) { + repo := &userRepoStub{nextID: 77} + quotaRepo := &userPlatformQuotaRepoStub{} + + service := newAuthService(repo, map[string]string{ + SettingKeyRegistrationEnabled: "true", + SettingKeyDefaultPlatformQuotas: `{"openai": {"weekly": 12.34}}`, + }, nil, quotaRepo) + + _, user, err := service.Register(context.Background(), "newuser@test.com", "password") + require.NoError(t, err) + require.NotNil(t, user) + + require.Len(t, quotaRepo.bulkInsertCalls, 1) + + records := quotaRepo.bulkInsertCalls[0] + var openaiRecord *UserPlatformQuotaRecord + for i := range records { + if records[i].Platform == "openai" { + openaiRecord = &records[i] + break + } + } + require.NotNil(t, openaiRecord, "expected openai platform record") + require.Equal(t, int64(77), openaiRecord.UserID) + require.NotNil(t, openaiRecord.WeeklyLimitUSD) + require.InDelta(t, 12.34, *openaiRecord.WeeklyLimitUSD, 0.0001) +} + +func TestAuthService_Register_DoesNotSnapshotOnDisabled(t *testing.T) { + repo := &userRepoStub{} + quotaRepo := &userPlatformQuotaRepoStub{} + + service := newAuthService(repo, map[string]string{ + SettingKeyRegistrationEnabled: "false", + }, nil, quotaRepo) + + _, _, err := service.Register(context.Background(), "user@test.com", "password") + require.ErrorIs(t, err, ErrRegDisabled) + + require.Empty(t, quotaRepo.bulkInsertCalls, "registration rejected before user creation must not snapshot") +} + func TestAuthService_Register_EmailVerifyEnabledButServiceNotConfigured(t *testing.T) { repo := &userRepoStub{} // 邮件验证开启但 emailCache 为 nil(emailService 未配置) service := newAuthService(repo, map[string]string{ SettingKeyRegistrationEnabled: "true", SettingKeyEmailVerifyEnabled: "true", - }, nil) + }, nil, nil) // 应返回服务不可用错误,而不是允许绕过验证 _, _, err := service.RegisterWithVerification(context.Background(), "user@test.com", "password", "any-code", "", "", "") @@ -254,7 +330,7 @@ func TestAuthService_Register_EmailVerifyRequired(t *testing.T) { service := newAuthService(repo, map[string]string{ SettingKeyRegistrationEnabled: "true", SettingKeyEmailVerifyEnabled: "true", - }, cache) + }, cache, nil) _, _, err := service.RegisterWithVerification(context.Background(), "user@test.com", "password", "", "", "", "") require.ErrorIs(t, err, ErrEmailVerifyRequired) @@ -268,7 +344,7 @@ func TestAuthService_Register_EmailVerifyInvalid(t *testing.T) { service := newAuthService(repo, map[string]string{ SettingKeyRegistrationEnabled: "true", SettingKeyEmailVerifyEnabled: "true", - }, cache) + }, cache, nil) _, _, err := service.RegisterWithVerification(context.Background(), "user@test.com", "password", "wrong", "", "", "") require.ErrorIs(t, err, ErrInvalidVerifyCode) @@ -279,7 +355,7 @@ func TestAuthService_Register_EmailExists(t *testing.T) { repo := &userRepoStub{exists: true} service := newAuthService(repo, map[string]string{ SettingKeyRegistrationEnabled: "true", - }, nil) + }, nil, nil) _, _, err := service.Register(context.Background(), "user@test.com", "password") require.ErrorIs(t, err, ErrEmailExists) @@ -289,7 +365,7 @@ func TestAuthService_Register_CheckEmailError(t *testing.T) { repo := &userRepoStub{existsErr: errors.New("db down")} service := newAuthService(repo, map[string]string{ SettingKeyRegistrationEnabled: "true", - }, nil) + }, nil, nil) _, _, err := service.Register(context.Background(), "user@test.com", "password") require.ErrorIs(t, err, ErrServiceUnavailable) @@ -299,7 +375,7 @@ func TestAuthService_Register_ReservedEmail(t *testing.T) { repo := &userRepoStub{} service := newAuthService(repo, map[string]string{ SettingKeyRegistrationEnabled: "true", - }, nil) + }, nil, nil) _, _, err := service.Register(context.Background(), "linuxdo-123@linuxdo-connect.invalid", "password") require.ErrorIs(t, err, ErrEmailReserved) @@ -310,7 +386,7 @@ func TestAuthService_Register_EmailSuffixNotAllowed(t *testing.T) { service := newAuthService(repo, map[string]string{ SettingKeyRegistrationEnabled: "true", SettingKeyRegistrationEmailSuffixWhitelist: `["@example.com","@company.com"]`, - }, nil) + }, nil, nil) _, _, err := service.Register(context.Background(), "user@other.com", "password") require.ErrorIs(t, err, ErrEmailSuffixNotAllowed) @@ -327,7 +403,7 @@ func TestAuthService_Register_EmailSuffixAllowed(t *testing.T) { service := newAuthService(repo, map[string]string{ SettingKeyRegistrationEnabled: "true", SettingKeyRegistrationEmailSuffixWhitelist: `["example.com"]`, - }, nil) + }, nil, nil) _, user, err := service.Register(context.Background(), "user@example.com", "password") require.NoError(t, err) @@ -340,7 +416,7 @@ func TestAuthService_SendVerifyCode_EmailSuffixNotAllowed(t *testing.T) { service := newAuthService(repo, map[string]string{ SettingKeyRegistrationEnabled: "true", SettingKeyRegistrationEmailSuffixWhitelist: `["@example.com","@company.com"]`, - }, nil) + }, nil, nil) err := service.SendVerifyCode(context.Background(), "user@other.com") require.ErrorIs(t, err, ErrEmailSuffixNotAllowed) @@ -354,7 +430,7 @@ func TestAuthService_Register_CreateError(t *testing.T) { repo := &userRepoStub{createErr: errors.New("create failed")} service := newAuthService(repo, map[string]string{ SettingKeyRegistrationEnabled: "true", - }, nil) + }, nil, nil) _, _, err := service.Register(context.Background(), "user@test.com", "password") require.ErrorIs(t, err, ErrServiceUnavailable) @@ -365,7 +441,7 @@ func TestAuthService_Register_CreateEmailExistsRace(t *testing.T) { repo := &userRepoStub{createErr: ErrEmailExists} service := newAuthService(repo, map[string]string{ SettingKeyRegistrationEnabled: "true", - }, nil) + }, nil, nil) _, _, err := service.Register(context.Background(), "user@test.com", "password") require.ErrorIs(t, err, ErrEmailExists) @@ -376,7 +452,7 @@ func TestAuthService_Register_Success(t *testing.T) { service := newAuthService(repo, map[string]string{ SettingKeyRegistrationEnabled: "true", SettingKeyAuthSourceDefaultEmailGrantOnSignup: "false", - }, nil) + }, nil, nil) token, user, err := service.Register(context.Background(), "user@test.com", "password") require.NoError(t, err) @@ -394,7 +470,7 @@ func TestAuthService_Register_Success(t *testing.T) { func TestAuthService_ValidateToken_ExpiredReturnsClaimsWithError(t *testing.T) { repo := &userRepoStub{} - service := newAuthService(repo, nil, nil) + service := newAuthService(repo, nil, nil, nil) // 创建用户并生成 token user := &User{ @@ -436,7 +512,7 @@ func TestAuthService_RefreshToken_ExpiredTokenNoPanic(t *testing.T) { TokenVersion: 1, } repo := &userRepoStub{user: user} - service := newAuthService(repo, nil, nil) + service := newAuthService(repo, nil, nil, nil) // 创建过期 token service.cfg.JWT.ExpireHour = -1 @@ -453,7 +529,7 @@ func TestAuthService_RefreshToken_ExpiredTokenNoPanic(t *testing.T) { } func TestAuthService_GetAccessTokenExpiresIn_FallbackToExpireHour(t *testing.T) { - service := newAuthService(&userRepoStub{}, nil, nil) + service := newAuthService(&userRepoStub{}, nil, nil, nil) service.cfg.JWT.ExpireHour = 24 service.cfg.JWT.AccessTokenExpireMinutes = 0 @@ -461,7 +537,7 @@ func TestAuthService_GetAccessTokenExpiresIn_FallbackToExpireHour(t *testing.T) } func TestAuthService_GetAccessTokenExpiresIn_MinutesHasPriority(t *testing.T) { - service := newAuthService(&userRepoStub{}, nil, nil) + service := newAuthService(&userRepoStub{}, nil, nil, nil) service.cfg.JWT.ExpireHour = 24 service.cfg.JWT.AccessTokenExpireMinutes = 90 @@ -469,7 +545,7 @@ func TestAuthService_GetAccessTokenExpiresIn_MinutesHasPriority(t *testing.T) { } func TestAuthService_GenerateToken_UsesExpireHourWhenMinutesZero(t *testing.T) { - service := newAuthService(&userRepoStub{}, nil, nil) + service := newAuthService(&userRepoStub{}, nil, nil, nil) service.cfg.JWT.ExpireHour = 24 service.cfg.JWT.AccessTokenExpireMinutes = 0 @@ -494,7 +570,7 @@ func TestAuthService_GenerateToken_UsesExpireHourWhenMinutesZero(t *testing.T) { } func TestAuthService_GenerateToken_UsesMinutesWhenConfigured(t *testing.T) { - service := newAuthService(&userRepoStub{}, nil, nil) + service := newAuthService(&userRepoStub{}, nil, nil, nil) service.cfg.JWT.ExpireHour = 24 service.cfg.JWT.AccessTokenExpireMinutes = 90 @@ -525,7 +601,7 @@ func TestAuthService_Register_AssignsDefaultSubscriptions(t *testing.T) { SettingKeyRegistrationEnabled: "true", SettingKeyDefaultSubscriptions: `[{"group_id":11,"validity_days":30},{"group_id":12,"validity_days":7}]`, SettingKeyAuthSourceDefaultEmailGrantOnSignup: "false", - }, nil) + }, nil, nil) service.defaultSubAssigner = assigner _, user, err := service.Register(context.Background(), "default-sub@test.com", "password") @@ -549,7 +625,7 @@ func TestAuthService_Register_UsesEmailAuthSourceDefaultsWhenGrantEnabled(t *tes SettingKeyAuthSourceDefaultEmailConcurrency: "7", SettingKeyAuthSourceDefaultEmailSubscriptions: `[{"group_id":11,"validity_days":30}]`, SettingKeyAuthSourceDefaultEmailGrantOnSignup: "true", - }, nil) + }, nil, nil) service.defaultSubAssigner = assigner _, user, err := service.Register(context.Background(), "email-defaults@test.com", "password") @@ -572,7 +648,7 @@ func TestAuthService_Register_GrantOnSignupFalseFallsBackToGlobalDefaults(t *tes SettingKeyAuthSourceDefaultEmailConcurrency: "88", SettingKeyAuthSourceDefaultEmailSubscriptions: `[{"group_id":32,"validity_days":9}]`, SettingKeyAuthSourceDefaultEmailGrantOnSignup: "false", - }, nil) + }, nil, nil) service.defaultSubAssigner = assigner _, user, err := service.Register(context.Background(), "email-global@test.com", "password") @@ -595,7 +671,7 @@ func TestAuthService_Register_GrantOnSignupMergesSourceOverridesWithGlobalDefaul SettingKeyAuthSourceDefaultEmailConcurrency: "5", SettingKeyAuthSourceDefaultEmailSubscriptions: `[]`, SettingKeyAuthSourceDefaultEmailGrantOnSignup: "true", - }, nil) + }, nil, nil) service.defaultSubAssigner = assigner _, user, err := service.Register(context.Background(), "email-merged@test.com", "password") @@ -618,7 +694,7 @@ func TestAuthService_LoginOrRegisterOAuthWithTokenPair_UsesLinuxDoAuthSourceDefa SettingKeyAuthSourceDefaultLinuxDoConcurrency: "9", SettingKeyAuthSourceDefaultLinuxDoSubscriptions: `[{"group_id":22,"validity_days":14}]`, SettingKeyAuthSourceDefaultLinuxDoGrantOnSignup: "true", - }, nil) + }, nil, nil) service.defaultSubAssigner = assigner service.refreshTokenCache = &refreshTokenCacheStub{} @@ -654,7 +730,7 @@ func TestAuthService_LoginOrRegisterOAuthWithTokenPair_ExistingUserDoesNotGrantA SettingKeyAuthSourceDefaultLinuxDoConcurrency: "9", SettingKeyAuthSourceDefaultLinuxDoSubscriptions: `[{"group_id":22,"validity_days":14}]`, SettingKeyAuthSourceDefaultLinuxDoGrantOnSignup: "true", - }, nil) + }, nil, nil) service.defaultSubAssigner = assigner service.refreshTokenCache = &refreshTokenCacheStub{} @@ -677,7 +753,7 @@ func newAuthServiceWithDingTalkCfg(settings map[string]string, dtCfg config.Ding DingTalk: dtCfg, } settingService := NewSettingService(&settingRepoStub{values: settings}, cfg) - return NewAuthService(nil, nil, nil, nil, cfg, settingService, nil, nil, nil, nil, nil, nil) + return NewAuthService(nil, nil, nil, nil, cfg, settingService, nil, nil, nil, nil, nil, nil, nil) } // minDingTalkURLs 返回一个包含必填字段的基础 DingTalkConnectConfig(不设 Enabled/BypassRegistration/Policy)。 diff --git a/backend/internal/service/auth_service_turnstile_register_test.go b/backend/internal/service/auth_service_turnstile_register_test.go index 3512822f..ce99c44d 100644 --- a/backend/internal/service/auth_service_turnstile_register_test.go +++ b/backend/internal/service/auth_service_turnstile_register_test.go @@ -55,6 +55,7 @@ func newAuthServiceForRegisterTurnstileTest(settings map[string]string, verifier nil, // promoService nil, // defaultSubAssigner nil, // affiliateService + nil, // userPlatformQuotaRepo ) } diff --git a/backend/internal/service/billing_cache_service.go b/backend/internal/service/billing_cache_service.go index 050db55b..2b7c06ba 100644 --- a/backend/internal/service/billing_cache_service.go +++ b/backend/internal/service/billing_cache_service.go @@ -11,18 +11,31 @@ import ( "github.com/Wei-Shaw/sub2api/internal/config" infraerrors "github.com/Wei-Shaw/sub2api/internal/pkg/errors" "github.com/Wei-Shaw/sub2api/internal/pkg/logger" + "github.com/Wei-Shaw/sub2api/internal/pkg/timezone" "golang.org/x/sync/singleflight" ) // 错误定义 // 注:ErrInsufficientBalance在redeem_service.go中定义 // 注:ErrDailyLimitExceeded/ErrWeeklyLimitExceeded/ErrMonthlyLimitExceeded在subscription_service.go中定义 +// errBillingCacheUnavailable 内部哨兵:用于 quota 校验路径在 cache==nil 时 +// 与"Redis 故障"走同一条 fail-open + DB 一次性检查的分支。 +var errBillingCacheUnavailable = fmt.Errorf("billing cache unavailable") + var ( ErrSubscriptionInvalid = infraerrors.Forbidden("SUBSCRIPTION_INVALID", "subscription is invalid or expired") ErrBillingServiceUnavailable = infraerrors.ServiceUnavailable("BILLING_SERVICE_ERROR", "Billing service temporarily unavailable. Please retry later.") // RPM 超限错误。gateway_handler 负责映射为 HTTP 429。 ErrGroupRPMExceeded = infraerrors.TooManyRequests("GROUP_RPM_EXCEEDED", "group requests-per-minute limit exceeded") ErrUserRPMExceeded = infraerrors.TooManyRequests("USER_RPM_EXCEEDED", "user requests-per-minute limit exceeded") + + // user × platform quota(HTTP 429 Too Many Requests + Retry-After header)。 + // 选用 429 而非 403:限额耗尽属于"暂时性资源用尽,重试可恢复"的场景(RFC 6585), + // 大量 SDK(如 OpenAI 兼容客户端)只对 429 触发自动退避并读取 Retry-After, + // 用 403 会被视为"权限不足,重试无意义"导致客户端直接报错且不退避。 + ErrUserPlatformDailyQuotaExhausted = infraerrors.TooManyRequests("USER_PLATFORM_DAILY_QUOTA_EXHAUSTED", "Daily usage quota exhausted for this platform.") + ErrUserPlatformWeeklyQuotaExhausted = infraerrors.TooManyRequests("USER_PLATFORM_WEEKLY_QUOTA_EXHAUSTED", "Weekly usage quota exhausted for this platform.") + ErrUserPlatformMonthlyQuotaExhausted = infraerrors.TooManyRequests("USER_PLATFORM_MONTHLY_QUOTA_EXHAUSTED", "Monthly usage quota exhausted for this platform.") ) // subscriptionCacheData 订阅缓存数据结构(内部使用) @@ -94,6 +107,7 @@ type BillingCacheService struct { userGroupRateRepo UserGroupRateRepository cfg *config.Config circuitBreaker *billingCircuitBreaker + userPlatformQuotaRepo UserPlatformQuotaRepository cacheWriteChan chan cacheWriteTask cacheWriteWg sync.WaitGroup @@ -101,6 +115,7 @@ type BillingCacheService struct { cacheWriteMu sync.RWMutex stopped atomic.Bool balanceLoadSF singleflight.Group + quotaLoadSF singleflight.Group // 丢弃日志节流计数器(减少高负载下日志噪音) cacheWriteDropFullCount uint64 cacheWriteDropFullLastLog int64 @@ -117,6 +132,7 @@ func NewBillingCacheService( userRPMCache UserRPMCache, userGroupRateRepo UserGroupRateRepository, cfg *config.Config, + userPlatformQuotaRepo UserPlatformQuotaRepository, ) *BillingCacheService { svc := &BillingCacheService{ cache: cache, @@ -126,6 +142,7 @@ func NewBillingCacheService( userRPMCache: userRPMCache, userGroupRateRepo: userGroupRateRepo, cfg: cfg, + userPlatformQuotaRepo: userPlatformQuotaRepo, } svc.circuitBreaker = newBillingCircuitBreaker(cfg.Billing.CircuitBreaker) svc.startCacheWriteWorkers() @@ -655,6 +672,30 @@ func (s *BillingCacheService) QueueUpdateAPIKeyRateLimitUsage(apiKeyID int64, co }) } +// IncrementUserPlatformQuotaUsage 同步累加 user × platform usage 到 Redis 缓存。 +// +// 设计:同步写入而非异步入队。同步写确保下次 preflight 立即看到最新 usage, +// 把 TOCTOU 超支窗口限制在并发 in-flight 请求数量内(而非随时间无限累积)。 +// 写延迟通常 < 1ms(本地 Redis),换取 quota 视图实时性的取舍合理。 +// +// Redis 写失败用 ALERT 级 log;DB 持久化由 caller 单独 goroutine 兜底(gateway_service.go)。 +func (s *BillingCacheService) IncrementUserPlatformQuotaUsage(userID int64, platform string, cost float64) { + if s.cache == nil { + return + } + if platform == "" || cost <= 0 { + return + } + ctx, cancel := context.WithTimeout(context.Background(), cacheWriteTimeout) + defer cancel() + ttl := time.Duration(s.cfg.Billing.UserPlatformQuotaCacheTTLSeconds) * time.Second + if err := s.cache.IncrUserPlatformQuotaUsageCache(ctx, userID, platform, cost, ttl); err != nil { + logger.LegacyPrintf("service.billing_cache", + "ALERT: incr user platform quota cache failed user=%d platform=%s cost=%f: %v", + userID, platform, cost, err) + } +} + // ============================================ // 统一检查方法 // ============================================ @@ -662,7 +703,8 @@ func (s *BillingCacheService) QueueUpdateAPIKeyRateLimitUsage(apiKeyID int64, co // CheckBillingEligibility 检查用户是否有资格发起请求 // 余额模式:检查缓存余额 > 0 // 订阅模式:检查缓存用量未超过限额(Group限额从参数传入) -func (s *BillingCacheService) CheckBillingEligibility(ctx context.Context, user *User, apiKey *APIKey, group *Group, subscription *UserSubscription) error { +// platform 为请求的目标平台(如 "anthropic"),传空串 "" 时跳过 user × platform quota 检查。 +func (s *BillingCacheService) CheckBillingEligibility(ctx context.Context, user *User, apiKey *APIKey, group *Group, subscription *UserSubscription, platform string) error { // 简易模式:跳过所有计费检查 if s.cfg.RunMode == config.RunModeSimple { return nil @@ -684,6 +726,13 @@ func (s *BillingCacheService) CheckBillingEligibility(ctx context.Context, user } } + // user × platform quota 仅在 standard(余额)模式生效;订阅模式豁免 + if !isSubscriptionMode { + if err := s.checkUserPlatformQuotaEligibility(ctx, user.ID, platform); err != nil { + return err + } + } + // Check API Key rate limits (applies to both billing modes) if apiKey != nil && apiKey.HasRateLimits() { if err := s.checkAPIKeyRateLimits(ctx, apiKey); err != nil { @@ -975,3 +1024,257 @@ func circuitStateString(state billingCircuitBreakerState) string { return "unknown" } } + +// checkUserPlatformQuotaEligibility 在 standard 模式下检查 user × platform 日/周/月 quota。 +// 返回 nil = 允许;返回 ErrUserPlatform{Daily/Weekly/Monthly}QuotaExhausted = 拒绝(带 window_resets_at metadata)。 +// checkUserPlatformQuotaEligibility 检查用户在指定平台的 USD 配额。 +// +// 流程(Redis-first / DB-fallback): +// 1. 先读 Redis cache;若命中且 SchemaVersion==1,直接用 entry 中的 limits 和 window_start 做校验, +// 免除 DB 查询。 +// 2. cache MISS 或旧版 entry(SchemaVersion==0)→ 查 DB 回填完整 entry(含 limits/window_start)。 +// 3. Redis 故障(err != nil)→ fail-open,查 DB 做一次性检查,不回填。 +func (s *BillingCacheService) checkUserPlatformQuotaEligibility( + ctx context.Context, + userID int64, + platform string, +) error { + if platform == "" || s.userPlatformQuotaRepo == nil { + return nil + } + + // cache 未配置(如简化部署 / 单测路径)→ 直接走 DB 查询,避免 nil panic。 + // 其他 check* 方法(balance/subscription/rate-limit)也有类似守卫。 + var ( + entry *UserPlatformQuotaCacheEntry + ok bool + cacheErr error + ) + if s.cache != nil { + entry, ok, cacheErr = s.cache.GetUserPlatformQuotaCache(ctx, userID, platform) + } else { + // 标记为"cache 故障"分支:跳过 HIT 路径、不回填、走 DB 一次性检查 + cacheErr = errBillingCacheUnavailable + } + + // --- cache HIT with current schema → 直接用 entry,不查 DB --- + if cacheErr == nil && ok && entry != nil && entry.SchemaVersion == UserPlatformQuotaCacheSchemaV1 { + now := time.Now() + dailyUsage := entry.DailyUsageUSD + weeklyUsage := entry.WeeklyUsageUSD + monthlyUsage := entry.MonthlyUsageUSD + // 若窗口已更新(DB 已重置但 cache 尚未失效),将对应 usage 清零再做比较, + // 同时记录新窗口起点用于后续刷新 cache entry。 + // 本次请求用本地清零值继续判断;DB 层 IncrementUsageWithReset 已有窗口自愈能力, + // 持久化数据始终正确。 + windowExpired := false + newDailyStart := entry.DailyWindowStart + newWeeklyStart := entry.WeeklyWindowStart + newMonthlyStart := entry.MonthlyWindowStart + if quotaWindowExpired(entry.DailyWindowStart, timezone.StartOfDay(now)) { + dailyUsage = 0 + windowExpired = true + dayStart := timezone.StartOfDay(now) + newDailyStart = &dayStart + } + if quotaWindowExpired(entry.WeeklyWindowStart, timezone.StartOfWeek(now)) { + weeklyUsage = 0 + windowExpired = true + weekStart := timezone.StartOfWeek(now) + newWeeklyStart = &weekStart + } + if monthlyQuotaWindowExpired(entry.MonthlyWindowStart, now) { + monthlyUsage = 0 + windowExpired = true + monthStart := now + newMonthlyStart = &monthStart + } + // 检测到任意窗口过期:用 reset 后的 entry 覆盖 Redis(而非 Delete)。 + // 旧实现 Delete 后,期间到达的 IncrUserPlatformQuotaUsage 调用让 Lua 看到 + // EXISTS=0 直接 return 0,并发请求的 cost 永久丢失,直到下次 cache MISS 回填。 + // 改为 SetCache 原子覆盖:key 不断链,Lua INCR 可在新窗口 entry 上正确累加。 + // 超时 50ms:覆盖正常路径与可接受抖动;Redis 异常时 hot path 不阻塞超过此值。 + // 用 context.Background()+短超时,避免请求 ctx 取消导致刷新丢失。 + // 显式 setCancel()(而非 defer):缩短 context 生命周期,避免 defer 延迟到函数返回。 + if windowExpired && s.cache != nil { + refreshed := &UserPlatformQuotaCacheEntry{ + DailyUsageUSD: dailyUsage, + WeeklyUsageUSD: weeklyUsage, + MonthlyUsageUSD: monthlyUsage, + SchemaVersion: UserPlatformQuotaCacheSchemaV1, + DailyLimitUSD: entry.DailyLimitUSD, + WeeklyLimitUSD: entry.WeeklyLimitUSD, + MonthlyLimitUSD: entry.MonthlyLimitUSD, + DailyWindowStart: newDailyStart, + WeeklyWindowStart: newWeeklyStart, + MonthlyWindowStart: newMonthlyStart, + } + ttl := time.Duration(s.cfg.Billing.UserPlatformQuotaCacheTTLSeconds) * time.Second + setCtx, setCancel := context.WithTimeout(context.Background(), 50*time.Millisecond) + if setErr := s.cache.SetUserPlatformQuotaCache(setCtx, userID, platform, refreshed, ttl); setErr != nil { + logger.LegacyPrintf("service.billing_cache", + "Warning: refresh expired user platform quota cache failed user=%d platform=%s: %v", + userID, platform, setErr) + } + setCancel() + } + if entry.DailyLimitUSD != nil && dailyUsage >= *entry.DailyLimitUSD { + return withWindowResetsMetadata(ErrUserPlatformDailyQuotaExhausted, nextDailyReset(now)) + } + if entry.WeeklyLimitUSD != nil && weeklyUsage >= *entry.WeeklyLimitUSD { + return withWindowResetsMetadata(ErrUserPlatformWeeklyQuotaExhausted, nextWeeklyReset(now)) + } + if entry.MonthlyLimitUSD != nil && monthlyUsage >= *entry.MonthlyLimitUSD { + return withWindowResetsMetadata(ErrUserPlatformMonthlyQuotaExhausted, nextMonthlyResetFrom(entry.MonthlyWindowStart, now)) + } + return nil + } + + // --- cache MISS、旧版 entry 或 Redis 故障 → 查 DB(singleflight 合并并发回源)--- + // 使用 DoChan 而非 Do:avoid sharing the first caller's ctx among all dedupe followers. + // 若第一个 caller 的 ctx 被取消(客户端断连),后续 caller 不受影响,仍由各自 ctx 控制超时。 + sfKey := strconv.FormatInt(userID, 10) + ":" + platform + ch := s.quotaLoadSF.DoChan(sfKey, func() (any, error) { + // 子查询用 detached context + 短超时,独立于任何 caller 的请求 ctx, + // 防止"第一个 caller ctx 取消"使所有 follower 一起 fail。 + bgCtx, bgCancel := context.WithTimeout(context.Background(), 3*time.Second) + defer bgCancel() + return s.userPlatformQuotaRepo.GetByUserPlatform(bgCtx, userID, platform) + }) + var ( + v any + dbErr error + ) + select { + case res := <-ch: + v, dbErr = res.Val, res.Err + case <-ctx.Done(): + // 当前 caller 的 ctx 被取消:fail-open,不阻断 (此请求已无意义)。 + logger.LegacyPrintf("service.billing_cache", "Warning: user platform quota check ctx cancelled user=%d platform=%s: %v (fail-open)", userID, platform, ctx.Err()) + return nil + } + if dbErr != nil { + logger.LegacyPrintf("service.billing_cache", "Warning: load user platform quota failed user=%d platform=%s: %v (fail-open)", userID, platform, dbErr) + return nil + } + rec, _ := v.(*UserPlatformQuotaRecord) + if rec == nil { + return nil + } + + now := time.Now() + dailyUsage := rec.DailyUsageUSD + weeklyUsage := rec.WeeklyUsageUSD + monthlyUsage := rec.MonthlyUsageUSD + if quotaWindowExpired(rec.DailyWindowStart, timezone.StartOfDay(now)) { + dailyUsage = 0 + } + if quotaWindowExpired(rec.WeeklyWindowStart, timezone.StartOfWeek(now)) { + weeklyUsage = 0 + } + if monthlyQuotaWindowExpired(rec.MonthlyWindowStart, now) { + monthlyUsage = 0 + } + + // Redis 故障时 fail-open:不回填,直接用 DB 数据做一次性检查 + if cacheErr != nil { + if rec.DailyLimitUSD != nil && dailyUsage >= *rec.DailyLimitUSD { + return withWindowResetsMetadata(ErrUserPlatformDailyQuotaExhausted, nextDailyReset(now)) + } + if rec.WeeklyLimitUSD != nil && weeklyUsage >= *rec.WeeklyLimitUSD { + return withWindowResetsMetadata(ErrUserPlatformWeeklyQuotaExhausted, nextWeeklyReset(now)) + } + if rec.MonthlyLimitUSD != nil && monthlyUsage >= *rec.MonthlyLimitUSD { + return withWindowResetsMetadata(ErrUserPlatformMonthlyQuotaExhausted, nextMonthlyResetFrom(rec.MonthlyWindowStart, now)) + } + return nil + } + + // cache MISS 或旧版 entry → 回填完整 entry(含 limits 和 window_start) + newEntry := &UserPlatformQuotaCacheEntry{ + DailyUsageUSD: dailyUsage, + WeeklyUsageUSD: weeklyUsage, + MonthlyUsageUSD: monthlyUsage, + SchemaVersion: UserPlatformQuotaCacheSchemaV1, + DailyLimitUSD: rec.DailyLimitUSD, + WeeklyLimitUSD: rec.WeeklyLimitUSD, + MonthlyLimitUSD: rec.MonthlyLimitUSD, + DailyWindowStart: rec.DailyWindowStart, + WeeklyWindowStart: rec.WeeklyWindowStart, + MonthlyWindowStart: rec.MonthlyWindowStart, + } + if s.cache != nil { + ttl := time.Duration(s.cfg.Billing.UserPlatformQuotaCacheTTLSeconds) * time.Second + // 与 HIT 过期回填路径(上文 SetCache 调用)保持一致:用 context.Background()+50ms, + // 避免请求 ctx 提前取消(客户端断连/上游超时)导致 cache 回填失败, + // 让下一次 preflight 仍然 MISS 并击穿到 DB(高并发下增大 DB 压力)。 + setCtx, setCancel := context.WithTimeout(context.Background(), 50*time.Millisecond) + if setErr := s.cache.SetUserPlatformQuotaCache(setCtx, userID, platform, newEntry, ttl); setErr != nil { + logger.LegacyPrintf("service.billing_cache", "Warning: set user platform quota cache failed user=%d platform=%s: %v", userID, platform, setErr) + } + setCancel() + } + + if rec.DailyLimitUSD != nil && dailyUsage >= *rec.DailyLimitUSD { + return withWindowResetsMetadata(ErrUserPlatformDailyQuotaExhausted, nextDailyReset(now)) + } + if rec.WeeklyLimitUSD != nil && weeklyUsage >= *rec.WeeklyLimitUSD { + return withWindowResetsMetadata(ErrUserPlatformWeeklyQuotaExhausted, nextWeeklyReset(now)) + } + if rec.MonthlyLimitUSD != nil && monthlyUsage >= *rec.MonthlyLimitUSD { + return withWindowResetsMetadata(ErrUserPlatformMonthlyQuotaExhausted, nextMonthlyResetFrom(rec.MonthlyWindowStart, now)) + } + return nil +} + +// withWindowResetsMetadata 给 quota error 附加 window_resets_at metadata(RFC3339)。 +func withWindowResetsMetadata(err error, resetAt time.Time) error { + appErr, ok := err.(*infraerrors.ApplicationError) + if !ok || appErr == nil { + return err + } + return appErr.WithMetadata(map[string]string{ + "window_resets_at": resetAt.Format(time.RFC3339), + }) +} + +// nextDailyReset 计算下一个日窗口起点(次日全局时区 0 点)。 +// 必须与 timezone.StartOfDay 同口径,否则 Retry-After 会偏差。 +func nextDailyReset(now time.Time) time.Time { + return timezone.StartOfDay(now).AddDate(0, 0, 1) +} + +// nextWeeklyReset 计算下一个周窗口起点(下周一全局时区 0 点)。 +// 必须与 timezone.StartOfWeek 同口径,否则 Retry-After 会偏差。 +func nextWeeklyReset(now time.Time) time.Time { + return timezone.StartOfWeek(now).AddDate(0, 0, 7) +} + +// nextMonthlyResetFrom 返回 30 天滚动窗口的下次重置时间(start + 30d)。 +// start 为 nil(未初始化)或已过期(now-start >= 30d,与 monthlyQuotaWindowExpired 同口径)时 +// 退化为 now+30d:过期窗口会在下次 increment 时重置为 now,下次重置即 now+30d; +// 否则按 start 计算会得到一个过去的时间,使 Retry-After 落回 fallback 并触发客户端紧凑重试。 +func nextMonthlyResetFrom(start *time.Time, now time.Time) time.Time { + if start == nil || now.Sub(*start) >= 30*24*time.Hour { + return now.Add(30 * 24 * time.Hour) + } + return start.Add(30 * 24 * time.Hour) +} + +// quotaWindowExpired 判断窗口是否已过期:start 为 nil(未初始化)或在 currWindowStart 之前视为已过期。 +func quotaWindowExpired(start *time.Time, currWindowStart time.Time) bool { + if start == nil { + return true + } + return start.Before(currWindowStart) +} + +// monthlyQuotaWindowExpired 判断 30 天滚动月度窗口是否已过期。 +// 过期条件:now - start >= 30×24h(与订阅模式 NeedsMonthlyReset 语义一致)。 +// start 为 nil 时视为已过期(未初始化窗口)。 +func monthlyQuotaWindowExpired(start *time.Time, now time.Time) bool { + if start == nil { + return true + } + return now.Sub(*start) >= 30*24*time.Hour +} diff --git a/backend/internal/service/billing_cache_service_rpm_test.go b/backend/internal/service/billing_cache_service_rpm_test.go index de66136f..cb71b886 100644 --- a/backend/internal/service/billing_cache_service_rpm_test.go +++ b/backend/internal/service/billing_cache_service_rpm_test.go @@ -74,7 +74,7 @@ func newBillingServiceForRPM(t *testing.T, cache UserRPMCache, rateRepo UserGrou t.Helper() // 用 nil BillingCache 走 "无缓存" 分支,避免 CheckBillingEligibility 副作用。 // 我们只直接测 checkRPM。 - svc := NewBillingCacheService(nil, nil, nil, nil, cache, rateRepo, &config.Config{}) + svc := NewBillingCacheService(nil, nil, nil, nil, cache, rateRepo, &config.Config{}, nil) t.Cleanup(svc.Stop) return svc } diff --git a/backend/internal/service/billing_cache_service_singleflight_test.go b/backend/internal/service/billing_cache_service_singleflight_test.go index 962becf0..b443d97e 100644 --- a/backend/internal/service/billing_cache_service_singleflight_test.go +++ b/backend/internal/service/billing_cache_service_singleflight_test.go @@ -67,6 +67,22 @@ func (s *billingCacheMissStub) InvalidateAPIKeyRateLimit(ctx context.Context, ke return nil } +func (s *billingCacheMissStub) GetUserPlatformQuotaCache(ctx context.Context, userID int64, platform string) (*UserPlatformQuotaCacheEntry, bool, error) { + return nil, false, nil +} + +func (s *billingCacheMissStub) SetUserPlatformQuotaCache(ctx context.Context, userID int64, platform string, entry *UserPlatformQuotaCacheEntry, ttl time.Duration) error { + return nil +} + +func (s *billingCacheMissStub) DeleteUserPlatformQuotaCache(ctx context.Context, userID int64, platform string) error { + return nil +} + +func (s *billingCacheMissStub) IncrUserPlatformQuotaUsageCache(ctx context.Context, userID int64, platform string, cost float64, ttl time.Duration) error { + return nil +} + type balanceLoadUserRepoStub struct { mockUserRepo calls atomic.Int64 @@ -100,7 +116,7 @@ func TestBillingCacheServiceGetUserBalance_Singleflight(t *testing.T) { delay: 80 * time.Millisecond, balance: 12.34, } - svc := NewBillingCacheService(cache, userRepo, nil, nil, nil, nil, &config.Config{}) + svc := NewBillingCacheService(cache, userRepo, nil, nil, nil, nil, &config.Config{}, nil) t.Cleanup(svc.Stop) const goroutines = 16 diff --git a/backend/internal/service/billing_cache_service_test.go b/backend/internal/service/billing_cache_service_test.go index 849e24b8..bcd086fa 100644 --- a/backend/internal/service/billing_cache_service_test.go +++ b/backend/internal/service/billing_cache_service_test.go @@ -68,9 +68,25 @@ func (b *billingCacheWorkerStub) InvalidateAPIKeyRateLimit(ctx context.Context, return nil } +func (b *billingCacheWorkerStub) GetUserPlatformQuotaCache(ctx context.Context, userID int64, platform string) (*UserPlatformQuotaCacheEntry, bool, error) { + return nil, false, nil +} + +func (b *billingCacheWorkerStub) SetUserPlatformQuotaCache(ctx context.Context, userID int64, platform string, entry *UserPlatformQuotaCacheEntry, ttl time.Duration) error { + return nil +} + +func (b *billingCacheWorkerStub) DeleteUserPlatformQuotaCache(ctx context.Context, userID int64, platform string) error { + return nil +} + +func (b *billingCacheWorkerStub) IncrUserPlatformQuotaUsageCache(ctx context.Context, userID int64, platform string, cost float64, ttl time.Duration) error { + return nil +} + func TestBillingCacheServiceQueueHighLoad(t *testing.T) { cache := &billingCacheWorkerStub{} - svc := NewBillingCacheService(cache, nil, nil, nil, nil, nil, &config.Config{}) + svc := NewBillingCacheService(cache, nil, nil, nil, nil, nil, &config.Config{}, nil) t.Cleanup(svc.Stop) start := time.Now() @@ -92,7 +108,7 @@ func TestBillingCacheServiceQueueHighLoad(t *testing.T) { func TestBillingCacheServiceEnqueueAfterStopReturnsFalse(t *testing.T) { cache := &billingCacheWorkerStub{} - svc := NewBillingCacheService(cache, nil, nil, nil, nil, nil, &config.Config{}) + svc := NewBillingCacheService(cache, nil, nil, nil, nil, nil, &config.Config{}, nil) svc.Stop() enqueued := svc.enqueueCacheWrite(cacheWriteTask{ diff --git a/backend/internal/service/billing_cache_service_user_platform_quota_test.go b/backend/internal/service/billing_cache_service_user_platform_quota_test.go new file mode 100644 index 00000000..57697ddb --- /dev/null +++ b/backend/internal/service/billing_cache_service_user_platform_quota_test.go @@ -0,0 +1,595 @@ +//go:build unit + +package service + +import ( + "context" + "errors" + "sync" + "testing" + "time" + + "github.com/Wei-Shaw/sub2api/internal/config" + "github.com/Wei-Shaw/sub2api/internal/pkg/timezone" +) + +// fakeIncrCache 仅记录 IncrUserPlatformQuotaUsageCache 被调用的参数。 +type fakeIncrCache struct { + BillingCache + calls []incrCall +} + +type incrCall struct { + userID int64 + platform string + cost float64 + ttl time.Duration +} + +func (f *fakeIncrCache) IncrUserPlatformQuotaUsageCache(ctx context.Context, userID int64, platform string, cost float64, ttl time.Duration) error { + f.calls = append(f.calls, incrCall{userID, platform, cost, ttl}) + return nil +} + +// IncrementUserPlatformQuotaUsage 已改为同步直写,不再走 worker。 +// 测试验证:同步调用立即调到 cache.IncrUserPlatformQuotaUsageCache。 +func TestIncrementUserPlatformQuotaUsage_SyncCallsCache(t *testing.T) { + fake := &fakeIncrCache{} + cfg := &config.Config{} + cfg.Billing.UserPlatformQuotaCacheTTLSeconds = 120 + + s := &BillingCacheService{ + cache: fake, + cfg: cfg, + } + + s.IncrementUserPlatformQuotaUsage(101, "anthropic", 0.25) + s.IncrementUserPlatformQuotaUsage(101, "openai", 0.50) + + if len(fake.calls) != 2 { + t.Fatalf("expected 2 incr calls, got %d", len(fake.calls)) + } + if fake.calls[0] != (incrCall{101, "anthropic", 0.25, 120 * time.Second}) { + t.Errorf("call[0] = %+v", fake.calls[0]) + } + if fake.calls[1] != (incrCall{101, "openai", 0.50, 120 * time.Second}) { + t.Errorf("call[1] = %+v", fake.calls[1]) + } +} + +// ── T6 tests: checkUserPlatformQuotaEligibility ────────────────────────────── + +// fakeQuotaRepo 实现 UserPlatformQuotaRepository 最小子集 +type fakeQuotaRepo struct { + rec *UserPlatformQuotaRecord +} + +func (f *fakeQuotaRepo) GetByUserPlatform(_ context.Context, _ int64, _ string) (*UserPlatformQuotaRecord, error) { + return f.rec, nil +} + +func (f *fakeQuotaRepo) BulkInsertInitial(_ context.Context, _ []UserPlatformQuotaRecord) error { + return nil +} + +func (f *fakeQuotaRepo) IncrementUsageWithReset(_ context.Context, _ int64, _ string, _ float64, _ time.Time) error { + return nil +} + +func (f *fakeQuotaRepo) ListByUser(_ context.Context, _ int64) ([]UserPlatformQuotaRecord, error) { + return nil, nil +} + +func (f *fakeQuotaRepo) UpsertForUser(_ context.Context, _ int64, _ []UserPlatformQuotaRecord) error { + return nil +} + +func (f *fakeQuotaRepo) ResetExpiredWindow(_ context.Context, _ int64, _ string, _ string, _ time.Time) error { + return nil +} + +// fakeFullCache 同时支持 Get + Set + Incr + Delete。 +// mu 保护 entry 和 deleteCalls,防止异步 goroutine 与主 goroutine 之间的 data race。 +type fakeFullCache struct { + BillingCache + mu sync.Mutex + entry *UserPlatformQuotaCacheEntry + deleteCalls int +} + +// getDeleteCalls 线程安全地读取 deleteCalls。 +func (f *fakeFullCache) getDeleteCalls() int { + f.mu.Lock() + defer f.mu.Unlock() + return f.deleteCalls +} + +// getEntry 线程安全地读取 entry。 +func (f *fakeFullCache) getEntry() *UserPlatformQuotaCacheEntry { + f.mu.Lock() + defer f.mu.Unlock() + return f.entry +} + +func (f *fakeFullCache) GetUserPlatformQuotaCache(_ context.Context, _ int64, _ string) (*UserPlatformQuotaCacheEntry, bool, error) { + f.mu.Lock() + defer f.mu.Unlock() + if f.entry == nil { + return nil, false, nil + } + return f.entry, true, nil +} + +func (f *fakeFullCache) SetUserPlatformQuotaCache(_ context.Context, _ int64, _ string, e *UserPlatformQuotaCacheEntry, _ time.Duration) error { + f.mu.Lock() + defer f.mu.Unlock() + f.entry = e + return nil +} + +func (f *fakeFullCache) DeleteUserPlatformQuotaCache(_ context.Context, _ int64, _ string) error { + f.mu.Lock() + defer f.mu.Unlock() + f.deleteCalls++ + f.entry = nil + return nil +} + +func newServiceForPreflight(t *testing.T, repo UserPlatformQuotaRepository, cache BillingCache) *BillingCacheService { + t.Helper() + cfg := &config.Config{} + cfg.Billing.UserPlatformQuotaCacheTTLSeconds = 60 + return &BillingCacheService{ + cache: cache, + cfg: cfg, + userPlatformQuotaRepo: repo, + } +} + +// currentDayStart 返回全局时区当天 0 点(与生产 timezone.StartOfDay 同口径,确保窗口有效)。 +func currentDayStart() *time.Time { + s := timezone.StartOfDay(time.Now()) + return &s +} + +func TestCheckUserPlatformQuotaEligibility_AllowsWhenUnderLimit(t *testing.T) { + daily := 10.0 + repo := &fakeQuotaRepo{rec: &UserPlatformQuotaRecord{ + UserID: 1, Platform: "anthropic", DailyLimitUSD: &daily, + }} + cache := &fakeFullCache{entry: &UserPlatformQuotaCacheEntry{ + DailyUsageUSD: 4.5, + DailyLimitUSD: &daily, + DailyWindowStart: currentDayStart(), + SchemaVersion: UserPlatformQuotaCacheSchemaV1, + }} + s := newServiceForPreflight(t, repo, cache) + if err := s.checkUserPlatformQuotaEligibility(context.Background(), 1, "anthropic"); err != nil { + t.Errorf("expected nil, got %v", err) + } +} + +func TestCheckUserPlatformQuotaEligibility_DailyExhausted(t *testing.T) { + daily := 5.0 + repo := &fakeQuotaRepo{rec: &UserPlatformQuotaRecord{ + UserID: 1, Platform: "anthropic", DailyLimitUSD: &daily, + }} + cache := &fakeFullCache{entry: &UserPlatformQuotaCacheEntry{ + DailyUsageUSD: 5.0, + DailyLimitUSD: &daily, + DailyWindowStart: currentDayStart(), + SchemaVersion: UserPlatformQuotaCacheSchemaV1, + }} + s := newServiceForPreflight(t, repo, cache) + err := s.checkUserPlatformQuotaEligibility(context.Background(), 1, "anthropic") + if !errors.Is(err, ErrUserPlatformDailyQuotaExhausted) { + t.Errorf("expected ErrUserPlatformDailyQuotaExhausted, got %v", err) + } +} + +func TestCheckUserPlatformQuotaEligibility_NilLimitMeansUnlimited(t *testing.T) { + repo := &fakeQuotaRepo{rec: &UserPlatformQuotaRecord{ + UserID: 1, Platform: "anthropic", + }} + cache := &fakeFullCache{entry: &UserPlatformQuotaCacheEntry{ + DailyUsageUSD: 999, + DailyWindowStart: currentDayStart(), + SchemaVersion: UserPlatformQuotaCacheSchemaV1, + // DailyLimitUSD nil → 无限额 + }} + s := newServiceForPreflight(t, repo, cache) + if err := s.checkUserPlatformQuotaEligibility(context.Background(), 1, "anthropic"); err != nil { + t.Errorf("nil limits should be unlimited, got %v", err) + } +} + +func TestCheckUserPlatformQuotaEligibility_ZeroLimitImmediateBlock(t *testing.T) { + zero := 0.0 + repo := &fakeQuotaRepo{rec: &UserPlatformQuotaRecord{ + UserID: 1, Platform: "anthropic", DailyLimitUSD: &zero, + }} + cache := &fakeFullCache{entry: &UserPlatformQuotaCacheEntry{ + DailyUsageUSD: 0, + DailyLimitUSD: &zero, + DailyWindowStart: currentDayStart(), + SchemaVersion: UserPlatformQuotaCacheSchemaV1, + }} + s := newServiceForPreflight(t, repo, cache) + err := s.checkUserPlatformQuotaEligibility(context.Background(), 1, "anthropic") + if !errors.Is(err, ErrUserPlatformDailyQuotaExhausted) { + t.Errorf("expected daily exhausted for limit=0, got %v", err) + } +} + +func TestCheckUserPlatformQuotaEligibility_NoRecordMeansUnlimited(t *testing.T) { + repo := &fakeQuotaRepo{rec: nil} + cache := &fakeFullCache{} + s := newServiceForPreflight(t, repo, cache) + if err := s.checkUserPlatformQuotaEligibility(context.Background(), 1, "anthropic"); err != nil { + t.Errorf("no record = unlimited, got %v", err) + } +} + +// TestCheckUserPlatformQuotaEligibility_OldSchemaCacheMissTriggersDB 验证旧版 entry(SchemaVersion=0) +// 触发 DB 回退路径,并在 DB 数据判断配额是否超限。 +// DB record 需设置有效的 window_start,否则 quotaWindowExpired 会将 usage 归零(nil 窗口视为已过期)。 +func TestCheckUserPlatformQuotaEligibility_OldSchemaCacheMissTriggersDB(t *testing.T) { + daily := 5.0 + dayStart := currentDayStart() + repo := &fakeQuotaRepo{rec: &UserPlatformQuotaRecord{ + UserID: 1, Platform: "anthropic", DailyLimitUSD: &daily, DailyUsageUSD: 6.0, + DailyWindowStart: dayStart, + }} + // SchemaVersion=0(旧 entry),应走 DB 路径 + cache := &fakeFullCache{entry: &UserPlatformQuotaCacheEntry{DailyUsageUSD: 1.0}} + s := newServiceForPreflight(t, repo, cache) + err := s.checkUserPlatformQuotaEligibility(context.Background(), 1, "anthropic") + if !errors.Is(err, ErrUserPlatformDailyQuotaExhausted) { + t.Errorf("旧版 entry 应走 DB 路径并报 daily exhausted, got %v", err) + } +} + +// TestCheckUserPlatformQuotaEligibility_WindowExpiredInCache 验证 cache HIT 时若窗口已过期,usage 归零,用户放行。 +func TestCheckUserPlatformQuotaEligibility_WindowExpiredInCache(t *testing.T) { + daily := 5.0 + past := time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC) // 远古窗口起始,肯定已过期 + repo := &fakeQuotaRepo{rec: &UserPlatformQuotaRecord{ + UserID: 1, Platform: "anthropic", DailyLimitUSD: &daily, + }} + cache := &fakeFullCache{entry: &UserPlatformQuotaCacheEntry{ + DailyUsageUSD: 10.0, // 超限,但窗口已过期 + DailyLimitUSD: &daily, + DailyWindowStart: &past, + SchemaVersion: UserPlatformQuotaCacheSchemaV1, + }} + s := newServiceForPreflight(t, repo, cache) + err := s.checkUserPlatformQuotaEligibility(context.Background(), 1, "anthropic") + if err != nil { + t.Errorf("过期窗口应归零放行, got %v", err) + } +} + +// TestCheckUserPlatformQuotaEligibility_WindowExpiredRefreshesCache 验证: +// V1 HIT 路径检测到窗口过期时,用 reset 后的 entry 同步覆盖 Redis(而非 Delete): +// 1. 当前请求以本地清零值判断 → 放行 +// 2. cache entry 被替换为新 entry: usage 清零 + window_start 更新到当前窗口 +// limit 保留;这样并发 IncrUserPlatformQuotaUsage 的 Lua INCR 可正确累加到新窗口。 +func TestCheckUserPlatformQuotaEligibility_WindowExpiredRefreshesCache(t *testing.T) { + daily := 5.0 + // 远古窗口起始,确保 quotaWindowExpired 返回 true + past := time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC) + repo := &fakeQuotaRepo{rec: &UserPlatformQuotaRecord{ + UserID: 1, Platform: "anthropic", DailyLimitUSD: &daily, + }} + cache := &fakeFullCache{entry: &UserPlatformQuotaCacheEntry{ + DailyUsageUSD: 10.0, // 超限,但窗口已过期 → 应被本地清零后放行 + DailyLimitUSD: &daily, + DailyWindowStart: &past, + SchemaVersion: UserPlatformQuotaCacheSchemaV1, + }} + s := newServiceForPreflight(t, repo, cache) + + // 本次 check 应放行(本地清零后 usage=0 < limit=5) + err := s.checkUserPlatformQuotaEligibility(context.Background(), 1, "anthropic") + if err != nil { + t.Errorf("过期窗口应归零放行, got %v", err) + } + + // 验证 cache entry 已被刷新:usage 清零、limit 保留、window_start 更新到当前窗口 + refreshed := cache.getEntry() + if refreshed == nil { + t.Fatal("窗口过期后 cache entry 不应为 nil(应被 SetCache 覆盖,而非 Delete)") + } + if refreshed.DailyUsageUSD != 0 { + t.Errorf("刷新后 DailyUsageUSD = %v, want 0", refreshed.DailyUsageUSD) + } + if refreshed.DailyLimitUSD == nil || *refreshed.DailyLimitUSD != daily { + t.Errorf("刷新后 DailyLimitUSD = %v, want %v(保留)", refreshed.DailyLimitUSD, daily) + } + if refreshed.SchemaVersion != UserPlatformQuotaCacheSchemaV1 { + t.Errorf("刷新后 SchemaVersion = %d, want V1", refreshed.SchemaVersion) + } + if refreshed.DailyWindowStart == nil || refreshed.DailyWindowStart.Equal(past) { + t.Errorf("刷新后 DailyWindowStart = %v, 应更新到当前窗口而非保留 past=%v", refreshed.DailyWindowStart, past) + } +} + +// ── T5 tests: QueueUpdateUserPlatformQuotaUsage ─────────────────────────────── + +// ── C-NEW-1: monthlyQuotaWindowExpired 30 天滚动测试 ───────────────────────── + +func TestMonthlyQuotaWindowExpired_NilStart(t *testing.T) { + if !monthlyQuotaWindowExpired(nil, time.Now().UTC()) { + t.Error("nil start should be considered expired") + } +} + +func TestMonthlyQuotaWindowExpired_Expired(t *testing.T) { + start := time.Now().UTC().Add(-30 * 24 * time.Hour) + if !monthlyQuotaWindowExpired(&start, time.Now().UTC()) { + t.Error("start exactly 30 days ago should be expired") + } +} + +func TestMonthlyQuotaWindowExpired_Active(t *testing.T) { + start := time.Now().UTC().Add(-29 * 24 * time.Hour) + if monthlyQuotaWindowExpired(&start, time.Now().UTC()) { + t.Error("start 29 days ago should NOT be expired") + } +} + +// TestMonthlyQuotaWindowExpired_CrossMonthBoundary 验证跨自然月时 30 天未满不视为过期。 +func TestMonthlyQuotaWindowExpired_CrossMonthBoundary(t *testing.T) { + // 窗口起始 4 月 20 日;5 月 1 日只过了 11 天,不足 30 天 + start := time.Date(2026, 4, 20, 0, 0, 0, 0, time.UTC) + now := time.Date(2026, 5, 1, 0, 0, 0, 0, time.UTC) + if monthlyQuotaWindowExpired(&start, now) { + t.Error("11 days into window should NOT be expired (30-day rolling, not calendar month)") + } +} + +// TestNextMonthlyResetFrom 验证 30 天滚动重置时间计算。 +func TestNextMonthlyResetFrom_WithStart(t *testing.T) { + start := time.Date(2026, 5, 1, 10, 0, 0, 0, time.UTC) + want := start.Add(30 * 24 * time.Hour) + now := time.Date(2026, 5, 22, 0, 0, 0, 0, time.UTC) + got := nextMonthlyResetFrom(&start, now) + if !got.Equal(want) { + t.Errorf("nextMonthlyResetFrom = %v, want %v", got, want) + } +} + +func TestNextMonthlyResetFrom_NilStart(t *testing.T) { + now := time.Date(2026, 5, 22, 0, 0, 0, 0, time.UTC) + got := nextMonthlyResetFrom(nil, now) + want := now.Add(30 * 24 * time.Hour) + if !got.Equal(want) { + t.Errorf("nextMonthlyResetFrom(nil) = %v, want now+30d=%v", got, want) + } +} + +func TestNextMonthlyResetFrom_NilStart_NotEqualToNow(t *testing.T) { + now := time.Date(2026, 5, 22, 12, 0, 0, 0, time.UTC) + got := nextMonthlyResetFrom(nil, now) + want := now.Add(30 * 24 * time.Hour) + if !got.Equal(want) { + t.Errorf("nextMonthlyResetFrom(nil) = %v, want %v (now+30d)", got, want) + } + if got.Equal(now) { + t.Error("nextMonthlyResetFrom(nil) must not return now (should be now+30d)") + } +} + +// TestNextMonthlyResetFrom_ExpiredStart 验证窗口已过期(now-start >= 30d)时, +// 下次重置时间为 now+30d,而非 start+30d(后者已是过去时间,会让 Retry-After 落回 +// fallback 并触发客户端紧凑重试)。 +func TestNextMonthlyResetFrom_ExpiredStart(t *testing.T) { + start := time.Date(2026, 3, 1, 0, 0, 0, 0, time.UTC) + now := time.Date(2026, 5, 1, 0, 0, 0, 0, time.UTC) // 距 start 61 天,已过期 + got := nextMonthlyResetFrom(&start, now) + want := now.Add(30 * 24 * time.Hour) + if !got.Equal(want) { + t.Errorf("nextMonthlyResetFrom(expired) = %v, want now+30d=%v", got, want) + } + if !got.After(now) { + t.Error("expired window 的下次重置必须在 now 之后,不能是过去时间") + } +} + +func TestIncrementUserPlatformQuotaUsage_GuardsAgainstEmpty(t *testing.T) { + fake := &fakeIncrCache{} + cfg := &config.Config{} + cfg.Billing.UserPlatformQuotaCacheTTLSeconds = 60 + s := &BillingCacheService{ + cache: fake, + cfg: cfg, + } + + s.IncrementUserPlatformQuotaUsage(1, "", 0.5) // empty platform → noop + s.IncrementUserPlatformQuotaUsage(1, "openai", 0) // zero cost → noop + s.IncrementUserPlatformQuotaUsage(1, "openai", -0.1) // negative → noop + + if len(fake.calls) != 0 { + t.Errorf("expected 0 calls (all guarded), got %d", len(fake.calls)) + } +} + +// ── C-NEW-2: 订阅模式豁免 user×platform quota 检查 ────────────────────────── +// 通过直接调用 checkUserPlatformQuotaEligibility 验证: +// 1. standard 模式下 limit=0 → 拦截 +// 2. 订阅模式豁免通过 isSubscriptionMode 守卫体现 — 逻辑已在 CheckBillingEligibility 里加 !isSubscriptionMode 条件 +// 此处用单元测试直接验证底层 checkUserPlatformQuotaEligibility 的行为(quota 超限确实拦截), +// 而 subscription bypass 逻辑则在 CheckBillingEligibility 中通过条件判断保证,不绕过 sub eligibility 内部复杂依赖。 + +// fakeZeroQuotaCache 模拟 cache 命中且 daily limit=0(quota 耗尽)。 +type fakeZeroQuotaCache struct { + BillingCache + called bool +} + +func (f *fakeZeroQuotaCache) GetUserPlatformQuotaCache(_ context.Context, _ int64, _ string) (*UserPlatformQuotaCacheEntry, bool, error) { + f.called = true + daily := 0.0 + entry := &UserPlatformQuotaCacheEntry{ + DailyUsageUSD: 0, + DailyLimitUSD: &daily, + DailyWindowStart: func() *time.Time { t := time.Now().UTC(); return &t }(), + SchemaVersion: UserPlatformQuotaCacheSchemaV1, + } + return entry, true, nil +} + +func (f *fakeZeroQuotaCache) DeleteUserPlatformQuotaCache(_ context.Context, _ int64, _ string) error { + return nil +} + +// SetUserPlatformQuotaCache 在 weekly/monthly window_start 为 nil 时,checkUserPlatform... +// 会触发"窗口过期 → SetCache 刷新"分支。fake 用 noop 避免 panic。 +func (f *fakeZeroQuotaCache) SetUserPlatformQuotaCache(_ context.Context, _ int64, _ string, _ *UserPlatformQuotaCacheEntry, _ time.Duration) error { + return nil +} + +// GetSubscriptionCache 返回有效订阅(active、未过期、usage 远低于 limit), +// 用于支持 checkSubscriptionEligibility 通过,以便验证 quota 检查不被触发。 +func (f *fakeZeroQuotaCache) GetSubscriptionCache(_ context.Context, _ int64, _ int64) (*SubscriptionCacheData, error) { + return &SubscriptionCacheData{ + Status: SubscriptionStatusActive, + ExpiresAt: time.Now().Add(30 * 24 * time.Hour), + DailyUsage: 0, + WeeklyUsage: 0, + MonthlyUsage: 0, + }, nil +} + +func (f *fakeZeroQuotaCache) GetUserBalanceCache(_ context.Context, _ int64) (float64, bool, error) { + return 100.0, true, nil +} + +// TestCheckUserPlatformQuotaEligibility_StandardMode_BlocksWhenLimitZero 验证: +// standard 模式下 limit=0 的 platform quota 确实会被拦截(守卫底层逻辑正确)。 +func TestCheckUserPlatformQuotaEligibility_StandardMode_BlocksWhenLimitZero(t *testing.T) { + fake := &fakeZeroQuotaCache{} + cfg := &config.Config{} + cfg.Billing.UserPlatformQuotaCacheTTLSeconds = 60 + s := &BillingCacheService{ + cache: fake, + cfg: cfg, + userPlatformQuotaRepo: &fakeQuotaRepo{}, + } + err := s.checkUserPlatformQuotaEligibility(context.Background(), 1, "anthropic") + if !errors.Is(err, ErrUserPlatformDailyQuotaExhausted) { + t.Errorf("standard mode with limit=0 should return ErrUserPlatformDailyQuotaExhausted, got: %v", err) + } + if !fake.called { + t.Error("GetUserPlatformQuotaCache should have been called in standard mode") + } +} + +// TestCheckBillingEligibility_SubscriptionMode_BypassesPlatformQuota 验证(C-NEW-2): +// 订阅模式用户不受 user×platform quota 拦截,GetUserPlatformQuotaCache 不应被调用。 +func TestCheckBillingEligibility_SubscriptionMode_BypassesPlatformQuota(t *testing.T) { + fake := &fakeZeroQuotaCache{} // GetUserPlatformQuotaCache 返回 limit=0,若被调用则拦截 + cfg := &config.Config{} + cfg.Billing.UserPlatformQuotaCacheTTLSeconds = 60 + s := &BillingCacheService{ + cache: fake, + cfg: cfg, + userPlatformQuotaRepo: &fakeQuotaRepo{}, + } + + subGroup := &Group{ + ID: 10, + SubscriptionType: "subscription", + Status: "active", + // 无 DailyLimitUSD → checkSubscriptionEligibility 不会因超限失败 + } + sub := &UserSubscription{Status: "active"} + user := &User{ID: 42} + + err := s.CheckBillingEligibility(context.Background(), user, nil, subGroup, sub, "anthropic") + // 订阅模式下不应收到任何 user×platform quota 错误 + if errors.Is(err, ErrUserPlatformDailyQuotaExhausted) || + errors.Is(err, ErrUserPlatformWeeklyQuotaExhausted) || + errors.Is(err, ErrUserPlatformMonthlyQuotaExhausted) { + t.Errorf("subscription mode should bypass user×platform quota, got: %v", err) + } + // GetUserPlatformQuotaCache 不应被调用 + if fake.called { + t.Error("GetUserPlatformQuotaCache must NOT be called in subscription mode (C-NEW-2)") + } +} + +// TestCheckBillingEligibility_NonSubscriptionGroup_AppliesQuota 验证: +// 非订阅模式(group=nil)用户 platform quota 超限时被拦截,quota cache 被查询。 +func TestCheckBillingEligibility_NonSubscriptionGroup_AppliesQuota(t *testing.T) { + called := &fakeZeroQuotaCache{} + cfg := &config.Config{} + cfg.Billing.UserPlatformQuotaCacheTTLSeconds = 60 + s := &BillingCacheService{ + cache: called, + cfg: cfg, + userPlatformQuotaRepo: &fakeQuotaRepo{}, + } + err := s.checkUserPlatformQuotaEligibility(context.Background(), 99, "openai") + if !errors.Is(err, ErrUserPlatformDailyQuotaExhausted) { + t.Errorf("non-subscription mode quota check should block, got: %v", err) + } + if !called.called { + t.Error("GetUserPlatformQuotaCache should be consulted in non-subscription mode") + } +} + +// ── B-3: monthlyQuotaWindowExpired 30 天边界表驱动测试 ──────────────────────── +// 覆盖 4 个必须场景: +// 1. 恰好 30 天 → expired +// 2. 30*24h - 1ns → not expired +// 3. 跨月末(2024-02-28 → 2024-03-29T00:00:01Z)→ expired +// 4. 跨年(2024-12-15 → 2025-01-14T00:00:01Z)→ expired +// +// repo 层 monthlyMaybeReset 不可导出,通过 service 层 monthlyQuotaWindowExpired 间接覆盖。 +func TestMonthlyQuotaWindowExpired_BoundaryTable(t *testing.T) { + const thirtyDays = 30 * 24 * time.Hour + + cases := []struct { + name string + start time.Time + now time.Time + expired bool + }{ + { + name: "exactly 30 days → expired", + start: time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC), + now: time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC).Add(thirtyDays), + expired: true, + }, + { + name: "30d minus 1ns → not expired", + start: time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC), + now: time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC).Add(thirtyDays - 1), + expired: false, + }, + { + name: "cross month-end (Feb→Mar, 29d+1s) → expired", + start: time.Date(2024, 2, 28, 0, 0, 0, 0, time.UTC), + now: time.Date(2024, 3, 29, 0, 0, 1, 0, time.UTC), + expired: true, + }, + { + name: "cross year boundary (Dec→Jan, 30d+1s) → expired", + start: time.Date(2024, 12, 15, 0, 0, 0, 0, time.UTC), + now: time.Date(2025, 1, 14, 0, 0, 1, 0, time.UTC), + expired: true, + }, + } + + for _, tc := range cases { + tc := tc // capture range variable + t.Run(tc.name, func(t *testing.T) { + got := monthlyQuotaWindowExpired(&tc.start, tc.now) + if got != tc.expired { + t.Errorf("monthlyQuotaWindowExpired(start=%v, now=%v) = %v, want %v", + tc.start, tc.now, got, tc.expired) + } + }) + } +} diff --git a/backend/internal/service/billing_service.go b/backend/internal/service/billing_service.go index 47975c8c..373502cf 100644 --- a/backend/internal/service/billing_service.go +++ b/backend/internal/service/billing_service.go @@ -6,6 +6,7 @@ import ( "fmt" "log" "strings" + "time" "github.com/Wei-Shaw/sub2api/internal/config" ) @@ -20,6 +21,32 @@ type APIKeyRateLimitCacheData struct { Window7d int64 `json:"window_7d"` } +// UserPlatformQuotaCacheEntry Redis hash 反序列化结果。 +// +// SchemaVersion 用于向后兼容: +// - 0(旧 entry,无 SchemaVersion 字段)→ 视为 cache MISS,强制 refresh +// - 1(当前版本)→ 包含 limits 和 window_start,可免 DB 查询 +// +// limit 字段为 nil 表示"无限额"(DB 中对应列为 NULL)。 +const UserPlatformQuotaCacheSchemaV1 = int64(1) + +type UserPlatformQuotaCacheEntry struct { + DailyUsageUSD float64 + WeeklyUsageUSD float64 + MonthlyUsageUSD float64 + Version int64 + SchemaVersion int64 + + // 以下字段仅在 SchemaVersion >= 1 时有效 + DailyLimitUSD *float64 + WeeklyLimitUSD *float64 + MonthlyLimitUSD *float64 + + DailyWindowStart *time.Time + WeeklyWindowStart *time.Time + MonthlyWindowStart *time.Time +} + // BillingCache defines cache operations for billing service type BillingCache interface { // Balance operations @@ -39,6 +66,13 @@ type BillingCache interface { SetAPIKeyRateLimit(ctx context.Context, keyID int64, data *APIKeyRateLimitCacheData) error UpdateAPIKeyRateLimitUsage(ctx context.Context, keyID int64, cost float64) error InvalidateAPIKeyRateLimit(ctx context.Context, keyID int64) error + + // user × platform quota 缓存 + GetUserPlatformQuotaCache(ctx context.Context, userID int64, platform string) (*UserPlatformQuotaCacheEntry, bool, error) + SetUserPlatformQuotaCache(ctx context.Context, userID int64, platform string, entry *UserPlatformQuotaCacheEntry, ttl time.Duration) error + DeleteUserPlatformQuotaCache(ctx context.Context, userID int64, platform string) error + // IncrUserPlatformQuotaUsageCache 在缓存命中时累加用量;缓存未命中(key 不存在)静默返回 nil。 + IncrUserPlatformQuotaUsageCache(ctx context.Context, userID int64, platform string, cost float64, ttl time.Duration) error } // ModelPricing 模型价格配置(per-token价格,与LiteLLM格式一致) diff --git a/backend/internal/service/domain_constants.go b/backend/internal/service/domain_constants.go index c7fa425a..59c34eaa 100644 --- a/backend/internal/service/domain_constants.go +++ b/backend/internal/service/domain_constants.go @@ -1,6 +1,10 @@ package service -import "github.com/Wei-Shaw/sub2api/internal/domain" +import ( + "fmt" + + "github.com/Wei-Shaw/sub2api/internal/domain" +) // Status constants const ( @@ -39,6 +43,26 @@ const ( PlatformAntigravity = domain.PlatformAntigravity ) +// AllowedQuotaPlatforms 是允许设置 user × platform quota 的平台列表(单一权威来源)。 +// ent/schema/user_platform_quota.go 的 Validate 函数独立维护(构建期约束), +// 若新增平台需同步修改该 schema。 +var AllowedQuotaPlatforms = []string{ + PlatformAnthropic, + PlatformOpenAI, + PlatformGemini, + PlatformAntigravity, +} + +// IsAllowedQuotaPlatform 报告 s 是否为合法的 quota platform 标识。 +func IsAllowedQuotaPlatform(s string) bool { + for _, p := range AllowedQuotaPlatforms { + if p == s { + return true + } + } + return false +} + // Account type constants const ( AccountTypeOAuth = domain.AccountTypeOAuth // OAuth类型账号(full scope: profile + inference) @@ -424,5 +448,15 @@ const ( SettingKeyWebSearchEmulationConfig = "web_search_emulation_config" // JSON 配置 ) +// SettingKeyDefaultPlatformQuotas —— 系统全局:每用户 × 平台日/周/月 USD 上限(JSON)。 +// 值为 map[platform]{daily,weekly,monthly},null/缺省 = 不限制;0 = 禁用;>0 = USD 上限。 +const SettingKeyDefaultPlatformQuotas = "default_platform_quotas" + +// SettingKeyAuthSourcePlatformQuotas 返回某 auth source 的 platform quota JSON key。 +// 形如 auth_source_default_{source}_platform_quotas +func SettingKeyAuthSourcePlatformQuotas(source string) string { + return fmt.Sprintf("auth_source_default_%s_platform_quotas", source) +} + // AdminAPIKeyPrefix is the prefix for admin API keys (distinct from user "sk-" keys). const AdminAPIKeyPrefix = "admin-" diff --git a/backend/internal/service/domain_constants_test.go b/backend/internal/service/domain_constants_test.go new file mode 100644 index 00000000..2157c979 --- /dev/null +++ b/backend/internal/service/domain_constants_test.go @@ -0,0 +1,23 @@ +//go:build unit + +package service + +import "testing" + +// TestSettingKeyDefaultPlatformQuotas 验证新的系统层 JSON key 常量值正确。 +func TestSettingKeyDefaultPlatformQuotas(t *testing.T) { + if SettingKeyDefaultPlatformQuotas != "default_platform_quotas" { + t.Errorf("SettingKeyDefaultPlatformQuotas = %q, want %q", + SettingKeyDefaultPlatformQuotas, "default_platform_quotas") + } +} + +// TestSettingKeyAuthSourcePlatformQuotas 验证新的 auth-source JSON key 函数返回值正确。 +func TestSettingKeyAuthSourcePlatformQuotas(t *testing.T) { + if got := SettingKeyAuthSourcePlatformQuotas("email"); got != "auth_source_default_email_platform_quotas" { + t.Fatalf("got %q, want %q", got, "auth_source_default_email_platform_quotas") + } + if got := SettingKeyAuthSourcePlatformQuotas("dingtalk"); got != "auth_source_default_dingtalk_platform_quotas" { + t.Fatalf("got %q, want %q", got, "auth_source_default_dingtalk_platform_quotas") + } +} diff --git a/backend/internal/service/gateway_record_usage_test.go b/backend/internal/service/gateway_record_usage_test.go index 09b07a5e..f8d98e55 100644 --- a/backend/internal/service/gateway_record_usage_test.go +++ b/backend/internal/service/gateway_record_usage_test.go @@ -44,6 +44,7 @@ func newGatewayRecordUsageServiceForTest(usageRepo UsageLogRepository, userRepo nil, nil, nil, + nil, // userPlatformQuotaRepo ) } diff --git a/backend/internal/service/gateway_service.go b/backend/internal/service/gateway_service.go index 1b1b9c5e..6106391b 100644 --- a/backend/internal/service/gateway_service.go +++ b/backend/internal/service/gateway_service.go @@ -95,6 +95,16 @@ var ( modelsListCacheHitTotal atomic.Int64 modelsListCacheMissTotal atomic.Int64 modelsListCacheStoreTotal atomic.Int64 + + // userPlatformQuotaDBIncrErrorTotal 统计 finalizePostUsageBilling 异步 goroutine + // 中 IncrementUsageWithReset 失败次数。Redis 已成功累加 + DB 写失败意味着 + // Redis cache TTL 过期或被清后该笔 cost 会丢失(与实际消费偏差)。 + // oncall 通过 GatewayUserPlatformQuotaIncrStats() 暴露给 ops 面板做阈值告警。 + userPlatformQuotaDBIncrErrorTotal atomic.Int64 + // userPlatformQuotaDBIncrLegacyErrorTotal 统计 legacy postUsageBilling + // (applyUsageBilling 在 repo==nil 时 fallback)路径下的失败次数; + // 与 DB Incr 失败分开计数,便于区分"主路径暂时故障"vs"基础设施长期未配齐"。 + userPlatformQuotaDBIncrLegacyErrorTotal atomic.Int64 ) func GatewayWindowCostPrefetchStats() (cacheHit, cacheMiss, batchSQL, fallback, errCount int64) { @@ -117,6 +127,15 @@ func GatewayModelsListCacheStats() (cacheHit, cacheMiss, store int64) { return modelsListCacheHitTotal.Load(), modelsListCacheMissTotal.Load(), modelsListCacheStoreTotal.Load() } +// GatewayUserPlatformQuotaIncrStats 返回 (mainPathErr, legacyPathErr)。 +// mainPathErr:finalizePostUsageBilling 异步 goroutine 写 DB 失败累计次数; +// legacyPathErr:postUsageBilling fallback 路径写 DB 失败累计次数。 +// ops 监控面板可以按"持续上升斜率"做告警阈值。 +func GatewayUserPlatformQuotaIncrStats() (mainPathErr, legacyPathErr int64) { + return userPlatformQuotaDBIncrErrorTotal.Load(), + userPlatformQuotaDBIncrLegacyErrorTotal.Load() +} + func openAIStreamEventIsTerminal(data string) bool { trimmed := strings.TrimSpace(data) if trimmed == "" { @@ -575,6 +594,7 @@ type GatewayService struct { debugGatewayBodyFile atomic.Pointer[os.File] // non-nil when SUB2API_DEBUG_GATEWAY_BODY is set tlsFPProfileService *TLSFingerprintProfileService balanceNotifyService *BalanceNotifyService + userPlatformQuotaRepo UserPlatformQuotaRepository } // NewGatewayService creates a new GatewayService @@ -605,41 +625,43 @@ func NewGatewayService( channelService *ChannelService, resolver *ModelPricingResolver, balanceNotifyService *BalanceNotifyService, + userPlatformQuotaRepo UserPlatformQuotaRepository, ) *GatewayService { userGroupRateTTL := resolveUserGroupRateCacheTTL(cfg) modelsListTTL := resolveModelsListCacheTTL(cfg) svc := &GatewayService{ - accountRepo: accountRepo, - groupRepo: groupRepo, - usageLogRepo: usageLogRepo, - usageBillingRepo: usageBillingRepo, - userRepo: userRepo, - userSubRepo: userSubRepo, - userGroupRateRepo: userGroupRateRepo, - cache: cache, - digestStore: digestStore, - cfg: cfg, - schedulerSnapshot: schedulerSnapshot, - concurrencyService: concurrencyService, - billingService: billingService, - rateLimitService: rateLimitService, - billingCacheService: billingCacheService, - identityService: identityService, - httpUpstream: httpUpstream, - deferredService: deferredService, - claudeTokenProvider: claudeTokenProvider, - sessionLimitCache: sessionLimitCache, - rpmCache: rpmCache, - userGroupRateCache: gocache.New(userGroupRateTTL, time.Minute), - settingService: settingService, - modelsListCache: gocache.New(modelsListTTL, time.Minute), - modelsListCacheTTL: modelsListTTL, - responseHeaderFilter: compileResponseHeaderFilter(cfg), - tlsFPProfileService: tlsFPProfileService, - channelService: channelService, - resolver: resolver, - balanceNotifyService: balanceNotifyService, + accountRepo: accountRepo, + groupRepo: groupRepo, + usageLogRepo: usageLogRepo, + usageBillingRepo: usageBillingRepo, + userRepo: userRepo, + userSubRepo: userSubRepo, + userGroupRateRepo: userGroupRateRepo, + cache: cache, + digestStore: digestStore, + cfg: cfg, + schedulerSnapshot: schedulerSnapshot, + concurrencyService: concurrencyService, + billingService: billingService, + rateLimitService: rateLimitService, + billingCacheService: billingCacheService, + identityService: identityService, + httpUpstream: httpUpstream, + deferredService: deferredService, + claudeTokenProvider: claudeTokenProvider, + sessionLimitCache: sessionLimitCache, + rpmCache: rpmCache, + userGroupRateCache: gocache.New(userGroupRateTTL, time.Minute), + settingService: settingService, + modelsListCache: gocache.New(modelsListTTL, time.Minute), + modelsListCacheTTL: modelsListTTL, + responseHeaderFilter: compileResponseHeaderFilter(cfg), + tlsFPProfileService: tlsFPProfileService, + channelService: channelService, + resolver: resolver, + balanceNotifyService: balanceNotifyService, + userPlatformQuotaRepo: userPlatformQuotaRepo, } svc.userGroupRateResolver = newUserGroupRateResolver( userGroupRateRepo, @@ -7949,6 +7971,7 @@ type RecordUsageInput struct { RequestPayloadHash string // 请求体语义哈希,用于降低 request_id 误复用时的静默误去重风险 ForceCacheBilling bool // 强制缓存计费:将 input_tokens 转为 cache_read 计费(用于粘性会话切换) APIKeyService APIKeyQuotaUpdater // 可选:用于更新API Key配额 + QuotaPlatform string // user×platform 配额计量平台:handler 在请求 ctx 内经 QuotaPlatform() 算定后传入(后扣运行在 worker 池 background ctx 上,取不到 ForcePlatform) ChannelUsageFields // 渠道映射信息(由 handler 在 Forward 前解析) } @@ -7978,6 +8001,31 @@ type postUsageBillingParams struct { IsSubscriptionBill bool AccountRateMultiplier float64 APIKeyService APIKeyQuotaUpdater + Platform string // 来自 APIKey 关联 Group 的平台标识 +} + +// PlatformFromAPIKey 从 APIKey 关联的 Group 推导 platform 名称。 +// apiKey 为 nil 或 Group 信息缺失时返回空串(调用方据此 short-circuit quota 累加)。 +// 导出供 handler 层调用。 +func PlatformFromAPIKey(apiKey *APIKey) string { + if apiKey == nil || apiKey.Group == nil { + return "" + } + return apiKey.Group.Platform +} + +// QuotaPlatform 返回 user×platform 配额计量使用的平台标识。 +// 强制平台路由(如 /antigravity)优先按 ctx 中的 ForcePlatform 计量,否则回退到 +// APIKey 关联 Group 的平台。 +// +// 注意:必须用带 ForcePlatform 的请求 context 调用(如 handler 的 c.Request.Context())。 +// 后扣运行在 worker 池的 background ctx 上没有 ForcePlatform,因此后扣平台由 handler +// 预先算定、经 RecordUsageInput.QuotaPlatform 传入,不要在后扣链路用 worker ctx 调用本函数。 +func QuotaPlatform(ctx context.Context, apiKey *APIKey) string { + if fp, ok := ctx.Value(ctxkey.ForcePlatform).(string); ok && fp != "" { + return fp + } + return PlatformFromAPIKey(apiKey) } func (p *postUsageBillingParams) shouldDeductAPIKeyQuota() bool { @@ -8036,6 +8084,21 @@ func postUsageBilling(ctx context.Context, p *postUsageBillingParams, deps *bill } } + // Platform quota DB-only 累加(与 finalizePostUsageBilling 行为对齐的兜底): + // - 仅对 standard(余额)模式生效;订阅模式豁免 + // - 直接走 DB,不经 Redis Incr 队列:legacy 路径在 repo==nil(仓库未注入) + // 时被触发,此时整套 billing repo 都不可用,没有"双队列"风险 + // - 失败仅记 ALERT log + counter,不阻断主扣费流程;与正常路径一致 + // + // 历史背景:原 legacy path 完全跳过此累加,导致部署中如果 repo 偶然为 nil + // 时用户消费可绕过 platform quota,存在静默资金风险。 + if !p.IsSubscriptionBill && p.Platform != "" && cost.ActualCost > 0 && p.User != nil && deps.userPlatformQuotaRepo != nil { + if err := deps.userPlatformQuotaRepo.IncrementUsageWithReset(billingCtx, p.User.ID, p.Platform, cost.ActualCost, time.Now().UTC()); err != nil { + userPlatformQuotaDBIncrLegacyErrorTotal.Add(1) + logger.LegacyPrintf("service.gateway", "ALERT: legacy incr user platform quota DB failed user=%d platform=%s cost=%f: %v", p.User.ID, p.Platform, cost.ActualCost, err) + } + } + // NOTE: finalizePostUsageBilling is NOT called here to avoid double-queuing // cache updates. The legacy path does DB writes directly; the finalize path // does cache queue + notifications. Notifications are dispatched separately @@ -8159,11 +8222,11 @@ func applyUsageBilling(ctx context.Context, requestID string, usageLog *UsageLog } } - finalizePostUsageBilling(p, deps, result) + finalizePostUsageBilling(billingCtx, p, deps, result) return true, nil } -func finalizePostUsageBilling(p *postUsageBillingParams, deps *billingDeps, result *UsageBillingApplyResult) { +func finalizePostUsageBilling(ctx context.Context, p *postUsageBillingParams, deps *billingDeps, result *UsageBillingApplyResult) { if p == nil || p.Cost == nil || deps == nil { return } @@ -8182,6 +8245,32 @@ func finalizePostUsageBilling(p *postUsageBillingParams, deps *billingDeps, resu deps.deferredService.ScheduleLastUsedUpdate(p.Account.ID) + // Platform quota 累加:仅在 standard(余额)模式生效;订阅模式豁免 + // Redis 同步写 + DB 异步持久化: + // - Redis 同步:确保下次 preflight 立即看到最新 usage,把 TOCTOU 超支窗口 + // 限制在并发 in-flight 请求数量内(旧实现的异步入队会让超支无限累积直到 worker 处理) + // - DB 异步:在独立 goroutine 中走 detached context,失败用 ALERT log 触发 oncall 对账 + if !p.IsSubscriptionBill && p.Platform != "" && p.Cost.ActualCost > 0 && p.User != nil && deps.userPlatformQuotaRepo != nil { + deps.billingCacheService.IncrementUserPlatformQuotaUsage(p.User.ID, p.Platform, p.Cost.ActualCost) + dbCtx, dbCancel := detachUpstreamContext(ctx) + userID, platform, cost := p.User.ID, p.Platform, p.Cost.ActualCost + go func() { + defer func() { + if r := recover(); r != nil { + logger.LegacyPrintf("service.gateway", "ALERT: panic in user platform quota incr goroutine user=%d platform=%s: %v", userID, platform, r) + } + }() + defer dbCancel() + if err := deps.userPlatformQuotaRepo.IncrementUsageWithReset(dbCtx, userID, platform, cost, time.Now().UTC()); err != nil { + // 失败计数器:暴露给 GatewayUserPlatformQuotaIncrStats(),由 ops 面板做斜率告警。 + userPlatformQuotaDBIncrErrorTotal.Add(1) + // ALERT 级别:DB 持久化失败意味着 Redis cache 失效后该笔 cost 永久丢失, + // 用户配额视图与实际消费会偏差,oncall 需要据此对账或人工补录。 + logger.LegacyPrintf("service.gateway", "ALERT: incr user platform quota DB failed user=%d platform=%s cost=%f: %v", userID, platform, cost, err) + } + }() + } + // Notification checks run async — all parameters are already captured, // no dependency on the request context or upstream connection. go notifyBalanceLow(p, deps, result) @@ -8287,22 +8376,24 @@ func detachUpstreamContext(ctx context.Context) (context.Context, context.Cancel // billingDeps 扣费逻辑依赖的服务(由各 gateway service 提供) type billingDeps struct { - accountRepo AccountRepository - userRepo UserRepository - userSubRepo UserSubscriptionRepository - billingCacheService *BillingCacheService - deferredService *DeferredService - balanceNotifyService *BalanceNotifyService + accountRepo AccountRepository + userRepo UserRepository + userSubRepo UserSubscriptionRepository + billingCacheService *BillingCacheService + deferredService *DeferredService + balanceNotifyService *BalanceNotifyService + userPlatformQuotaRepo UserPlatformQuotaRepository } func (s *GatewayService) billingDeps() *billingDeps { return &billingDeps{ - accountRepo: s.accountRepo, - userRepo: s.userRepo, - userSubRepo: s.userSubRepo, - billingCacheService: s.billingCacheService, - deferredService: s.deferredService, - balanceNotifyService: s.balanceNotifyService, + accountRepo: s.accountRepo, + userRepo: s.userRepo, + userSubRepo: s.userSubRepo, + billingCacheService: s.billingCacheService, + deferredService: s.deferredService, + balanceNotifyService: s.balanceNotifyService, + userPlatformQuotaRepo: s.userPlatformQuotaRepo, } } @@ -8360,6 +8451,7 @@ func (s *GatewayService) RecordUsage(ctx context.Context, input *RecordUsageInpu RequestPayloadHash: input.RequestPayloadHash, ForceCacheBilling: input.ForceCacheBilling, APIKeyService: input.APIKeyService, + QuotaPlatform: input.QuotaPlatform, ChannelUsageFields: input.ChannelUsageFields, }, &recordUsageOpts{ EnableClaudePath: true, @@ -8382,6 +8474,7 @@ type RecordUsageLongContextInput struct { LongContextMultiplier float64 // 超出阈值部分的倍率(如 2.0) ForceCacheBilling bool // 强制缓存计费:将 input_tokens 转为 cache_read 计费(用于粘性会话切换) APIKeyService APIKeyQuotaUpdater // API Key 配额服务(可选) + QuotaPlatform string // user×platform 配额计量平台:handler 在请求 ctx 内经 QuotaPlatform() 算定后传入(后扣运行在 worker 池 background ctx 上,取不到 ForcePlatform) ChannelUsageFields // 渠道映射信息(由 handler 在 Forward 前解析) } @@ -8401,6 +8494,7 @@ func (s *GatewayService) RecordUsageWithLongContext(ctx context.Context, input * RequestPayloadHash: input.RequestPayloadHash, ForceCacheBilling: input.ForceCacheBilling, APIKeyService: input.APIKeyService, + QuotaPlatform: input.QuotaPlatform, ChannelUsageFields: input.ChannelUsageFields, }, &recordUsageOpts{ LongContextThreshold: input.LongContextThreshold, @@ -8422,6 +8516,7 @@ type recordUsageCoreInput struct { RequestPayloadHash string ForceCacheBilling bool APIKeyService APIKeyQuotaUpdater + QuotaPlatform string ChannelUsageFields } @@ -8519,6 +8614,13 @@ func (s *GatewayService) recordUsageCore(ctx context.Context, input *recordUsage return nil } + // 配额平台由 handler 在请求 ctx 内经 QuotaPlatform() 算定并通过 input 传入; + // 后扣运行在 worker 池的 background ctx 上,无法再从 ctx 取 ForcePlatform。 + // 缺省(未设置)时回退到分组平台,保持对其它调用方的兼容。 + quotaPlatform := input.QuotaPlatform + if quotaPlatform == "" { + quotaPlatform = PlatformFromAPIKey(apiKey) + } requestID := usageLog.RequestID _, billingErr := applyUsageBilling(ctx, requestID, usageLog, &postUsageBillingParams{ Cost: cost, @@ -8530,6 +8632,7 @@ func (s *GatewayService) recordUsageCore(ctx context.Context, input *recordUsage IsSubscriptionBill: isSubscriptionBilling, AccountRateMultiplier: accountRateMultiplier, APIKeyService: input.APIKeyService, + Platform: quotaPlatform, }, s.billingDeps(), s.usageBillingRepo) if billingErr != nil { diff --git a/backend/internal/service/openai_gateway_record_usage_test.go b/backend/internal/service/openai_gateway_record_usage_test.go index 096f5b10..9769a82e 100644 --- a/backend/internal/service/openai_gateway_record_usage_test.go +++ b/backend/internal/service/openai_gateway_record_usage_test.go @@ -155,6 +155,7 @@ func newOpenAIRecordUsageServiceForTest(usageRepo UsageLogRepository, userRepo U nil, nil, nil, + nil, // userPlatformQuotaRepo ) svc.userGroupRateResolver = newUserGroupRateResolver( rateRepo, diff --git a/backend/internal/service/openai_gateway_service.go b/backend/internal/service/openai_gateway_service.go index f312f50d..2f81457f 100644 --- a/backend/internal/service/openai_gateway_service.go +++ b/backend/internal/service/openai_gateway_service.go @@ -343,6 +343,7 @@ type OpenAIGatewayService struct { channelService *ChannelService balanceNotifyService *BalanceNotifyService settingService *SettingService + userPlatformQuotaRepo UserPlatformQuotaRepository openaiWSPoolOnce sync.Once openaiWSStateStoreOnce sync.Once @@ -387,6 +388,7 @@ func NewOpenAIGatewayService( channelService *ChannelService, balanceNotifyService *BalanceNotifyService, settingService *SettingService, + userPlatformQuotaRepo UserPlatformQuotaRepository, ) *OpenAIGatewayService { svc := &OpenAIGatewayService{ accountRepo: accountRepo, @@ -418,6 +420,7 @@ func NewOpenAIGatewayService( channelService: channelService, balanceNotifyService: balanceNotifyService, settingService: settingService, + userPlatformQuotaRepo: userPlatformQuotaRepo, responseHeaderFilter: compileResponseHeaderFilter(cfg), codexSnapshotThrottle: newAccountWriteThrottle(openAICodexSnapshotPersistMinInterval), } @@ -523,12 +526,13 @@ func (s *OpenAIGatewayService) getCodexSnapshotThrottle() *accountWriteThrottle func (s *OpenAIGatewayService) billingDeps() *billingDeps { return &billingDeps{ - accountRepo: s.accountRepo, - userRepo: s.userRepo, - userSubRepo: s.userSubRepo, - billingCacheService: s.billingCacheService, - deferredService: s.deferredService, - balanceNotifyService: s.balanceNotifyService, + accountRepo: s.accountRepo, + userRepo: s.userRepo, + userSubRepo: s.userSubRepo, + billingCacheService: s.billingCacheService, + deferredService: s.deferredService, + balanceNotifyService: s.balanceNotifyService, + userPlatformQuotaRepo: s.userPlatformQuotaRepo, } } @@ -5634,6 +5638,7 @@ func (s *OpenAIGatewayService) RecordUsage(ctx context.Context, input *OpenAIRec IsSubscriptionBill: isSubscriptionBilling, AccountRateMultiplier: accountRateMultiplier, APIKeyService: input.APIKeyService, + Platform: PlatformFromAPIKey(apiKey), }, s.billingDeps(), s.usageBillingRepo) return err }() diff --git a/backend/internal/service/openai_ws_protocol_forward_test.go b/backend/internal/service/openai_ws_protocol_forward_test.go index f3936de1..99e92251 100644 --- a/backend/internal/service/openai_ws_protocol_forward_test.go +++ b/backend/internal/service/openai_ws_protocol_forward_test.go @@ -619,6 +619,7 @@ func TestNewOpenAIGatewayService_InitializesOpenAIWSResolver(t *testing.T) { nil, nil, nil, + nil, // userPlatformQuotaRepo ) decision := svc.getOpenAIWSProtocolResolver().Resolve(nil) diff --git a/backend/internal/service/post_billing_platform_test.go b/backend/internal/service/post_billing_platform_test.go new file mode 100644 index 00000000..a3ce0676 --- /dev/null +++ b/backend/internal/service/post_billing_platform_test.go @@ -0,0 +1,81 @@ +//go:build unit + +package service + +import ( + "context" + "testing" + + "github.com/Wei-Shaw/sub2api/internal/pkg/ctxkey" +) + +func TestPlatformFromAPIKey_NilSafe(t *testing.T) { + if got := PlatformFromAPIKey(nil); got != "" { + t.Errorf("nil APIKey should yield empty string, got %q", got) + } +} + +func TestPlatformFromAPIKey_NilGroup(t *testing.T) { + k := &APIKey{Group: nil} + if got := PlatformFromAPIKey(k); got != "" { + t.Errorf("APIKey with nil Group should yield empty string, got %q", got) + } +} + +func TestPlatformFromAPIKey_DerivesFromGroup(t *testing.T) { + tests := []struct { + name string + platform string + }{ + {"anthropic", "anthropic"}, + {"openai", "openai"}, + {"gemini", "gemini"}, + {"antigravity", "antigravity"}, + {"empty", ""}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + k := &APIKey{ + Group: &Group{Platform: tt.platform}, + } + got := PlatformFromAPIKey(k) + if got != tt.platform { + t.Errorf("PlatformFromAPIKey(%q) = %q, want %q", tt.platform, got, tt.platform) + } + }) + } +} + +// TestQuotaPlatform 锁定配额计量口径:ForcePlatform 路由(如 /antigravity)按 ForcePlatform 计, +// 否则回退到 Group 平台。preflight 与 post-billing 共用此口径,保证一致。 +func TestQuotaPlatform(t *testing.T) { + apiKey := &APIKey{Group: &Group{Platform: PlatformAnthropic}} + + t.Run("no force platform falls back to group platform", func(t *testing.T) { + if got := QuotaPlatform(context.Background(), apiKey); got != PlatformAnthropic { + t.Errorf("QuotaPlatform without force = %q, want %q", got, PlatformAnthropic) + } + }) + + t.Run("force platform overrides group platform", func(t *testing.T) { + ctx := context.WithValue(context.Background(), ctxkey.ForcePlatform, PlatformAntigravity) + if got := QuotaPlatform(ctx, apiKey); got != PlatformAntigravity { + t.Errorf("QuotaPlatform with force = %q, want %q", got, PlatformAntigravity) + } + }) + + t.Run("empty force platform falls back to group platform", func(t *testing.T) { + ctx := context.WithValue(context.Background(), ctxkey.ForcePlatform, "") + if got := QuotaPlatform(ctx, apiKey); got != PlatformAnthropic { + t.Errorf("QuotaPlatform with empty force = %q, want %q", got, PlatformAnthropic) + } + }) + + t.Run("nil api key with force platform returns force platform", func(t *testing.T) { + ctx := context.WithValue(context.Background(), ctxkey.ForcePlatform, PlatformAntigravity) + if got := QuotaPlatform(ctx, nil); got != PlatformAntigravity { + t.Errorf("QuotaPlatform(nil) with force = %q, want %q", got, PlatformAntigravity) + } + }) +} diff --git a/backend/internal/service/setting_service.go b/backend/internal/service/setting_service.go index 5eef2c13..e6f0f2bc 100644 --- a/backend/internal/service/setting_service.go +++ b/backend/internal/service/setting_service.go @@ -165,12 +165,20 @@ type SettingService struct { openAICodexUASF singleflight.Group } +// DefaultPlatformQuotaSetting 单 platform 三档限额(nil = 沿用上层;0 = 显式禁用;>0 = 上限) +type DefaultPlatformQuotaSetting struct { + DailyLimitUSD *float64 `json:"daily"` + WeeklyLimitUSD *float64 `json:"weekly"` + MonthlyLimitUSD *float64 `json:"monthly"` +} + type ProviderDefaultGrantSettings struct { Balance float64 Concurrency int Subscriptions []DefaultSubscriptionSetting GrantOnSignup bool GrantOnFirstBind bool + PlatformQuotas map[string]*DefaultPlatformQuotaSetting // key = platform name } type AuthSourceDefaultSettings struct { @@ -185,62 +193,80 @@ type AuthSourceDefaultSettings struct { } type authSourceDefaultKeySet struct { + // source 是 auth source 标识(如 "email"、"github"),仅用于 parse 时 + // slog.Warn 诊断输出,不再参与 key 拼接(platformQuotas 字段已存完整 key)。 + source string balance string concurrency string subscriptions string grantOnSignup string grantOnFirstBind string + platformQuotas string // SettingKeyAuthSourcePlatformQuotas(source) } var ( emailAuthSourceDefaultKeys = authSourceDefaultKeySet{ + source: "email", balance: SettingKeyAuthSourceDefaultEmailBalance, concurrency: SettingKeyAuthSourceDefaultEmailConcurrency, subscriptions: SettingKeyAuthSourceDefaultEmailSubscriptions, grantOnSignup: SettingKeyAuthSourceDefaultEmailGrantOnSignup, grantOnFirstBind: SettingKeyAuthSourceDefaultEmailGrantOnFirstBind, + platformQuotas: SettingKeyAuthSourcePlatformQuotas("email"), } linuxDoAuthSourceDefaultKeys = authSourceDefaultKeySet{ + source: "linuxdo", balance: SettingKeyAuthSourceDefaultLinuxDoBalance, concurrency: SettingKeyAuthSourceDefaultLinuxDoConcurrency, subscriptions: SettingKeyAuthSourceDefaultLinuxDoSubscriptions, grantOnSignup: SettingKeyAuthSourceDefaultLinuxDoGrantOnSignup, grantOnFirstBind: SettingKeyAuthSourceDefaultLinuxDoGrantOnFirstBind, + platformQuotas: SettingKeyAuthSourcePlatformQuotas("linuxdo"), } oidcAuthSourceDefaultKeys = authSourceDefaultKeySet{ + source: "oidc", balance: SettingKeyAuthSourceDefaultOIDCBalance, concurrency: SettingKeyAuthSourceDefaultOIDCConcurrency, subscriptions: SettingKeyAuthSourceDefaultOIDCSubscriptions, grantOnSignup: SettingKeyAuthSourceDefaultOIDCGrantOnSignup, grantOnFirstBind: SettingKeyAuthSourceDefaultOIDCGrantOnFirstBind, + platformQuotas: SettingKeyAuthSourcePlatformQuotas("oidc"), } weChatAuthSourceDefaultKeys = authSourceDefaultKeySet{ + source: "wechat", balance: SettingKeyAuthSourceDefaultWeChatBalance, concurrency: SettingKeyAuthSourceDefaultWeChatConcurrency, subscriptions: SettingKeyAuthSourceDefaultWeChatSubscriptions, grantOnSignup: SettingKeyAuthSourceDefaultWeChatGrantOnSignup, grantOnFirstBind: SettingKeyAuthSourceDefaultWeChatGrantOnFirstBind, + platformQuotas: SettingKeyAuthSourcePlatformQuotas("wechat"), } gitHubAuthSourceDefaultKeys = authSourceDefaultKeySet{ + source: "github", balance: SettingKeyAuthSourceDefaultGitHubBalance, concurrency: SettingKeyAuthSourceDefaultGitHubConcurrency, subscriptions: SettingKeyAuthSourceDefaultGitHubSubscriptions, grantOnSignup: SettingKeyAuthSourceDefaultGitHubGrantOnSignup, grantOnFirstBind: SettingKeyAuthSourceDefaultGitHubGrantOnFirstBind, + platformQuotas: SettingKeyAuthSourcePlatformQuotas("github"), } googleAuthSourceDefaultKeys = authSourceDefaultKeySet{ + source: "google", balance: SettingKeyAuthSourceDefaultGoogleBalance, concurrency: SettingKeyAuthSourceDefaultGoogleConcurrency, subscriptions: SettingKeyAuthSourceDefaultGoogleSubscriptions, grantOnSignup: SettingKeyAuthSourceDefaultGoogleGrantOnSignup, grantOnFirstBind: SettingKeyAuthSourceDefaultGoogleGrantOnFirstBind, + platformQuotas: SettingKeyAuthSourcePlatformQuotas("google"), } dingTalkAuthSourceDefaultKeys = authSourceDefaultKeySet{ + source: "dingtalk", balance: SettingKeyAuthSourceDefaultDingTalkBalance, concurrency: SettingKeyAuthSourceDefaultDingTalkConcurrency, subscriptions: SettingKeyAuthSourceDefaultDingTalkSubscriptions, grantOnSignup: SettingKeyAuthSourceDefaultDingTalkGrantOnSignup, grantOnFirstBind: SettingKeyAuthSourceDefaultDingTalkGrantOnFirstBind, + platformQuotas: SettingKeyAuthSourcePlatformQuotas("dingtalk"), } ) @@ -1804,9 +1830,41 @@ func (s *SettingService) buildSystemSettingsUpdates(ctx context.Context, setting updates[SettingKeyAccountQuotaNotifyEnabled] = strconv.FormatBool(settings.AccountQuotaNotifyEnabled) updates[SettingKeyAccountQuotaNotifyEmails] = MarshalNotifyEmails(settings.AccountQuotaNotifyEmails) + // 系统全局 platform quota:整体替换语义(null/缺省 = 不限制)。 + if settings.DefaultPlatformQuotas != nil { + if err := validateDefaultPlatformQuotaMap(settings.DefaultPlatformQuotas); err != nil { + return nil, err + } + blob, err := json.Marshal(settings.DefaultPlatformQuotas) + if err != nil { + return nil, fmt.Errorf("marshal default platform quotas: %w", err) + } + updates[SettingKeyDefaultPlatformQuotas] = string(blob) + } + return updates, nil } +// validateDefaultPlatformQuotaMap 校验 platform quota map 的合法性: +// 平台名须在 AllowedQuotaPlatforms 白名单内,每个非 nil 上限须 finite 且 >= 0。 +// 系统层和 auth-source 层共用此 helper。 +func validateDefaultPlatformQuotaMap(m map[string]*DefaultPlatformQuotaSetting) error { + for platform, pq := range m { + if !IsAllowedQuotaPlatform(platform) { + return infraerrors.BadRequest("INVALID_DEFAULT_PLATFORM_QUOTA", fmt.Sprintf("unknown platform %q", platform)) + } + if pq == nil { + continue + } + for _, v := range []*float64{pq.DailyLimitUSD, pq.WeeklyLimitUSD, pq.MonthlyLimitUSD} { + if v != nil && (*v < 0 || math.IsNaN(*v) || math.IsInf(*v, 0)) { + return infraerrors.BadRequest("INVALID_DEFAULT_PLATFORM_QUOTA", "platform quota limit must be a finite non-negative number") + } + } + } + return nil +} + func (s *SettingService) buildAuthSourceDefaultUpdates(ctx context.Context, settings *AuthSourceDefaultSettings) (map[string]string, error) { if settings == nil { return nil, nil @@ -1826,6 +1884,26 @@ func (s *SettingService) buildAuthSourceDefaultUpdates(ctx context.Context, sett } } + // 校验各 auth source 的 platform quota map(改动 C:对等系统层校验) + for _, pgs := range []struct { + name string + pq map[string]*DefaultPlatformQuotaSetting + }{ + {"email", settings.Email.PlatformQuotas}, + {"linuxdo", settings.LinuxDo.PlatformQuotas}, + {"oidc", settings.OIDC.PlatformQuotas}, + {"wechat", settings.WeChat.PlatformQuotas}, + {"github", settings.GitHub.PlatformQuotas}, + {"google", settings.Google.PlatformQuotas}, + {"dingtalk", settings.DingTalk.PlatformQuotas}, + } { + if pgs.pq != nil { + if err := validateDefaultPlatformQuotaMap(pgs.pq); err != nil { + return nil, err + } + } + } + updates := make(map[string]string, 36) writeProviderDefaultGrantUpdates(updates, emailAuthSourceDefaultKeys, settings.Email) writeProviderDefaultGrantUpdates(updates, linuxDoAuthSourceDefaultKeys, settings.LinuxDo) @@ -2386,6 +2464,13 @@ func (s *SettingService) GetAuthSourceDefaultSettings(ctx context.Context) (*Aut SettingKeyAuthSourceDefaultDingTalkSubscriptions, SettingKeyAuthSourceDefaultDingTalkGrantOnSignup, SettingKeyAuthSourceDefaultDingTalkGrantOnFirstBind, + SettingKeyAuthSourcePlatformQuotas("email"), + SettingKeyAuthSourcePlatformQuotas("linuxdo"), + SettingKeyAuthSourcePlatformQuotas("oidc"), + SettingKeyAuthSourcePlatformQuotas("wechat"), + SettingKeyAuthSourcePlatformQuotas("github"), + SettingKeyAuthSourcePlatformQuotas("google"), + SettingKeyAuthSourcePlatformQuotas("dingtalk"), SettingKeyForceEmailOnThirdPartySignup, } @@ -3179,6 +3264,16 @@ func (s *SettingService) parseSettings(settings map[string]string) *SystemSettin result.AccountQuotaNotifyEmails = []NotifyEmailEntry{} } + // 系统层默认 platform quota(修复 Bug B:parseSettings 不填充导致回显恒为 nil) + if raw := settings[SettingKeyDefaultPlatformQuotas]; raw != "" { + parsed := map[string]*DefaultPlatformQuotaSetting{} + if err := json.Unmarshal([]byte(raw), &parsed); err != nil { + slog.Warn("[Setting] parseSettings: unmarshal default_platform_quotas failed", "error", err) + } else { + result.DefaultPlatformQuotas = parsed + } + } + return result } @@ -3271,6 +3366,15 @@ func parseProviderDefaultGrantSettings(settings map[string]string, keys authSour result.GrantOnFirstBind = raw == "true" } + if raw := settings[keys.platformQuotas]; raw != "" { + parsed := map[string]*DefaultPlatformQuotaSetting{} + if err := json.Unmarshal([]byte(raw), &parsed); err != nil { + slog.Warn("[Setting] parseProviderDefaultGrantSettings: unmarshal auth source platform quotas failed", "source", keys.source, "error", err) + } else { + result.PlatformQuotas = parsed + } + } + return result } @@ -3289,6 +3393,17 @@ func writeProviderDefaultGrantUpdates(updates map[string]string, keys authSource updates[keys.subscriptions] = string(raw) updates[keys.grantOnSignup] = strconv.FormatBool(settings.GrantOnSignup) updates[keys.grantOnFirstBind] = strconv.FormatBool(settings.GrantOnFirstBind) + + // auth source platform quota:整体替换语义。 + // nil = 请求未携带该字段,跳过写入以保留既有配置(与系统层 buildSystemSettingsUpdates 的 + // DefaultPlatformQuotas nil 守卫一致);非 nil(含空 map)才整体替换。二者语义不可混同。 + if keys.platformQuotas != "" && settings.PlatformQuotas != nil { + blob, err := json.Marshal(settings.PlatformQuotas) + if err != nil { + blob = []byte("{}") + } + updates[keys.platformQuotas] = string(blob) + } } func mergeProviderDefaultGrantSettings(globalDefaults ProviderDefaultGrantSettings, providerDefaults ProviderDefaultGrantSettings) ProviderDefaultGrantSettings { @@ -4493,3 +4608,63 @@ func (s *SettingService) SetStreamTimeoutSettings(ctx context.Context, settings return s.settingRepo.Set(ctx, SettingKeyStreamTimeoutSettings, string(data)) } + +// GetDefaultPlatformQuotas 读取系统全局 platform quota JSON key,返回 4 platform x 3 window 的设置。 +// 永远返回包含全部 4 platform key 的 map(值可能为零值/nil 字段,表示"上层未配置 = 不限制")。 +// +// 使用单个 JSON key(default_platform_quotas),一次 DB roundtrip,消除旧 12-KV 格式的 N+1 问题。 +// 容错语义:取值失败或 unmarshal 失败 → 返回补齐 4 key 的空 map(fail-open,注册不被阻断)。 +func (s *SettingService) GetDefaultPlatformQuotas(ctx context.Context) (map[string]*DefaultPlatformQuotaSetting, error) { + out := map[string]*DefaultPlatformQuotaSetting{ + "anthropic": {}, + "openai": {}, + "gemini": {}, + "antigravity": {}, + } + raw, err := s.settingRepo.GetValue(ctx, SettingKeyDefaultPlatformQuotas) + if err != nil || raw == "" { + return out, nil // 无配置 = 全部不限制 + } + parsed := map[string]*DefaultPlatformQuotaSetting{} + if err := json.Unmarshal([]byte(raw), &parsed); err != nil { + slog.Warn("[Setting] unmarshal default_platform_quotas failed (fail-open)", "error", err) + return out, nil + } + for _, platform := range AllowedQuotaPlatforms { + if v := parsed[platform]; v != nil { + out[platform] = v + } + } + return out, nil // 补齐 4 platform key,保持与旧实现一致的下游契约 +} + +// GetAuthSourcePlatformQuotas 读取指定 auth source 的 platform quota 覆盖(仅返回有配置的平台,override 语义)。 +func (s *SettingService) GetAuthSourcePlatformQuotas(ctx context.Context, source string) map[string]*DefaultPlatformQuotaSetting { + out := map[string]*DefaultPlatformQuotaSetting{} + raw, err := s.settingRepo.GetValue(ctx, SettingKeyAuthSourcePlatformQuotas(source)) + if err != nil || raw == "" { + return out // 无 override + } + if err := json.Unmarshal([]byte(raw), &out); err != nil { + slog.Warn("[Setting] unmarshal auth source platform quotas failed (fail-open)", "source", source, "error", err) + return map[string]*DefaultPlatformQuotaSetting{} + } + return out // 仅含已配置平台,保持 override 语义 +} + +// mergePlatformQuotaDefaults 按字段级 patch:src 中非 nil 字段覆盖 dst。 +// 区分 nil("未配置",保留 dst)vs &0.0("显式禁用",覆盖 dst 为 0) +func mergePlatformQuotaDefaults(dst, src *DefaultPlatformQuotaSetting) { + if src == nil || dst == nil { + return + } + if src.DailyLimitUSD != nil { + dst.DailyLimitUSD = src.DailyLimitUSD + } + if src.WeeklyLimitUSD != nil { + dst.WeeklyLimitUSD = src.WeeklyLimitUSD + } + if src.MonthlyLimitUSD != nil { + dst.MonthlyLimitUSD = src.MonthlyLimitUSD + } +} diff --git a/backend/internal/service/setting_service_platform_quota_test.go b/backend/internal/service/setting_service_platform_quota_test.go new file mode 100644 index 00000000..557cc5f1 --- /dev/null +++ b/backend/internal/service/setting_service_platform_quota_test.go @@ -0,0 +1,344 @@ +//go:build unit + +package service + +import ( + "context" + "testing" + + "github.com/Wei-Shaw/sub2api/internal/config" + infraerrors "github.com/Wei-Shaw/sub2api/internal/pkg/errors" + "github.com/stretchr/testify/require" +) + +func TestMergePlatformQuotaDefaults_PatchSemantics(t *testing.T) { + five := 5.0 + base := DefaultPlatformQuotaSetting{ + DailyLimitUSD: &five, + WeeklyLimitUSD: &five, + } + ten := 10.0 + patch := DefaultPlatformQuotaSetting{DailyLimitUSD: &ten} + + mergePlatformQuotaDefaults(&base, &patch) + if base.DailyLimitUSD == nil || *base.DailyLimitUSD != 10.0 { + t.Errorf("daily not patched: %+v", base.DailyLimitUSD) + } + if base.WeeklyLimitUSD == nil || *base.WeeklyLimitUSD != 5.0 { + t.Errorf("weekly should remain 5.0: %+v", base.WeeklyLimitUSD) + } +} + +func TestMergePlatformQuotaDefaults_ZeroIsExplicitDisable(t *testing.T) { + five := 5.0 + base := DefaultPlatformQuotaSetting{DailyLimitUSD: &five} + zero := 0.0 + patch := DefaultPlatformQuotaSetting{DailyLimitUSD: &zero} + + mergePlatformQuotaDefaults(&base, &patch) + if base.DailyLimitUSD == nil || *base.DailyLimitUSD != 0 { + t.Errorf("explicit 0 should patch base, got %+v", base.DailyLimitUSD) + } +} + +func TestMergePlatformQuotaDefaults_NilSrcIsNoop(t *testing.T) { + five := 5.0 + base := DefaultPlatformQuotaSetting{DailyLimitUSD: &five} + mergePlatformQuotaDefaults(&base, nil) + if base.DailyLimitUSD == nil || *base.DailyLimitUSD != 5.0 { + t.Errorf("nil src should be no-op: %+v", base.DailyLimitUSD) + } +} + +func floatPtrPQ(v float64) *float64 { return &v } + +func newSettingServiceForPlatformQuotaTest(seed map[string]string) *SettingService { + repo := newMockSettingRepo() + for k, v := range seed { + repo.data[k] = v + } + return NewSettingService(repo, &config.Config{}) +} + +func TestGetDefaultPlatformQuotas_ReturnsFourPlatforms(t *testing.T) { + zero := 0.0 + svc := newSettingServiceForPlatformQuotaTest(map[string]string{ + // 新 JSON 格式:anthropic daily=10.5, openai monthly=0, gemini/antigravity 无配置 + SettingKeyDefaultPlatformQuotas: `{"anthropic":{"daily":10.5},"openai":{"monthly":0}}`, + }) + got, err := svc.GetDefaultPlatformQuotas(context.Background()) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + // 必须包含全部 4 个 platform key(补齐契约) + for _, platform := range []string{"anthropic", "openai", "gemini", "antigravity"} { + if _, ok := got[platform]; !ok { + t.Errorf("missing platform key: %q", platform) + } + } + // anthropic daily = 10.5 + if v := got["anthropic"].DailyLimitUSD; v == nil || *v != 10.5 { + t.Errorf("anthropic daily want 10.5, got %v", v) + } + // openai monthly = 0(显式禁用) + if v := got["openai"].MonthlyLimitUSD; v == nil || *v != zero { + t.Errorf("openai monthly want 0 (explicit disable), got %v", v) + } + // gemini 无配置 → weekly = nil + if v := got["gemini"].WeeklyLimitUSD; v != nil { + t.Errorf("gemini weekly want nil (not configured), got %v", *v) + } + // antigravity 无配置 → daily = nil + if v := got["antigravity"].DailyLimitUSD; v != nil { + t.Errorf("antigravity daily want nil (not configured), got %v", *v) + } +} + +func TestGetAuthSourcePlatformQuotas_OnlyConfiguredReturned(t *testing.T) { + source := "email" + // 新 JSON 格式:anthropic daily=5, monthly=100;openai weekly=0;gemini/antigravity 无配置 + svc := newSettingServiceForPlatformQuotaTest(map[string]string{ + SettingKeyAuthSourcePlatformQuotas(source): `{"anthropic":{"daily":5,"monthly":100},"openai":{"weekly":0}}`, + }) + got := svc.GetAuthSourcePlatformQuotas(context.Background(), source) + + // anthropic 有配置 → 在结果中 + anthro, ok := got["anthropic"] + if !ok { + t.Fatal("expected anthropic to be present") + } + if anthro.DailyLimitUSD == nil || *anthro.DailyLimitUSD != 5.0 { + t.Errorf("anthropic daily want 5.0, got %v", anthro.DailyLimitUSD) + } + if anthro.MonthlyLimitUSD == nil || *anthro.MonthlyLimitUSD != 100.0 { + t.Errorf("anthropic monthly want 100.0, got %v", anthro.MonthlyLimitUSD) + } + if anthro.WeeklyLimitUSD != nil { + t.Errorf("anthropic weekly not configured, want nil, got %v", *anthro.WeeklyLimitUSD) + } + + // openai weekly=0 → 在结果中 + oai, ok := got["openai"] + if !ok { + t.Fatal("expected openai to be present") + } + if oai.WeeklyLimitUSD == nil || *oai.WeeklyLimitUSD != 0 { + t.Errorf("openai weekly want 0, got %v", oai.WeeklyLimitUSD) + } + + // gemini / antigravity 无配置 → 不在结果中(override 语义) + if _, ok := got["gemini"]; ok { + t.Error("gemini not configured, should be absent from result") + } + if _, ok := got["antigravity"]; ok { + t.Error("antigravity not configured, should be absent from result") + } +} + +func TestGetAuthSourcePlatformQuotas_AllNegativeOrEmpty_NoEntry(t *testing.T) { + source := "linuxdo" + // 新 JSON 格式:未配置任何平台(空 JSON key)→ 返回空 map + svc := newSettingServiceForPlatformQuotaTest(map[string]string{ + SettingKeyAuthSourcePlatformQuotas(source): `{}`, + }) + got := svc.GetAuthSourcePlatformQuotas(context.Background(), source) + // 空 map → override 语义,无 openai 条目 + if _, ok := got["openai"]; ok { + t.Error("empty JSON object should result in no openai entry") + } + if len(got) != 0 { + t.Errorf("expected empty result map, got %v", got) + } +} + +// TestSystemPlatformQuotas_WriteReadRoundTrip 验证系统层 platform quota 经 buildSystemSettingsUpdates(写) +// 再由 GetDefaultPlatformQuotas(读)正确往返——覆盖真实 write→read 路径,锁住 4-key 补齐契约。 +func TestSystemPlatformQuotas_WriteReadRoundTrip(t *testing.T) { + svc := newSettingServiceForPlatformQuotaTest(nil) + ctx := context.Background() + + ten := 10.0 + ss := &SystemSettings{ + DefaultPlatformQuotas: map[string]*DefaultPlatformQuotaSetting{ + "anthropic": {DailyLimitUSD: &ten, WeeklyLimitUSD: nil, MonthlyLimitUSD: nil}, + }, + } + if err := svc.UpdateSettings(ctx, ss); err != nil { + t.Fatalf("UpdateSettings: %v", err) + } + + got, err := svc.GetDefaultPlatformQuotas(ctx) + if err != nil { + t.Fatal(err) + } + // 4-key 补齐契约:无论写了几个 platform,读回必须含全部 4 个 + for _, p := range []string{"anthropic", "openai", "gemini", "antigravity"} { + if _, ok := got[p]; !ok { + t.Errorf("4-key contract violated: missing platform %q", p) + } + } + // 写入值正确往返 + if v := got["anthropic"].DailyLimitUSD; v == nil || *v != ten { + t.Fatalf("anthropic daily round-trip failed: got %v, want 10", v) + } + // 未写入的平台字段为 nil + if got["openai"].DailyLimitUSD != nil { + t.Errorf("openai daily should be nil (not written), got %v", got["openai"].DailyLimitUSD) + } +} + +// TestSystemPlatformQuotas_EmptyMapClearsAll 验证空 map 的整体替换语义: +// 写入 DefaultPlatformQuotas={} 后,GetDefaultPlatformQuotas 返回 4 个平台、所有字段均为 nil, +// 明确文档化"空 map = 清空全部配额"是有意为之的 whole-replace 语义。 +func TestSystemPlatformQuotas_EmptyMapClearsAll(t *testing.T) { + svc := newSettingServiceForPlatformQuotaTest(nil) + ctx := context.Background() + + // 先写入有值的配置 + ten := 10.0 + if err := svc.UpdateSettings(ctx, &SystemSettings{ + DefaultPlatformQuotas: map[string]*DefaultPlatformQuotaSetting{ + "anthropic": {DailyLimitUSD: &ten}, + }, + }); err != nil { + t.Fatalf("initial write: %v", err) + } + + // 再写入空 map(整体替换语义:清空全部) + if err := svc.UpdateSettings(ctx, &SystemSettings{ + DefaultPlatformQuotas: map[string]*DefaultPlatformQuotaSetting{}, + }); err != nil { + t.Fatalf("empty map write: %v", err) + } + + got, err := svc.GetDefaultPlatformQuotas(ctx) + if err != nil { + t.Fatal(err) + } + // 4 个 key 仍然存在(补齐契约) + for _, p := range []string{"anthropic", "openai", "gemini", "antigravity"} { + if _, ok := got[p]; !ok { + t.Errorf("4-key contract violated after empty write: missing %q", p) + } + } + // 所有字段 nil(全部已清空) + for _, p := range AllowedQuotaPlatforms { + pq := got[p] + if pq == nil { + continue + } + if pq.DailyLimitUSD != nil || pq.WeeklyLimitUSD != nil || pq.MonthlyLimitUSD != nil { + t.Errorf("platform %q should have all-nil limits after empty-map write, got %+v", p, pq) + } + } +} + +// TestUpdateSettingsWithAuthSourceDefaults_PlatformQuotaRoundTrip 验证 round-4 fix: +// PUT /admin/settings 携带的 auth source × platform × window 限额能完整写入并被 GetAuthSourcePlatformQuotas 读回。 +// Round-4 之前 writeProviderDefaultGrantUpdates 完全没写 PQ key,前端配置静默丢失。 +func TestUpdateSettingsWithAuthSourceDefaults_PlatformQuotaRoundTrip(t *testing.T) { + svc := newSettingServiceForPlatformQuotaTest(nil) + systemSettings := &SystemSettings{} + authDefaults := &AuthSourceDefaultSettings{ + Email: ProviderDefaultGrantSettings{ + PlatformQuotas: map[string]*DefaultPlatformQuotaSetting{ + "anthropic": { + DailyLimitUSD: floatPtrPQ(5.0), + WeeklyLimitUSD: nil, // 无限额 + MonthlyLimitUSD: floatPtrPQ(100.0), + }, + "openai": { + DailyLimitUSD: floatPtrPQ(0), // 显式禁用 + }, + }, + }, + } + if err := svc.UpdateSettingsWithAuthSourceDefaults(context.Background(), systemSettings, authDefaults); err != nil { + t.Fatalf("UpdateSettingsWithAuthSourceDefaults: %v", err) + } + got := svc.GetAuthSourcePlatformQuotas(context.Background(), "email") + anthro := got["anthropic"] + if anthro == nil || anthro.DailyLimitUSD == nil || *anthro.DailyLimitUSD != 5.0 { + t.Errorf("anthropic daily round-trip failed: %+v", anthro) + } + if anthro != nil && anthro.WeeklyLimitUSD != nil { + t.Errorf("anthropic weekly want nil (无限额), got %v", *anthro.WeeklyLimitUSD) + } + if anthro == nil || anthro.MonthlyLimitUSD == nil || *anthro.MonthlyLimitUSD != 100.0 { + t.Errorf("anthropic monthly round-trip failed: %+v", anthro) + } + oai := got["openai"] + if oai == nil || oai.DailyLimitUSD == nil || *oai.DailyLimitUSD != 0 { + t.Errorf("openai daily=0 (禁用) round-trip failed: %+v", oai) + } + // 其他 source 不应有 quota(authDefaults 只填了 Email) + if linux := svc.GetAuthSourcePlatformQuotas(context.Background(), "linuxdo"); len(linux) != 0 { + t.Errorf("linuxdo should be empty, got %+v", linux) + } +} + +// TestUpdateSettingsWithAuthSourceDefaults_NilPlatformQuotaPreservesExisting 验证 #2 防御: +// 请求未携带某 auth source 的 platform quota(nil)时跳过写入、保留既有配置, +// 而非整体替换为空 map 清空(与系统层 nil 守卫一致)。 +func TestUpdateSettingsWithAuthSourceDefaults_NilPlatformQuotaPreservesExisting(t *testing.T) { + svc := newSettingServiceForPlatformQuotaTest(map[string]string{ + SettingKeyAuthSourcePlatformQuotas("email"): `{"anthropic":{"daily":5,"weekly":null,"monthly":null}}`, + }) + // authDefaults 不携带 Email 的 PlatformQuotas(nil)——应保留既有配置 + authDefaults := &AuthSourceDefaultSettings{ + Email: ProviderDefaultGrantSettings{PlatformQuotas: nil}, + } + if err := svc.UpdateSettingsWithAuthSourceDefaults(context.Background(), &SystemSettings{}, authDefaults); err != nil { + t.Fatalf("UpdateSettingsWithAuthSourceDefaults: %v", err) + } + anthro := svc.GetAuthSourcePlatformQuotas(context.Background(), "email")["anthropic"] + if anthro == nil || anthro.DailyLimitUSD == nil || *anthro.DailyLimitUSD != 5.0 { + t.Errorf("nil PlatformQuotas 应保留既有 anthropic daily=5,got %+v", anthro) + } +} + +// TestGetAuthSourcePlatformQuotas_JSON 验证新 JSON key 读写语义: +// 写入 JSON,断言已配置平台在结果中、未配置平台不在结果中(override 语义)。 +func TestGetAuthSourcePlatformQuotas_JSON(t *testing.T) { + svc := newSettingServiceForPlatformQuotaTest(map[string]string{ + SettingKeyAuthSourcePlatformQuotas("email"): `{"openai":{"daily":null,"weekly":null,"monthly":20}}`, + }) + got := svc.GetAuthSourcePlatformQuotas(context.Background(), "email") + + // openai monthly = 20 + oai, ok := got["openai"] + if !ok { + t.Fatal("expected openai to be present") + } + if oai.MonthlyLimitUSD == nil || *oai.MonthlyLimitUSD != 20 { + t.Errorf("openai monthly want 20, got %v", oai.MonthlyLimitUSD) + } + if oai.DailyLimitUSD != nil { + t.Errorf("openai daily want nil, got %v", *oai.DailyLimitUSD) + } + if oai.WeeklyLimitUSD != nil { + t.Errorf("openai weekly want nil, got %v", *oai.WeeklyLimitUSD) + } + + // anthropic 未配置 → 不在结果中(override 语义) + if _, ok := got["anthropic"]; ok { + t.Error("anthropic not configured, should be absent from result") + } +} + +// TestUpdateSettingsWithAuthSourceDefaults_NegativeQuotaRejected 验证改动 C: +// auth-source platform quota 含负数时,UpdateSettingsWithAuthSourceDefaults 返回 BadRequest 错误。 +func TestUpdateSettingsWithAuthSourceDefaults_NegativeQuotaRejected(t *testing.T) { + svc := newSettingServiceForPlatformQuotaTest(nil) + neg := -1.0 + authDefaults := &AuthSourceDefaultSettings{ + Email: ProviderDefaultGrantSettings{ + PlatformQuotas: map[string]*DefaultPlatformQuotaSetting{ + "anthropic": {DailyLimitUSD: &neg}, + }, + }, + } + err := svc.UpdateSettingsWithAuthSourceDefaults(context.Background(), &SystemSettings{}, authDefaults) + require.Error(t, err, "expected error for negative quota") + require.Equal(t, "INVALID_DEFAULT_PLATFORM_QUOTA", infraerrors.Reason(err)) +} diff --git a/backend/internal/service/settings_view.go b/backend/internal/service/settings_view.go index c9bea224..3f961ab2 100644 --- a/backend/internal/service/settings_view.go +++ b/backend/internal/service/settings_view.go @@ -219,6 +219,9 @@ type SystemSettings struct { // 账号限额通知 AccountQuotaNotifyEnabled bool AccountQuotaNotifyEmails []NotifyEmailEntry + + // 系统全局默认平台配额(key = platform,nil/缺省 = 不限制) + DefaultPlatformQuotas map[string]*DefaultPlatformQuotaSetting `json:"default_platform_quotas"` } type DefaultSubscriptionSetting struct { diff --git a/backend/internal/service/user_platform_quota_port.go b/backend/internal/service/user_platform_quota_port.go new file mode 100644 index 00000000..cb09542a --- /dev/null +++ b/backend/internal/service/user_platform_quota_port.go @@ -0,0 +1,50 @@ +package service + +import ( + "context" + "errors" + "time" +) + +// ErrUserPlatformQuotaNotFound service 层 sentinel:quota 记录不存在。 +// adapter 将 repository.ErrUserPlatformQuotaNotFound 包装为此错误, +// handler 只需引用 service 包,无需直接依赖 repository 包。 +var ErrUserPlatformQuotaNotFound = errors.New("user platform quota not found") + +// UserPlatformQuotaRecord service 层传输结构体(与 repository 层解耦)。 +type UserPlatformQuotaRecord struct { + UserID int64 + Platform string + DailyLimitUSD *float64 + WeeklyLimitUSD *float64 + MonthlyLimitUSD *float64 + DailyUsageUSD float64 + WeeklyUsageUSD float64 + MonthlyUsageUSD float64 + // 窗口起始时间(可选,用于未来 reset 校验) + DailyWindowStart *time.Time + WeeklyWindowStart *time.Time + MonthlyWindowStart *time.Time +} + +// UserPlatformQuotaRepository 定义 service 层所需的 user × platform quota 数据访问端口。 +// repository 包的 userPlatformQuotaRepository 实现此接口。 +type UserPlatformQuotaRepository interface { + // GetByUserPlatform 查询单条配额记录,未找到时返回 (nil, nil)。 + GetByUserPlatform(ctx context.Context, userID int64, platform string) (*UserPlatformQuotaRecord, error) + // BulkInsertInitial 幂等批量插入初始配额记录(ON CONFLICT DO NOTHING)。 + BulkInsertInitial(ctx context.Context, records []UserPlatformQuotaRecord) error + // IncrementUsageWithReset 原子地累加用量,若窗口已过期则先重置再累加。 + IncrementUsageWithReset(ctx context.Context, userID int64, platform string, cost float64, now time.Time) error + // ListByUser 查询用户的所有平台配额记录。 + ListByUser(ctx context.Context, userID int64) ([]UserPlatformQuotaRecord, error) + // UpsertForUser 全量替换该用户所有平台限额配置(事务内): + // 1. 软删除未在 records 中出现的所有 active 行 + // 2. 对 records 中每条:UPDATE 已存在的(含重新激活软删行);UPDATE 未命中时 INSERT + // 仅改 *_limit_usd + deleted_at + updated_at,保留 *_usage_usd / *_window_start。 + // records 为空时仅执行步骤 1。 + UpsertForUser(ctx context.Context, userID int64, records []UserPlatformQuotaRecord) error + // ResetExpiredWindow 重置指定窗口("daily"|"weekly"|"monthly")的用量与起始时间。 + // 未命中活跃记录时返回(service-side wrapper of repository.ErrUserPlatformQuotaNotFound)。 + ResetExpiredWindow(ctx context.Context, userID int64, platform string, window string, newStart time.Time) error +} diff --git a/backend/internal/service/user_service_test.go b/backend/internal/service/user_service_test.go index 775dd602..19aec5d3 100644 --- a/backend/internal/service/user_service_test.go +++ b/backend/internal/service/user_service_test.go @@ -202,7 +202,7 @@ func (m *mockUserRepo) RemoveGroupFromAllowedGroups(context.Context, int64) (int func (m *mockUserRepo) BatchSetConcurrency(context.Context, []int64, int) (int, error) { return 0, nil } func (m *mockUserRepo) BatchAddConcurrency(context.Context, []int64, int) (int, error) { return 0, nil } -func (m *mockUserRepo) AddGroupToAllowedGroups(context.Context, int64, int64) error { return nil } +func (m *mockUserRepo) AddGroupToAllowedGroups(context.Context, int64, int64) error { return nil } func (m *mockUserRepo) ListUserAuthIdentities(context.Context, int64) ([]UserAuthIdentityRecord, error) { out := make([]UserAuthIdentityRecord, len(m.identities)) copy(out, m.identities) @@ -315,6 +315,22 @@ func (m *mockBillingCache) InvalidateAPIKeyRateLimit(context.Context, int64) err return nil } +func (m *mockBillingCache) GetUserPlatformQuotaCache(context.Context, int64, string) (*UserPlatformQuotaCacheEntry, bool, error) { + return nil, false, nil +} + +func (m *mockBillingCache) SetUserPlatformQuotaCache(context.Context, int64, string, *UserPlatformQuotaCacheEntry, time.Duration) error { + return nil +} + +func (m *mockBillingCache) DeleteUserPlatformQuotaCache(context.Context, int64, string) error { + return nil +} + +func (m *mockBillingCache) IncrUserPlatformQuotaUsageCache(context.Context, int64, string, float64, time.Duration) error { + return nil +} + // --- 测试 --- func TestUpdateBalance_Success(t *testing.T) { diff --git a/backend/internal/service/wire.go b/backend/internal/service/wire.go index 43748aa5..b22e10ae 100644 --- a/backend/internal/service/wire.go +++ b/backend/internal/service/wire.go @@ -417,8 +417,9 @@ func ProvideBillingCacheService( rpmCache UserRPMCache, rateRepo UserGroupRateRepository, cfg *config.Config, + userPlatformQuotaRepo UserPlatformQuotaRepository, ) *BillingCacheService { - return NewBillingCacheService(cache, userRepo, subRepo, apiKeyRepo, rpmCache, rateRepo, cfg) + return NewBillingCacheService(cache, userRepo, subRepo, apiKeyRepo, rpmCache, rateRepo, cfg, userPlatformQuotaRepo) } // ProvideAPIKeyService wires APIKeyService and connects rate-limit cache invalidation. diff --git a/backend/migrations/142_user_platform_quotas.sql b/backend/migrations/142_user_platform_quotas.sql new file mode 100644 index 00000000..34375edd --- /dev/null +++ b/backend/migrations/142_user_platform_quotas.sql @@ -0,0 +1,36 @@ +-- 用户平台维度配额表。每个 (user_id, platform) 对独立记录日/周/月三层 USD 限额与用量。 +-- nil limit = 不限制(沿用上层默认),0 = 显式禁用,>0 = USD 上限。 +-- 软删除:deleted_at IS NULL 的记录为活跃记录,部分唯一索引保证同用户同平台只有一条活跃配额。 + +CREATE TABLE IF NOT EXISTS user_platform_quotas ( + id BIGSERIAL PRIMARY KEY, + user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE, + platform VARCHAR(32) NOT NULL CHECK (platform IN ('anthropic', 'openai', 'gemini', 'antigravity')), + + -- 日 / 周 / 月 USD 上限:NULL = 不限制,0 = 显式禁用,>0 = 上限 + daily_limit_usd DECIMAL(20,10), + weekly_limit_usd DECIMAL(20,10), + monthly_limit_usd DECIMAL(20,10), + + -- 当前窗口已用量 + daily_usage_usd DECIMAL(20,10) NOT NULL DEFAULT 0, + weekly_usage_usd DECIMAL(20,10) NOT NULL DEFAULT 0, + monthly_usage_usd DECIMAL(20,10) NOT NULL DEFAULT 0, + + -- 窗口起点(NULL = 首次尚未初始化) + daily_window_start TIMESTAMPTZ, + weekly_window_start TIMESTAMPTZ, + monthly_window_start TIMESTAMPTZ, + + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + deleted_at TIMESTAMPTZ +); + +-- 软删除友好唯一索引:同用户同平台只允许一条未删除记录 +CREATE UNIQUE INDEX IF NOT EXISTS userplatformquota_user_id_platform_uq + ON user_platform_quotas (user_id, platform) + WHERE deleted_at IS NULL; + +CREATE INDEX IF NOT EXISTS userplatformquota_user_id + ON user_platform_quotas (user_id); diff --git a/deploy/config.example.yaml b/deploy/config.example.yaml index 8e9b0e3b..8d8e1fd7 100644 --- a/deploy/config.example.yaml +++ b/deploy/config.example.yaml @@ -1001,6 +1001,9 @@ billing: # Number of requests to allow in half-open state # 半开状态允许通过的请求数 half_open_requests: 3 + # Cache TTL (seconds) for per-user × per-platform quota records + # 用户 × 平台 quota 缓存 TTL(秒),默认 86400=1天,覆盖典型 daily 窗口 + user_platform_quota_cache_ttl_seconds: 86400 # ============================================================================= # Turnstile Configuration diff --git a/frontend/src/api/__tests__/settings.authSourceDefaults.spec.ts b/frontend/src/api/__tests__/settings.authSourceDefaults.spec.ts index 10f6247a..4dc7db2e 100644 --- a/frontend/src/api/__tests__/settings.authSourceDefaults.spec.ts +++ b/frontend/src/api/__tests__/settings.authSourceDefaults.spec.ts @@ -3,9 +3,20 @@ import { describe, expect, it } from "vitest"; import { appendAuthSourceDefaultsToUpdateRequest, buildAuthSourceDefaultsState, + normalizePlatformQuotasMap, + sanitizePlatformQuotasMap, type UpdateSettingsRequest, + type DefaultPlatformQuotasMap, } from "@/api/admin/settings"; +/** 全 null 的 4 平台 map,用于断言归一化默认值 */ +const allNullQuotas: DefaultPlatformQuotasMap = { + anthropic: { daily: null, weekly: null, monthly: null }, + openai: { daily: null, weekly: null, monthly: null }, + gemini: { daily: null, weekly: null, monthly: null }, + antigravity: { daily: null, weekly: null, monthly: null }, +} + describe("admin settings auth source defaults helpers", () => { it("builds auth source defaults state from flat settings fields", () => { const state = buildAuthSourceDefaultsState({ @@ -31,6 +42,7 @@ describe("admin settings auth source defaults helpers", () => { subscriptions: [{ group_id: 1, validity_days: 30 }], grant_on_signup: false, grant_on_first_bind: true, + platform_quotas: allNullQuotas, }); expect(state.linuxdo).toEqual({ balance: 6, @@ -38,6 +50,7 @@ describe("admin settings auth source defaults helpers", () => { subscriptions: [{ group_id: 2, validity_days: 60 }], grant_on_signup: true, grant_on_first_bind: false, + platform_quotas: allNullQuotas, }); expect(state.oidc).toEqual({ balance: 0, @@ -45,6 +58,7 @@ describe("admin settings auth source defaults helpers", () => { subscriptions: [], grant_on_signup: false, grant_on_first_bind: false, + platform_quotas: allNullQuotas, }); expect(state.wechat).toEqual({ balance: 0, @@ -52,6 +66,7 @@ describe("admin settings auth source defaults helpers", () => { subscriptions: [], grant_on_signup: false, grant_on_first_bind: false, + platform_quotas: allNullQuotas, }); }); @@ -64,6 +79,23 @@ describe("admin settings auth source defaults helpers", () => { expect(state.wechat.grant_on_signup).toBe(false); }); + it("reads nested platform_quotas from settings into auth source state", () => { + const state = buildAuthSourceDefaultsState({ + auth_source_default_email_platform_quotas: { + anthropic: { daily: 10, weekly: 50, monthly: 200 }, + openai: { daily: null, weekly: null, monthly: null }, + } as DefaultPlatformQuotasMap, + }); + + // anthropic 填写的值应被保留 + expect(state.email.platform_quotas.anthropic).toEqual({ daily: 10, weekly: 50, monthly: 200 }); + // openai 全 null 应被保留 + expect(state.email.platform_quotas.openai).toEqual({ daily: null, weekly: null, monthly: null }); + // 未出现的平台(gemini/antigravity)归一化为 null + expect(state.email.platform_quotas.gemini).toEqual({ daily: null, weekly: null, monthly: null }); + expect(state.email.platform_quotas.antigravity).toEqual({ daily: null, weekly: null, monthly: null }); + }); + it("appends auth source defaults back onto update payload", () => { const payload: UpdateSettingsRequest = { site_name: "Sub2API", @@ -76,6 +108,7 @@ describe("admin settings auth source defaults helpers", () => { subscriptions: [{ group_id: 3, validity_days: 7 }], grant_on_signup: true, grant_on_first_bind: false, + platform_quotas: {}, }, linuxdo: { balance: 0, @@ -83,6 +116,7 @@ describe("admin settings auth source defaults helpers", () => { subscriptions: [], grant_on_signup: false, grant_on_first_bind: true, + platform_quotas: {}, }, oidc: { balance: 4, @@ -90,6 +124,7 @@ describe("admin settings auth source defaults helpers", () => { subscriptions: [{ group_id: 9, validity_days: 90 }], grant_on_signup: true, grant_on_first_bind: true, + platform_quotas: {}, }, wechat: { balance: 2, @@ -97,6 +132,31 @@ describe("admin settings auth source defaults helpers", () => { subscriptions: [], grant_on_signup: false, grant_on_first_bind: false, + platform_quotas: {}, + }, + github: { + balance: 0, + concurrency: 5, + subscriptions: [], + grant_on_signup: false, + grant_on_first_bind: false, + platform_quotas: {}, + }, + google: { + balance: 0, + concurrency: 5, + subscriptions: [], + grant_on_signup: false, + grant_on_first_bind: false, + platform_quotas: {}, + }, + dingtalk: { + balance: 0, + concurrency: 5, + subscriptions: [], + grant_on_signup: false, + grant_on_first_bind: false, + platform_quotas: {}, }, }); @@ -126,6 +186,111 @@ describe("admin settings auth source defaults helpers", () => { auth_source_default_wechat_subscriptions: [], auth_source_default_wechat_grant_on_signup: false, auth_source_default_wechat_grant_on_first_bind: false, + // 嵌套 platform_quotas 字段 + auth_source_default_email_platform_quotas: allNullQuotas, + auth_source_default_linuxdo_platform_quotas: allNullQuotas, + auth_source_default_oidc_platform_quotas: allNullQuotas, + auth_source_default_wechat_platform_quotas: allNullQuotas, + auth_source_default_github_platform_quotas: allNullQuotas, + auth_source_default_google_platform_quotas: allNullQuotas, + auth_source_default_dingtalk_platform_quotas: allNullQuotas, }); }); + + it("appends sanitized nested platform_quotas with non-null values in update payload", () => { + const payload: UpdateSettingsRequest = {}; + appendAuthSourceDefaultsToUpdateRequest(payload, { + email: { + balance: 0, + concurrency: 5, + subscriptions: [], + grant_on_signup: false, + grant_on_first_bind: false, + platform_quotas: { + anthropic: { daily: 10, weekly: 50, monthly: 200 }, + openai: { daily: 0, weekly: null, monthly: null }, + }, + }, + linuxdo: { balance: 0, concurrency: 5, subscriptions: [], grant_on_signup: false, grant_on_first_bind: false, platform_quotas: {} }, + oidc: { balance: 0, concurrency: 5, subscriptions: [], grant_on_signup: false, grant_on_first_bind: false, platform_quotas: {} }, + wechat: { balance: 0, concurrency: 5, subscriptions: [], grant_on_signup: false, grant_on_first_bind: false, platform_quotas: {} }, + github: { balance: 0, concurrency: 5, subscriptions: [], grant_on_signup: false, grant_on_first_bind: false, platform_quotas: {} }, + google: { balance: 0, concurrency: 5, subscriptions: [], grant_on_signup: false, grant_on_first_bind: false, platform_quotas: {} }, + dingtalk: { balance: 0, concurrency: 5, subscriptions: [], grant_on_signup: false, grant_on_first_bind: false, platform_quotas: {} }, + }); + + const emailQuotas = (payload as Record)["auth_source_default_email_platform_quotas"] as DefaultPlatformQuotasMap; + expect(emailQuotas.anthropic).toEqual({ daily: 10, weekly: 50, monthly: 200 }); + // 0 是合法值(不限额=0 与"不设"不同,保留) + expect(emailQuotas.openai?.daily).toBe(0); + // 缺失平台归一化为全 null + expect(emailQuotas.gemini).toEqual({ daily: null, weekly: null, monthly: null }); + expect(emailQuotas.antigravity).toEqual({ daily: null, weekly: null, monthly: null }); + }); +}); + +describe("normalizePlatformQuotasMap", () => { + it("填充缺失的平台为全 null 三档", () => { + const result = normalizePlatformQuotasMap({ anthropic: { daily: 5, weekly: null, monthly: null } }); + expect(result.anthropic).toEqual({ daily: 5, weekly: null, monthly: null }); + expect(result.openai).toEqual({ daily: null, weekly: null, monthly: null }); + expect(result.gemini).toEqual({ daily: null, weekly: null, monthly: null }); + expect(result.antigravity).toEqual({ daily: null, weekly: null, monthly: null }); + }); + + it("无参数时返回全 4 平台全 null", () => { + const result = normalizePlatformQuotasMap(); + expect(Object.keys(result)).toHaveLength(4); + for (const v of Object.values(result)) { + expect(v).toEqual({ daily: null, weekly: null, monthly: null }); + } + }); + + it("非 number 类型的值归一化为 null", () => { + const result = normalizePlatformQuotasMap({ + anthropic: { daily: "50" as unknown as number, weekly: undefined as unknown as number, monthly: null }, + }); + expect(result.anthropic).toEqual({ daily: null, weekly: null, monthly: null }); + }); +}); + +describe("sanitizePlatformQuotasMap", () => { + it("保留合法的正数和零值", () => { + const result = sanitizePlatformQuotasMap({ + anthropic: { daily: 10.5, weekly: 0, monthly: null }, + }); + expect(result.anthropic?.daily).toBe(10.5); + expect(result.anthropic?.weekly).toBe(0); + expect(result.anthropic?.monthly).toBe(null); + }); + + it("空字符串(v-model.number 空输入)清洗为 null", () => { + const result = sanitizePlatformQuotasMap({ + anthropic: { daily: "" as unknown as number, weekly: null, monthly: null }, + }); + expect(result.anthropic?.daily).toBe(null); + }); + + it("负数清洗为 null", () => { + const result = sanitizePlatformQuotasMap({ + openai: { daily: -1, weekly: null, monthly: null }, + }); + expect(result.openai?.daily).toBe(null); + }); + + it("NaN/Infinity 清洗为 null", () => { + const result = sanitizePlatformQuotasMap({ + gemini: { daily: NaN, weekly: Infinity, monthly: null }, + }); + expect(result.gemini?.daily).toBe(null); + expect(result.gemini?.weekly).toBe(null); + }); + + it("缺失平台填充为全 null", () => { + const result = sanitizePlatformQuotasMap({}); + expect(Object.keys(result)).toHaveLength(4); + for (const v of Object.values(result)) { + expect(v).toEqual({ daily: null, weekly: null, monthly: null }); + } + }); }); diff --git a/frontend/src/api/admin/settings.ts b/frontend/src/api/admin/settings.ts index 3bdf3ee4..d2b878cc 100644 --- a/frontend/src/api/admin/settings.ts +++ b/frontend/src/api/admin/settings.ts @@ -16,6 +16,47 @@ export interface DefaultSubscriptionSetting { validity_days: number; } +// ── 平台限额类型 ────────────────────────────────────────────────── +export type PlatformType = "anthropic" | "openai" | "gemini" | "antigravity" +export type QuotaWindowType = "daily" | "weekly" | "monthly" + +/** 单平台三档限额;null = 不限制,undefined = 未填(等价 null) */ +export interface PlatformQuotaLimits { + daily: number | null + weekly: number | null + monthly: number | null +} + +/** 全平台默认限额 map(key = PlatformType) */ +export type DefaultPlatformQuotasMap = Partial> + +const PLATFORMS: PlatformType[] = ["anthropic", "openai", "gemini", "antigravity"] + +/** 归一化为全 4 平台 × 3 窗口(缺失填 null),供模板非空绑定 */ +export function normalizePlatformQuotasMap(input?: DefaultPlatformQuotasMap | null): DefaultPlatformQuotasMap { + const result: DefaultPlatformQuotasMap = {} + for (const p of PLATFORMS) { + const src = input?.[p] + result[p] = { + daily: typeof src?.daily === "number" ? src.daily : null, + weekly: typeof src?.weekly === "number" ? src.weekly : null, + monthly: typeof src?.monthly === "number" ? src.monthly : null, + } + } + return result +} + +/** 提交前清洗:非有限数/负数/空字符串 → null(保留 0 = 显式禁用),返回全 4 平台嵌套 map */ +export function sanitizePlatformQuotasMap(input?: DefaultPlatformQuotasMap | null): DefaultPlatformQuotasMap { + const clean = (v: unknown): number | null => (typeof v === "number" && Number.isFinite(v) && v >= 0 ? v : null) + const result: DefaultPlatformQuotasMap = {} + for (const p of PLATFORMS) { + const src = input?.[p] + result[p] = { daily: clean(src?.daily), weekly: clean(src?.weekly), monthly: clean(src?.monthly) } + } + return result +} + export type AuthSourceType = | "email" | "linuxdo" @@ -31,6 +72,8 @@ export interface AuthSourceDefaultsValue { subscriptions: DefaultSubscriptionSetting[]; grant_on_signup: boolean; grant_on_first_bind: boolean; + // ★ 新增:平台限额覆盖(key = PlatformType) + platform_quotas: DefaultPlatformQuotasMap; } export type AuthSourceDefaultsState = Record< @@ -193,6 +236,7 @@ export function buildAuthSourceDefaultsState( raw[`auth_source_default_${source}_grant_on_signup`] === true, grant_on_first_bind: raw[`auth_source_default_${source}_grant_on_first_bind`] === true, + platform_quotas: normalizePlatformQuotasMap(raw[`auth_source_default_${source}_platform_quotas`] as DefaultPlatformQuotasMap | undefined), }; return acc; }, {} as AuthSourceDefaultsState); @@ -220,6 +264,7 @@ export function appendAuthSourceDefaultsToUpdateRequest( current.grant_on_signup; target[`auth_source_default_${source}_grant_on_first_bind`] = current.grant_on_first_bind; + target[`auth_source_default_${source}_platform_quotas`] = sanitizePlatformQuotasMap(current.platform_quotas) } return payload; @@ -370,6 +415,15 @@ export interface SystemSettings { auth_source_default_google_grant_on_signup?: boolean; auth_source_default_google_grant_on_first_bind?: boolean; force_email_on_third_party_signup?: boolean; + // ── 平台限额(嵌套 JSON,系统层 + 7 auth-source 层)──────────────────────────────── + default_platform_quotas?: DefaultPlatformQuotasMap; + auth_source_default_email_platform_quotas?: DefaultPlatformQuotasMap; + auth_source_default_linuxdo_platform_quotas?: DefaultPlatformQuotasMap; + auth_source_default_oidc_platform_quotas?: DefaultPlatformQuotasMap; + auth_source_default_wechat_platform_quotas?: DefaultPlatformQuotasMap; + auth_source_default_github_platform_quotas?: DefaultPlatformQuotasMap; + auth_source_default_google_platform_quotas?: DefaultPlatformQuotasMap; + auth_source_default_dingtalk_platform_quotas?: DefaultPlatformQuotasMap; // OEM settings site_name: string; site_logo: string; @@ -616,6 +670,15 @@ export interface UpdateSettingsRequest { auth_source_default_google_grant_on_signup?: boolean; auth_source_default_google_grant_on_first_bind?: boolean; force_email_on_third_party_signup?: boolean; + // ── 平台限额(嵌套 JSON,系统层 + 7 auth-source 层)──────────────────────────────── + default_platform_quotas?: DefaultPlatformQuotasMap; + auth_source_default_email_platform_quotas?: DefaultPlatformQuotasMap; + auth_source_default_linuxdo_platform_quotas?: DefaultPlatformQuotasMap; + auth_source_default_oidc_platform_quotas?: DefaultPlatformQuotasMap; + auth_source_default_wechat_platform_quotas?: DefaultPlatformQuotasMap; + auth_source_default_github_platform_quotas?: DefaultPlatformQuotasMap; + auth_source_default_google_platform_quotas?: DefaultPlatformQuotasMap; + auth_source_default_dingtalk_platform_quotas?: DefaultPlatformQuotasMap; site_name?: string; site_logo?: string; site_subtitle?: string; diff --git a/frontend/src/api/admin/users.ts b/frontend/src/api/admin/users.ts index fabc69bc..bfe5e3ba 100644 --- a/frontend/src/api/admin/users.ts +++ b/frontend/src/api/admin/users.ts @@ -297,6 +297,78 @@ export async function bindUserAuthIdentity( return data } +/** + * Platform quota types + */ +export type PlatformQuotaPlatform = 'anthropic' | 'openai' | 'gemini' | 'antigravity' +export type PlatformQuotaWindow = 'daily' | 'weekly' | 'monthly' + +export interface PlatformQuotaItem { + platform: PlatformQuotaPlatform + daily_limit_usd: number | null + weekly_limit_usd: number | null + monthly_limit_usd: number | null + daily_usage_usd: number + weekly_usage_usd: number + monthly_usage_usd: number + daily_window_start?: string | null + weekly_window_start?: string | null + monthly_window_start?: string | null + daily_window_resets_at?: string | null + weekly_window_resets_at?: string | null + monthly_window_resets_at?: string | null +} + +export interface PlatformQuotaUpdateItem { + platform: PlatformQuotaPlatform + daily_limit_usd: number | null + weekly_limit_usd: number | null + monthly_limit_usd: number | null +} + +export interface PlatformQuotasResponse { + platform_quotas: PlatformQuotaItem[] +} + +/** + * Get user's platform quotas + */ +export async function getPlatformQuotas(id: number): Promise { + const { data } = await apiClient.get( + `/admin/users/${id}/platform-quotas` + ) + return data +} + +/** + * Replace user's platform quotas (全量替换) + */ +export async function updatePlatformQuotas( + id: number, + quotas: PlatformQuotaUpdateItem[] +): Promise { + const { data } = await apiClient.put( + `/admin/users/${id}/platform-quotas`, + { quotas } + ) + return data +} + +/** + * Reset a single (platform, window) usage immediately + */ +export async function resetPlatformQuotaWindow( + id: number, + platform: PlatformQuotaPlatform, + window: PlatformQuotaWindow +): Promise { + const { data } = await apiClient.post( + `/admin/users/${id}/platform-quotas/reset`, + { platform, window } + ) + return data +} + export const usersAPI = { list, getById, @@ -310,7 +382,10 @@ export const usersAPI = { getUserUsageStats, getUserBalanceHistory, replaceGroup, - bindUserAuthIdentity + bindUserAuthIdentity, + getPlatformQuotas, + updatePlatformQuotas, + resetPlatformQuotaWindow, } export default usersAPI diff --git a/frontend/src/api/user.ts b/frontend/src/api/user.ts index da7a91eb..88768530 100644 --- a/frontend/src/api/user.ts +++ b/frontend/src/api/user.ts @@ -15,7 +15,8 @@ import type { NotifyEmailEntry, UserAuthProvider, UserAffiliateDetail, - AffiliateTransferResponse + AffiliateTransferResponse, + PlatformQuotasResponse, } from '@/types' /** @@ -185,6 +186,14 @@ export async function transferAffiliateQuota(): Promise { + const { data } = await apiClient.get('/user/platform-quotas') + return data +} + export const userAPI = { getProfile, updateProfile, @@ -199,7 +208,8 @@ export const userAPI = { buildOAuthBindingStartURL, startOAuthBinding, getAffiliateDetail, - transferAffiliateQuota + transferAffiliateQuota, + getMyPlatformQuotas, } export default userAPI diff --git a/frontend/src/components/admin/user/UserPlatformQuotaModal.vue b/frontend/src/components/admin/user/UserPlatformQuotaModal.vue new file mode 100644 index 00000000..76d23b0c --- /dev/null +++ b/frontend/src/components/admin/user/UserPlatformQuotaModal.vue @@ -0,0 +1,283 @@ + + + diff --git a/frontend/src/components/admin/user/__tests__/UserPlatformQuotaModal.spec.ts b/frontend/src/components/admin/user/__tests__/UserPlatformQuotaModal.spec.ts new file mode 100644 index 00000000..06248133 --- /dev/null +++ b/frontend/src/components/admin/user/__tests__/UserPlatformQuotaModal.spec.ts @@ -0,0 +1,245 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest' +import { mount, flushPromises } from '@vue/test-utils' +import { createPinia, setActivePinia } from 'pinia' + +const apiMocks = vi.hoisted(() => ({ + getPlatformQuotas: vi.fn(), + updatePlatformQuotas: vi.fn(), + resetPlatformQuotaWindow: vi.fn(), +})) + +vi.mock('@/api/admin', () => ({ + adminAPI: { + users: { + getPlatformQuotas: apiMocks.getPlatformQuotas, + updatePlatformQuotas: apiMocks.updatePlatformQuotas, + resetPlatformQuotaWindow: apiMocks.resetPlatformQuotaWindow, + }, + }, +})) + +vi.mock('@/stores/app', () => ({ + useAppStore: () => ({ + showError: vi.fn(), + showSuccess: vi.fn(), + }), +})) + +vi.mock('vue-i18n', async () => { + const actual = await vi.importActual('vue-i18n') + return { + ...actual, + useI18n: () => ({ + t: (key: string, params?: Record) => { + if (params) { + return key.replace(/\{(\w+)\}/g, (_, k) => params[k] ?? '') + } + return key + }, + }), + } +}) + +vi.mock('@/components/common/BaseDialog.vue', () => ({ + default: { + name: 'BaseDialog', + props: ['show', 'title', 'width'], + template: '
    ', + }, +})) + +import UserPlatformQuotaModal from '../UserPlatformQuotaModal.vue' +import type { UserSubscription } from '@/types' + +function makeUser(overrides: { subscriptions?: UserSubscription[] } = {}) { + return { id: 99, email: 'u@example.com', ...overrides } as any +} + +/** 挂载并触发 show:false → true,确保 watch 被激活 */ +async function mountAndOpen(extraProps: Record = {}) { + const w = mount(UserPlatformQuotaModal, { + props: { show: false, user: makeUser(), ...extraProps }, + }) + await w.setProps({ show: true }) + await flushPromises() + return w +} + +beforeEach(() => { + setActivePinia(createPinia()) + vi.clearAllMocks() + apiMocks.getPlatformQuotas.mockResolvedValue({ platform_quotas: [] }) + apiMocks.updatePlatformQuotas.mockResolvedValue({ platform_quotas: [] }) + apiMocks.resetPlatformQuotaWindow.mockResolvedValue({ platform_quotas: [] }) +}) + +describe('UserPlatformQuotaModal', () => { + it('挂载并 show=true 时调用 getPlatformQuotas', async () => { + await mountAndOpen() + expect(apiMocks.getPlatformQuotas).toHaveBeenCalledWith(99) + }) + + it('空数据渲染 4 个 platform 行', async () => { + const w = await mountAndOpen() + const html = w.html() + expect(html).toContain('anthropic') + expect(html).toContain('openai') + expect(html).toContain('gemini') + expect(html).toContain('antigravity') + }) + + it('已有数据正确填充 limit input', async () => { + apiMocks.getPlatformQuotas.mockResolvedValueOnce({ + platform_quotas: [ + { platform: 'anthropic', daily_limit_usd: 10, weekly_limit_usd: null, monthly_limit_usd: null, + daily_usage_usd: 3.2, weekly_usage_usd: 0, monthly_usage_usd: 0 }, + ], + }) + const w = await mountAndOpen() + const inputs = w.findAll('input[type=number]') + // 4 platforms × 3 windows = 12 inputs + expect(inputs.length).toBe(12) + // 第一个 input 是 anthropic.daily = 10 + expect((inputs[0].element as HTMLInputElement).value).toBe('10') + }) + + it('保存提交完整 4 platform payload', async () => { + apiMocks.getPlatformQuotas.mockResolvedValueOnce({ + platform_quotas: [ + { platform: 'openai', daily_limit_usd: null, weekly_limit_usd: 20, monthly_limit_usd: null, + daily_usage_usd: 0, weekly_usage_usd: 0, monthly_usage_usd: 0 }, + ], + }) + const w = await mountAndOpen() + // 找到「保存」按钮(包含中文「保存」字样的按钮) + const buttons = w.findAll('button') + const saveBtn = buttons.find((b) => b.text() === 'admin.users.platformQuota.save') + expect(saveBtn).toBeTruthy() + await saveBtn!.trigger('click') + await flushPromises() + expect(apiMocks.updatePlatformQuotas).toHaveBeenCalledTimes(1) + const [uid, payload] = apiMocks.updatePlatformQuotas.mock.calls[0] + expect(uid).toBe(99) + expect(payload).toHaveLength(4) // 4 platforms always submitted + const openai = payload.find((p: any) => p.platform === 'openai') + expect(openai.weekly_limit_usd).toBe(20) + }) + + it('全部清空把所有 limit 置 null(确认通过)', async () => { + const confirmSpy = vi.spyOn(window, 'confirm').mockReturnValue(true) + apiMocks.getPlatformQuotas.mockResolvedValueOnce({ + platform_quotas: [ + { platform: 'anthropic', daily_limit_usd: 10, weekly_limit_usd: 50, monthly_limit_usd: 100, + daily_usage_usd: 0, weekly_usage_usd: 0, monthly_usage_usd: 0 }, + ], + }) + const w = await mountAndOpen() + const buttons = w.findAll('button') + const clearBtn = buttons.find((b) => b.text() === 'admin.users.platformQuota.clearAll') + expect(clearBtn).toBeTruthy() + await clearBtn!.trigger('click') + await flushPromises() + expect(confirmSpy).toHaveBeenCalledTimes(1) + const inputs = w.findAll('input[type=number]') + for (const inp of inputs) { + expect((inp.element as HTMLInputElement).value).toBe('') + } + confirmSpy.mockRestore() + }) + + it('全部清空 confirm 取消则保持原值', async () => { + const confirmSpy = vi.spyOn(window, 'confirm').mockReturnValue(false) + apiMocks.getPlatformQuotas.mockResolvedValueOnce({ + platform_quotas: [ + { platform: 'anthropic', daily_limit_usd: 10, weekly_limit_usd: 50, monthly_limit_usd: 100, + daily_usage_usd: 0, weekly_usage_usd: 0, monthly_usage_usd: 0 }, + ], + }) + const w = await mountAndOpen() + const clearBtn = w.findAll('button').find((b) => b.text() === 'admin.users.platformQuota.clearAll') + await clearBtn!.trigger('click') + await flushPromises() + expect(confirmSpy).toHaveBeenCalledTimes(1) + // anthropic daily 应保持 10(未被清空) + const inputs = w.findAll('input[type=number]') + const dailyVal = (inputs[0].element as HTMLInputElement).value + expect(dailyVal).toBe('10') + confirmSpy.mockRestore() + }) + + it('重置按钮 confirm 取消则不调用 API', async () => { + const confirmSpy = vi.spyOn(window, 'confirm').mockReturnValue(false) + const w = await mountAndOpen() + const resetBtns = w.findAll('button').filter((b) => b.text() === '↻') + expect(resetBtns.length).toBeGreaterThan(0) + await resetBtns[0].trigger('click') + await flushPromises() + expect(apiMocks.resetPlatformQuotaWindow).not.toHaveBeenCalled() + confirmSpy.mockRestore() + }) + + it('重置按钮 confirm 确认则调用 API', async () => { + const confirmSpy = vi.spyOn(window, 'confirm').mockReturnValue(true) + const w = await mountAndOpen() + const resetBtns = w.findAll('button').filter((b) => b.text() === '↻') + await resetBtns[0].trigger('click') // 第一个是 anthropic.daily + await flushPromises() + expect(apiMocks.resetPlatformQuotaWindow).toHaveBeenCalledWith(99, 'anthropic', 'daily') + confirmSpy.mockRestore() + }) + + describe('subscription warning banner', () => { + it('displays subscription warning when user has active subscription', async () => { + const w = mount(UserPlatformQuotaModal, { + props: { + show: true, + user: makeUser({ + subscriptions: [ + { + id: 1, user_id: 99, group_id: 1, status: 'active', + starts_at: '2026-01-01T00:00:00Z', expires_at: null, + daily_usage_usd: 0, weekly_usage_usd: 0, monthly_usage_usd: 0, + daily_window_start: null, weekly_window_start: null, monthly_window_start: null, + created_at: '2026-01-01T00:00:00Z', updated_at: '2026-01-01T00:00:00Z', + } as UserSubscription, + ], + }), + }, + }) + await flushPromises() + expect(w.html()).toContain('admin.users.platformQuota.subscriptionWarning') + }) + + it('hides subscription warning when user has only expired subscriptions', async () => { + const w = mount(UserPlatformQuotaModal, { + props: { + show: true, + user: makeUser({ + subscriptions: [ + { + id: 2, user_id: 99, group_id: 1, status: 'expired', + starts_at: '2025-01-01T00:00:00Z', expires_at: '2025-12-31T00:00:00Z', + daily_usage_usd: 0, weekly_usage_usd: 0, monthly_usage_usd: 0, + daily_window_start: null, weekly_window_start: null, monthly_window_start: null, + created_at: '2025-01-01T00:00:00Z', updated_at: '2025-12-31T00:00:00Z', + } as UserSubscription, + ], + }), + }, + }) + await flushPromises() + expect(w.html()).not.toContain('admin.users.platformQuota.subscriptionWarning') + }) + + it('hides subscription warning when subscriptions is empty array', async () => { + const w = mount(UserPlatformQuotaModal, { + props: { + show: true, + user: makeUser({ subscriptions: [] }), + }, + }) + await flushPromises() + expect(w.html()).not.toContain('admin.users.platformQuota.subscriptionWarning') + }) + }) +}) diff --git a/frontend/src/components/user/UserPlatformQuotaCell.vue b/frontend/src/components/user/UserPlatformQuotaCell.vue new file mode 100644 index 00000000..376b61c8 --- /dev/null +++ b/frontend/src/components/user/UserPlatformQuotaCell.vue @@ -0,0 +1,61 @@ + + + diff --git a/frontend/src/components/user/__tests__/UserPlatformQuotaCell.spec.ts b/frontend/src/components/user/__tests__/UserPlatformQuotaCell.spec.ts new file mode 100644 index 00000000..533d1a32 --- /dev/null +++ b/frontend/src/components/user/__tests__/UserPlatformQuotaCell.spec.ts @@ -0,0 +1,74 @@ +import { describe, it, expect, vi } from 'vitest' +import { mount } from '@vue/test-utils' + +// t() 回显 key,便于断言文案键 +vi.mock('vue-i18n', async () => { + const actual = await vi.importActual('vue-i18n') + return { + ...actual, + useI18n: () => ({ t: (key: string) => key }), + } +}) + +import UserPlatformQuotaCell from '../UserPlatformQuotaCell.vue' +import type { PlatformQuotaItem } from '@/api/admin/users' + +function item(over: Partial & { platform: PlatformQuotaItem['platform'] }): PlatformQuotaItem { + return { + daily_limit_usd: null, weekly_limit_usd: null, monthly_limit_usd: null, + daily_usage_usd: 0, weekly_usage_usd: 0, monthly_usage_usd: 0, + ...over, + } as PlatformQuotaItem +} + +describe('UserPlatformQuotaCell', () => { + it('quotas 为 undefined 时渲染加载占位 …', () => { + const w = mount(UserPlatformQuotaCell, { props: { quotas: undefined } }) + expect(w.text()).toContain('…') + expect(w.html()).not.toContain('admin.users.platformQuota.cellNotConfigured') + }) + + it('空数组渲染「未配置」', () => { + const w = mount(UserPlatformQuotaCell, { props: { quotas: [] } }) + expect(w.html()).toContain('admin.users.platformQuota.cellNotConfigured') + }) + + it('平台有记录但全部 limit 为 null 时视为未配置', () => { + const w = mount(UserPlatformQuotaCell, { + props: { quotas: [item({ platform: 'openai', daily_usage_usd: 5 })] }, + }) + expect(w.html()).toContain('admin.users.platformQuota.cellNotConfigured') + }) + + it('已配置平台渲染 已用/限额,null 档显示 —,金额去尾零', () => { + const w = mount(UserPlatformQuotaCell, { + props: { + quotas: [ + item({ platform: 'anthropic', daily_limit_usd: 100, daily_usage_usd: 30, + weekly_limit_usd: null, weekly_usage_usd: 0, + monthly_limit_usd: 2000, monthly_usage_usd: 90.5 }), + ], + }, + }) + const html = w.html() + expect(html).toContain('anthropic') + expect(html).toContain('30/100') + expect(html).toContain('0/—') + expect(html).toContain('90.5/2000') + }) + + it('多平台按 anthropic→openai→gemini→antigravity 顺序,仅展示有限额的', () => { + const w = mount(UserPlatformQuotaCell, { + props: { + quotas: [ + item({ platform: 'gemini', monthly_limit_usd: 50 }), + item({ platform: 'anthropic', daily_limit_usd: 10 }), + item({ platform: 'openai', daily_usage_usd: 9 }), + ], + }, + }) + const text = w.text() + expect(text.indexOf('anthropic')).toBeLessThan(text.indexOf('gemini')) + expect(text).not.toContain('openai') + }) +}) diff --git a/frontend/src/components/user/dashboard/UserDashboardStats.vue b/frontend/src/components/user/dashboard/UserDashboardStats.vue index 97d2da3d..e7f3449d 100644 --- a/frontend/src/components/user/dashboard/UserDashboardStats.vue +++ b/frontend/src/components/user/dashboard/UserDashboardStats.vue @@ -177,6 +177,46 @@ + + +
    +

    + {{ t('dashboard.platformQuota.title') }} +

    + +
    @@ -187,11 +227,23 @@ import { computed } from 'vue' import { useI18n } from 'vue-i18n' import Icon from '@/components/icons/Icon.vue' import type { UserDashboardStats as UserStatsType } from '@/api/usage' +import type { PlatformQuotaItem } from '@/types' + +interface FusedPlatformCard { + platform: string + total_actual_cost: number + today_actual_cost: number + total_requests: number + total_tokens: number + isOther?: boolean + quota?: PlatformQuotaItem +} const props = defineProps<{ stats: UserStatsType balance: number isSimple: boolean + platformQuotas?: PlatformQuotaItem[] | null }>() const { t } = useI18n() @@ -213,16 +265,45 @@ const sortedPlatforms = computed(() => { // (group 与 account 都缺 platform)。这里把差值作为"其他"卡片显式展示, // 避免 Row 1 总值与 Row 3 平台拆分加总对不上、用户困惑。 const OTHER_THRESHOLD = 0.0001 -const platformCards = computed(() => { - const cards: Array<{ - platform: string - total_actual_cost: number - today_actual_cost: number - total_requests: number - total_tokens: number - isOther?: boolean - }> = sortedPlatforms.value.map((p) => ({ ...p })) +const platformCards = computed(() => { + // 建立 by_platform Map + const byPlat = new Map() + for (const item of props.stats?.by_platform ?? []) byPlat.set(item.platform, item) + // 建立 quota Map + const byQuota = new Map() + for (const q of props.platformQuotas ?? []) byQuota.set(q.platform, q) + + // union 平台集合。后端 by_platform / quota 接口均不会返回 platform='__other__', + // 无需显式排除;__other__ 由下方差值补差逻辑单独追加。 + const platforms = new Set([...byPlat.keys(), ...byQuota.keys()]) + + const PLATFORM_ORDER = ['anthropic', 'openai', 'gemini', 'antigravity'] + const cards: FusedPlatformCard[] = [] + + for (const p of platforms) { + const stat = byPlat.get(p) + cards.push({ + platform: p, + total_actual_cost: stat?.total_actual_cost ?? 0, + today_actual_cost: stat?.today_actual_cost ?? 0, + total_requests: stat?.total_requests ?? 0, + total_tokens: stat?.total_tokens ?? 0, + quota: byQuota.get(p), + }) + } + + // 排序:按 PLATFORM_ORDER,未知平台按名称排序 + cards.sort((a, b) => { + const ai = PLATFORM_ORDER.indexOf(a.platform) + const bi = PLATFORM_ORDER.indexOf(b.platform) + if (ai === -1 && bi === -1) return a.platform.localeCompare(b.platform) + if (ai === -1) return 1 + if (bi === -1) return -1 + return ai - bi + }) + + // __other__ 补差逻辑:只对 by_platform 有 usage 数据的总和计算 const total = props.stats?.total_actual_cost ?? 0 const today = props.stats?.today_actual_cost ?? 0 const sumTotal = cards.reduce((s, c) => s + c.total_actual_cost, 0) @@ -237,12 +318,62 @@ const platformCards = computed(() => { today_actual_cost: diffToday, total_requests: 0, total_tokens: 0, - isOther: true + isOther: true, }) } + return cards }) +// Quota helpers + +type QuotaWindow = 'daily' | 'weekly' | 'monthly' +type QuotaField = `${QuotaWindow}_limit_usd` | `${QuotaWindow}_usage_usd` | `${QuotaWindow}_window_resets_at` + +function quotaVal(q: PlatformQuotaItem | undefined, key: QuotaField): PlatformQuotaItem[QuotaField] { + return q?.[key] +} + +function hasAnyLimit(q: PlatformQuotaItem | undefined): boolean { + if (!q) return false + return q.daily_limit_usd != null || q.weekly_limit_usd != null || q.monthly_limit_usd != null +} + +function calcPercent(usage: number, limit: number): number { + if (!limit || limit <= 0) return 0 + return Math.min(100, Math.max(0, Math.round((usage / limit) * 100))) +} + +function quotaBarClass(p: number): string { + if (p >= 95) return 'bg-red-500' + if (p >= 75) return 'bg-amber-500' + return 'bg-green-500' +} + +// 与 formatBalance 一致使用 Intl.NumberFormat 做半偶舍入,避免 toFixed 在不同 JS 引擎 +// 下偶发截断而非四舍五入(与后端展示精度不一致)。 +const usdFormatter = new Intl.NumberFormat('en-US', { + minimumFractionDigits: 2, + maximumFractionDigits: 2, +}) +function formatUsd(n: number): string { + if (!Number.isFinite(n)) return '0.00' + return usdFormatter.format(n) +} + +function formatResetTime(iso: string | null | undefined): string { + if (!iso) return '' + const d = new Date(iso) + if (Number.isNaN(d.getTime())) return iso + return d.toLocaleString(undefined, { + month: 'numeric', + day: 'numeric', + hour: '2-digit', + minute: '2-digit', + hour12: false, + }) +} + const formatBalance = (b: number) => new Intl.NumberFormat('en-US', { minimumFractionDigits: 2, diff --git a/frontend/src/i18n/locales/en.ts b/frontend/src/i18n/locales/en.ts index 53176a93..bd7ac310 100644 --- a/frontend/src/i18n/locales/en.ts +++ b/frontend/src/i18n/locales/en.ts @@ -634,6 +634,15 @@ export default { platformBreakdownEmpty: 'No platform usage yet', platformCount: '{count} platforms', platformOther: 'Other', + platformQuota: { + title: 'Quota Usage', + daily: 'Daily', + weekly: 'Weekly', + monthly: 'Monthly (30-day rolling)', + resetsAt: 'Resets {time}', + noLimit: 'unlimited', + disabled: 'Disabled', + }, tokenUsageTrend: 'Token Usage Trend', noDataAvailable: 'No data available', model: 'Model', @@ -1793,6 +1802,7 @@ export default { groups: 'Groups', subscriptions: 'Subscriptions', balance: 'Balance', + balancePlatformQuota: 'Balance (Platform Quota)', usage: 'Usage', usageAnthropic: 'Usage (Claude)', usageOpenAI: 'Usage (OpenAI)', @@ -1985,6 +1995,41 @@ export default { failedToReorder: 'Failed to update order', keyExists: 'Attribute key already exists', dragToReorder: 'Drag to reorder' + }, + platformQuota: { + menuItem: 'Platform Quotas', + title: 'Platform Quotas', + subtitle: 'Configure daily / weekly / monthly USD usage limits for each upstream platform for user {email}', + columns: { + platform: 'Platform', + daily: 'Daily (USD)', + weekly: 'Weekly (USD)', + monthly: 'Monthly (USD, 30-day rolling)', + usage: 'Current Usage', + }, + placeholder: 'unlimited', + save: 'Save', + saving: 'Saving...', + cancel: 'Cancel', + clearAll: 'Clear All (remove all limits)', + clearAllConfirm: 'Clear daily / weekly / monthly limits for ALL platforms? All platforms will become "unlimited" with no local undo — you must manually re-enter values before saving.', + reset: { + button: 'Reset window', + confirm: 'Reset the {window} usage for {platform} for this user? This is effective immediately.', + success: 'Reset {platform} {window} usage', + failed: 'Reset failed', + }, + updateSuccess: 'Platform quotas updated', + updateFailed: 'Save failed', + loadFailed: 'Load failed', + hint: 'Empty = no limit for that window.', + windowDaily: 'daily', + windowWeekly: 'weekly', + windowMonthly: 'monthly', + cellNotConfigured: 'Not configured', + cellColumnTooltip: 'Only platforms with a limit are shown', + subscriptionWarning: 'This user has an active subscription. Platform quotas only apply to balance (standard) mode requests; subscription mode requests are not subject to these limits.', + invalidNumber: 'The following fields contain invalid numbers. Please fix them before saving: {fields}', } }, @@ -5467,7 +5512,17 @@ export default { defaultSubscriptionsDuplicate: 'Duplicate subscription group: {groupId}. Each group can only appear once.', subscriptionGroup: 'Subscription Group', - subscriptionValidityDays: 'Validity (days)' + subscriptionValidityDays: 'Validity (days)', + defaultPlatformQuotas: 'Default Platform Quotas (on signup)', + defaultPlatformQuotasHint: 'Automatically assigned to new users on signup; existing users are not affected. Leave blank = unlimited.', + platformQuotaNotice: 'Monthly quota uses a 30-day rolling window, not a calendar month.', + }, + platformQuota: { + platform: 'Platform', + daily: 'Daily (USD)', + weekly: 'Weekly (USD)', + monthly: 'Monthly (USD, 30d rolling)', + placeholder: 'Unlimited', }, claudeCode: { title: 'Claude Code Settings', @@ -6188,7 +6243,9 @@ export default { grantOnFirstBindHint: 'Grant default entitlements when an existing user first binds this source.', defaultSubscriptionsLabel: 'Default subscriptions', defaultSubscriptionsHint: 'Applies only to this auth source. Leave empty to skip source-specific subscriptions.', - noSourceSubscriptions: 'No source-specific default subscriptions configured.' + noSourceSubscriptions: 'No source-specific default subscriptions configured.', + platformQuotasOverride: 'Platform Quota Overrides', + platformQuotasOverrideHint: 'Blank fields inherit the system default. Set to 0 to fully block that window for this auth source.', }, paymentVisibleMethods: { methodLabel: '{title} visible method', diff --git a/frontend/src/i18n/locales/zh.ts b/frontend/src/i18n/locales/zh.ts index b293ec67..90f168b4 100644 --- a/frontend/src/i18n/locales/zh.ts +++ b/frontend/src/i18n/locales/zh.ts @@ -633,6 +633,15 @@ export default { platformBreakdownEmpty: '暂无平台用量', platformCount: '{count} 个平台', platformOther: '其他', + platformQuota: { + title: '配额用量', + daily: '日', + weekly: '周', + monthly: '月(近30天)', + resetsAt: '{time} 重置', + noLimit: '不限制', + disabled: '已禁用', + }, tokenUsageTrend: 'Token 使用趋势', noDataAvailable: '暂无数据', model: '模型', @@ -1814,6 +1823,7 @@ export default { groups: '分组', subscriptions: '订阅分组', balance: '余额', + balancePlatformQuota: '余额(平台配额)', usage: '用量', usageAnthropic: '用量 (Claude)', usageOpenAI: '用量 (OpenAI)', @@ -2038,6 +2048,41 @@ export default { failedToReorder: '更新排序失败', keyExists: '属性键已存在', dragToReorder: '拖拽排序' + }, + platformQuota: { + menuItem: '平台限额', + title: '平台限额', + subtitle: '为用户 {email} 配置各上游平台的日 / 周 / 月用量上限', + columns: { + platform: '平台', + daily: '日 (USD)', + weekly: '周 (USD)', + monthly: '月 (USD, 30天滚动)', + usage: '当前用量', + }, + placeholder: '不限制', + save: '保存', + saving: '保存中...', + cancel: '取消', + clearAll: '全部清空(取消所有限额)', + clearAllConfirm: '确认清空全部平台的日 / 周 / 月限额?所有平台将变为"无限额",本地无法撤销,需要在保存前手动重填。', + reset: { + button: '重置该窗口', + confirm: '确认重置该用户 {platform} 平台的 {window} 用量?此操作立即生效。', + success: '已重置 {platform} {window} 用量', + failed: '重置失败', + }, + updateSuccess: '平台限额已更新', + updateFailed: '保存失败', + loadFailed: '加载失败', + hint: '留空 = 不限制该窗口。', + windowDaily: '日', + windowWeekly: '周', + windowMonthly: '月', + cellNotConfigured: '未配置', + cellColumnTooltip: '仅展示已设限额的平台', + subscriptionWarning: '此用户有活跃订阅,平台限额仅在余额(标准)模式下生效,订阅模式请求不受此限额约束。', + invalidNumber: '以下字段填写不是合法数字,请修正后再保存:{fields}', } }, @@ -5626,7 +5671,17 @@ export default { defaultSubscriptionsEmpty: '未配置默认订阅。新用户不会自动获得订阅套餐。', defaultSubscriptionsDuplicate: '默认订阅存在重复分组:{groupId}。每个分组只能出现一次。', subscriptionGroup: '订阅分组', - subscriptionValidityDays: '有效期(天)' + subscriptionValidityDays: '有效期(天)', + defaultPlatformQuotas: '默认平台限额(注册时分配)', + defaultPlatformQuotasHint: '新用户注册时自动写入平台限额记录;已有用户不受影响。留空 = 该平台该窗口不限制。', + platformQuotaNotice: '月限额为 30 天滚动窗口,非自然月', + }, + platformQuota: { + platform: '平台', + daily: '日限额 (USD)', + weekly: '周限额 (USD)', + monthly: '月限额 (USD, 30天滚动)', + placeholder: '不限', }, claudeCode: { title: 'Claude Code 设置', @@ -6346,7 +6401,9 @@ export default { grantOnFirstBindHint: '已有账号首次绑定该来源时发放默认权益。', defaultSubscriptionsLabel: '默认订阅', defaultSubscriptionsHint: '仅对当前认证来源生效,未配置时不追加来源专属订阅。', - noSourceSubscriptions: '当前来源未配置专属默认订阅。' + noSourceSubscriptions: '当前来源未配置专属默认订阅。', + platformQuotasOverride: '平台限额覆盖', + platformQuotasOverrideHint: '留空的字段继承「系统默认平台限额」;填 0 表示禁止该窗口使用。', }, paymentVisibleMethods: { methodLabel: '{title} 可见方式', diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts index 63b9b14f..632e5108 100644 --- a/frontend/src/types/index.ts +++ b/frontend/src/types/index.ts @@ -1854,3 +1854,11 @@ export interface UpdateScheduledTestPlanRequest { // Payment types export type { SubscriptionPlan, PaymentOrder, CheckoutInfoResponse } from './payment' + +export type { + PlatformQuotaItem, + PlatformQuotaUpdateItem, + PlatformQuotaPlatform, + PlatformQuotaWindow, + PlatformQuotasResponse, +} from '@/api/admin/users' diff --git a/frontend/src/views/admin/SettingsView.vue b/frontend/src/views/admin/SettingsView.vue index d3fac4d5..68eb4849 100644 --- a/frontend/src/views/admin/SettingsView.vue +++ b/frontend/src/views/admin/SettingsView.vue @@ -3262,6 +3262,71 @@ + + +
    +
    + +

    + {{ t("admin.settings.defaults.defaultPlatformQuotasHint") }} +

    +

    + {{ t("admin.settings.defaults.platformQuotaNotice") }} +

    +
    +
    + + + + + + + + + + + + + + + + + +
    {{ t("admin.settings.platformQuota.platform") }}{{ t("admin.settings.platformQuota.daily") }}{{ t("admin.settings.platformQuota.weekly") }}{{ t("admin.settings.platformQuota.monthly") }}
    + {{ p }} + + + + + + +
    +
    +
    + @@ -3535,6 +3600,68 @@ + + +
    +
    + +

    + {{ t("admin.settings.authSourceDefaults.platformQuotasOverrideHint") }} +

    +
    +
    + + + + + + + + + + + + + + + + + +
    {{ t("admin.settings.platformQuota.platform") }}{{ t("admin.settings.platformQuota.daily") }}{{ t("admin.settings.platformQuota.weekly") }}{{ t("admin.settings.platformQuota.monthly") }}
    + {{ p }} + + + + + + +
    +
    +
    + @@ -6530,6 +6657,8 @@ import { adminAPI } from "@/api"; import { appendAuthSourceDefaultsToUpdateRequest, buildAuthSourceDefaultsState, + normalizePlatformQuotasMap, + sanitizePlatformQuotasMap, defaultWeChatConnectScopesForMode, deriveWeChatConnectStoredMode, normalizeDefaultSubscriptionSettings, @@ -6541,6 +6670,7 @@ import type { SystemSettings, UpdateSettingsRequest, DefaultSubscriptionSetting, + DefaultPlatformQuotasMap, OpenAIFastPolicyRule, WeChatConnectMode, WebSearchEmulationConfig, @@ -6835,6 +6965,8 @@ type SettingsForm = Omit< google_oauth_client_secret: string; force_email_on_third_party_signup: boolean; openai_advanced_scheduler_enabled: boolean; + // 系统全局平台限额 map;form 内始终归一化为全 4 平台对象(模板非空绑定依赖此不变量) + default_platform_quotas: DefaultPlatformQuotasMap; }; const form = reactive({ @@ -6851,6 +6983,7 @@ const form = reactive({ login_agreement_updated_at: "2026-03-31", login_agreement_documents: defaultLoginAgreementDocuments(), default_balance: 0, + default_platform_quotas: normalizePlatformQuotasMap() as DefaultPlatformQuotasMap, affiliate_rebate_rate: 20, affiliate_rebate_freeze_hours: 0, affiliate_rebate_duration_days: 0, @@ -7659,6 +7792,7 @@ async function loadSettings() { })) : defaultLoginAgreementDocuments(); Object.assign(authSourceDefaults, buildAuthSourceDefaultsState(settings)); + form.default_platform_quotas = normalizePlatformQuotasMap(settings.default_platform_quotas); form.backend_mode_enabled = settings.backend_mode_enabled; form.default_subscriptions = normalizeDefaultSubscriptionSettings( settings.default_subscriptions, @@ -8212,6 +8346,7 @@ async function saveSettings() { }; } + payload.default_platform_quotas = sanitizePlatformQuotasMap(form.default_platform_quotas); appendAuthSourceDefaultsToUpdateRequest(payload, authSourceDefaults); const updated = await adminAPI.settings.updateSettings(payload); @@ -8222,6 +8357,7 @@ async function saveSettings() { } } Object.assign(authSourceDefaults, buildAuthSourceDefaultsState(updated)); + form.default_platform_quotas = normalizePlatformQuotasMap(updated.default_platform_quotas); registrationEmailSuffixWhitelistTags.value = normalizeRegistrationEmailSuffixDomains( updated.registration_email_suffix_whitelist, diff --git a/frontend/src/views/admin/UsersView.vue b/frontend/src/views/admin/UsersView.vue index 512bae67..93c70c6b 100644 --- a/frontend/src/views/admin/UsersView.vue +++ b/frontend/src/views/admin/UsersView.vue @@ -420,6 +420,17 @@ + + @@ -673,6 +684,15 @@ {{ t('admin.users.withdraw') }} + + +