+ o w9 @& t* b9 D# 配置跨域问题 j) T. ]9 @4 [8 corigins = [ / Z! j* f4 V- K! ? "http://localhost:8000",* D1 x- x0 A7 x- b7 M9 j+ z
"http://localhost:3000"7 G, d2 [! N* D. j# Y$ G
] " }; V% e& i: u4 V' F 0 |& j1 {4 |' C1 a% G9 ~0 b( {9 Q# 全局主题模型训练对象 " F! B# k6 e, Q _topic_model_training_tasks: Dict[str, TopicModelTrainingTask] = {}8 ~; ~) F, R( b6 }, J, q: T* e! `8 r
6 _# P% ]% C; X
app.add_middleware(4 D2 L8 v/ c: C: `8 o8 m
CORSMiddleware,; V- B; w" x, y, {6 L/ j; n5 n
allow_origins=origins, ( b2 H( s- n H6 [9 {- B allow_credentials=True," v, s6 |- p/ v |" j5 _
allow_methods=["*"],( |; O f- |- {3 t
allow_headers=["*"], $ b+ w' L( U' C+ u! W)* i" \' G0 o$ V; T
2 o8 t1 d3 J' q9 o7 |- [7 A6 z4 S0 V- Q0 T" ?5 {0 d
# 数据库连接依赖 - F$ c1 `% j5 f8 N v% }% p. Cdef get_db():9 M% W) E, k4 `( R$ h+ X. k+ j
try: , c. w [. y9 O% w* z& D db = SessionLocal()6 x" q8 c' `# f8 ^, U8 q+ V: w* p
yield db 0 B' V# M5 n7 M: _( H% C/ o1 U finally:9 d$ S: g" V+ i" j
db.close() & A, @% A8 F6 C1 R6 M7 d& d3 q ' r' O% _1 ]. u0 g , _, k* a; `0 d2 ?3 B, j, H# G! j6 o@app.get( % ^$ G7 q3 e# ^. P3 ^ w "/bilibilivideos/", 9 S) }! A/ M/ K7 p+ y! | response_model=List[schemas.BilibiliVideo],; [; p# V; I4 h) d- V
tags=['bilibili视频评论语料库数据接口']# D6 d( z+ w- A3 D( \* \6 J
) - |5 M. V+ b; O- \def get_bilibili_videos(db: Session = Depends(get_db)): ! a' u+ \" e- [4 ~3 F* { db_videos = crud.get_bilibili_videos(db) 4 m6 t3 G5 H+ W* ] return db_videos2 c6 k' p; d' u
/ I/ @7 I" @8 `% g* h+ q
3 X- V ]* L7 d" g4 x) }
@app.get( ' {$ K5 v2 ^$ ]& `7 }' y! M "/bilibilivideos/{vid}/", G- C9 B% X+ W: u8 r0 ?" D1 v
response_model=schemas.BilibiliVideo,9 j& K0 \. e+ m2 A2 a+ b& q2 j' V
tags=['bilibili视频评论语料库数据接口']7 c1 z9 \" ^- }# ~8 {
) & O [2 g! \$ F m7 [% z' f6 qdef get_bilibili_videos_by_vid(vid: int, db: Session = Depends(get_db)): ; k* O* [0 Z, ?, H db_video = crud.get_bilibili_videos_by_vid(vid, db) ( {+ ~% I, Q5 g- x* e return db_video3 m: X* s: {* J. ^
- W$ ^# s, N/ p4 V- A! i5 e
( {/ V! Z3 b$ @& r+ q
@app.get(, @: j! p/ |, V/ m
"/bilibilivideos/{vid}/comments/", * G; g) `6 J: ]$ G response_model=List[schemas.BilibiliVideoComment],3 i, ` W- f) U4 S# ~1 O+ y
tags=['bilibili视频评论语料库数据接口'] 4 y$ }5 O5 r& T {) ; X. j/ q) `. Pdef get_bilibili_video_comments_by_vid(vid: int, db: Session = Depends(get_db)): * u6 [1 @( V* K# \+ T6 S db_comments = crud.get_bilibili_video_comments_by_vid(vid, db) 4 s: {4 v$ x1 \; W9 i8 S8 r) E; l return db_comments/ m. R9 G! m$ V
$ f6 q4 R+ A9 Y( c- p# x$ O% Q, U
7 i) f' }, l' T; P@app.get( 8 N) V9 O# P; ^" t) F "/onlineShoppingReviews/",3 T9 e; t% r' S9 k
response_model=List[schemas.OnlineShoppingReview],. O$ Q+ p$ y+ R" F: g
tags=['电商购物评价语料库数据接口'] , p( G: n+ T/ M- J' x) 4 ^' Z. d7 S. C9 `/ k2 {def get_online_shopping_reviews(db: Session = Depends(get_db)): $ U, d, l1 t8 m( A4 S: B3 u db_reviews = crud.get_online_shopping_reviews(db) 7 E6 P8 X$ \8 Z! _ return db_reviews9 z) {) }0 s3 e
( E# M9 u L- p1 j0 Y
' P# `7 f( ]* d+ H' X; E& [
@app.get(8 v1 B* [* T/ j1 ]/ j' Z
"/takeawayReviews/", ) v+ j& Z- [5 @7 P response_model=List[schemas.TakeawayReview], * I0 V9 B2 M i0 G- H" D' { tags=['外卖评价语料库数据接口'] ' w( L* G8 ~7 S- p3 a- K& z& X) - B- Q2 U* P$ ~8 Qdef get_takeaway_reviews(db: Session = Depends(get_db)):. d- C7 B( ^' ~$ e: R0 o4 c; z
db_reviews = crud.get_takeaway_reviews(db)( ^& f# g5 G& X4 T9 B- p/ @
return db_reviews " K) G5 j1 }# u0 K5 S. D1 K6 T1 L6 G; e: ? f! F
/ A* ?3 x7 D& G7 F' e5 q' R7 ?: ]7 ~@app.get(, W) @3 B4 S0 }( l& d& \# \2 n% ?) b
"/chineseLyrics/", , c5 @5 g/ i" b- ^ response_model=List[schemas.ChineseLyrics],9 S1 y. ?6 N5 A t# Y( o
tags=['中文歌歌词语料库数据接口'] * ?: z; \8 N* d6 A* T m( O)8 i w8 y1 ?% ]) S
def get_chinese_lyrics(db: Session = Depends(get_db)): r, W- K8 p: I1 E( S& c3 @8 {9 m/ L db_reviews = crud.get_chinese_lyrics(db)7 @, R8 W, a% |) b
return db_reviews. E. Y3 ^. w1 Y- m* @2 t/ z
1 r; r8 y5 |! S1 \, u9 ^; J& P0 F! R+ s
@app.get(# F. R1 N6 Q- @* Z* m! d
"/COVID19News/",* k! z7 ]% v% Q+ q
response_model=List[schemas.COVID19News],) H) G+ m: O3 A' e7 A
tags=['新冠病毒新闻语料库数据接口']$ t$ d: F; O; N6 _9 h
) . }( V# y/ F4 J _def get_COVID19_news(db: Session = Depends(get_db)):/ ~6 K" L5 ]( g0 v+ @$ J2 _! Z
db_reviews = crud.get_COVID19_news(db) . s5 i. j9 t% C" u2 e. a2 R return db_reviews& b) d- Q2 p; e. L3 ^9 L) p+ p
- I* K5 U9 o7 j: O( O* d) ]/ O/ I/ J7 B8 g( r( X4 c
# 为每个用户设置uuid标识符,并存入Cookie 2 S! q8 [4 ~8 G+ _) q! Jdef create_user_uuid_and_set_cookie(response: Response): & Y* {4 F/ ~7 Q9 c% a# d user_uuid = str(uuid.uuid1()) % x' z% z. k' Z& s- p response.set_cookie(key="user_uuid", value=user_uuid)" [! ?# H8 w) y Q, [
return user_uuid * r( f+ y3 |1 M8 C1 B. z : Z: Z: O- t& [% Z9 Q; ?! G% ]+ i0 j+ Q
@app.post( 1 i/ [* l+ N6 C6 W- \6 v4 ]5 y "/calculate/preprocessing/",4 o8 A' A- Q. ]' R' h+ Y/ S# b
tags=["计算模块数据接口"]- }! y5 I% N6 j6 s) h
) 6 y8 d+ M. H+ c. Hasync def run_text_preprocessing_task(text_preprocessing_params: TextPreprocessingParams," K3 d8 }" ?: B2 q( j! p" a& ~
background_task: BackgroundTasks,; r/ n0 F/ \5 v
response: Response, 8 P" D( U/ j! r8 f- f3 U8 h user_uuid: str = Cookie(None)):7 z' b6 O% C/ V7 [( @' h
if not user_uuid: X+ i1 }' e+ X2 Q
user_uuid = create_user_uuid_and_set_cookie(response)4 }% [ g+ V* C. @
" ]3 C( v' V; f% w8 C5 u# {
global topic_model_training_tasks , w0 c+ N' n4 N3 @! v$ M9 o" K task = TopicModelTrainingTask(text_preprocessing_params) % q8 I) o; q( X1 v) w topic_model_training_tasks[user_uuid] = task& n' U2 L- m4 G8 ?# T5 q6 t1 h
3 w$ f3 M- n0 g
background_task.add_task(task.preprocessing) , F6 Y( u6 u' G* C3 ` return {"message": "已添加文本预处理后台任务"}- {, h( M" J8 I/ w5 _9 w: `
/ c9 z. G w. f& G
- G/ T2 w2 ?! D7 h* D5 J( ]# x: d
@app.post(+ b, H: F$ A: T& s
"/calculate/nmftraining/", 0 x5 P! W* n1 w+ j3 c tags=["计算模块数据接口"] # M2 k& }, ^; U; d) X/ [) ( N% i2 u9 L7 {! ]async def run_nmf_training_and_tsne_task(nmf_training_params: NMFTrainingParams,( x) m& b7 Z, q5 d3 [7 ]) C( Z4 f
background_task: BackgroundTasks, + q0 ]# G+ c8 @5 s/ p- r% l- m( } response: Response, $ y" K6 T; m' }! V# W user_uuid: str = Cookie(None)): ( Y, e. ~, H. y/ p$ C3 Z1 o2 | if not user_uuid: 0 N& K9 x: ` d user_uuid = create_user_uuid_and_set_cookie(response). h! D0 d' B! R) A8 M/ f8 \
0 K; c- Q0 Z1 W m6 P& U
global topic_model_training_tasks + E$ q( c; A$ s6 ]: K # j8 R H/ \6 a- {# Z% a9 S if user_uuid and user_uuid in topic_model_training_tasks: & J# J! _; ~; F) ] task = topic_model_training_tasks[user_uuid] # U2 f# i2 r+ ?4 j$ `& g if task.text_preprocessing_progress.status_code == 2:, c# {3 \8 r" _ \- Z( O1 U
background_task.add_task(task.nmf_training, nmf_training_params)0 n6 g: r8 Q/ w7 K) Y/ z
return {"message": "已添加NMF主题模型训练后台任务"}' s$ x/ A2 q- O6 E2 `* a
else:, q- ?7 _- V+ J$ ^
raise HTTPException(status_code=404, detail="请先进行文本预处理任务!") / l% i0 b' W4 j0 v$ Z else: ) m/ E% k8 j' Q5 z, C3 C raise HTTPException(status_code=404, detail="未找到相应的训练对象!")& g+ d& A1 a' |& D
5 A: z! c; L0 A% b: q0 {) X+ a8 e % O& G& N3 m# m( p9 n/ C5 n* h@app.get( 4 S) f" t& v: @ "/calculate/nmftraining/keywordsearch/",8 ~7 F7 j& U1 p( X8 L& ]
response_model=KeywordSearchResult, 5 L/ C) G# k# M. V. H$ s tags=["用户交互"]3 R4 d4 n8 `& t; ^. |% A; I
) 5 r4 v4 M5 }. ?) y; pasync def search_keyword(search_text: str, # A0 c) h! ^6 R% @ response: Response, / y; Z" i6 f- i% p1 Z& a4 E user_uuid: str = Cookie(None)): 5 t6 B( r/ e5 R0 o1 ?* k3 M6 j if not user_uuid:$ l; e' K. @* o1 Z+ [! E) ?! @
user_uuid = create_user_uuid_and_set_cookie(response)9 k$ ?8 R+ Q# t ?( \! h5 z
: g4 n$ O# ?* Q+ d2 o B2 v( I/ L global topic_model_training_tasks _ i, i" b3 `! C
& ?8 w7 D6 D) f1 z+ ~. n2 K
if user_uuid and user_uuid in topic_model_training_tasks: . c$ e# c9 Z+ {; h4 r task = topic_model_training_tasks[user_uuid]' l o3 S9 z* @* L0 ]: E
if task.text_preprocessing_progress.status_code == 2:# G( e' C1 N r
search_text = search_text.lower() 0 _: ]5 S8 q5 D1 ]$ p+ I, o bag_words = task.text_preprocessing.bagWords 8 ^' B2 }& f; E& R- B keyword_search_result = KeywordSearchResult() 0 o+ H/ L. |: R, P5 a! j! F for wi, word in enumerate(bag_words): : s+ W, K: U4 g% y: s" Z if search_text in word: w! o. z# A" A0 }' P2 m keyword_search_result.word_id_list.append(wi): \' F0 T& {0 C5 y5 v
keyword_search_result.word_list.append(word) 6 X; [, r$ _* N return keyword_search_result 4 D( d( R( x j; [( m+ z. ^ else: . J( ~ E4 R7 I7 o/ ~( Z+ i raise HTTPException(status_code=404, detail="请先进行文本预处理任务!")$ w9 _* |& m% ]' r8 Y5 r* C
else: " K- ]; `* |5 R4 z4 A raise HTTPException(status_code=404, detail="未找到相应的训练对象!") " S0 z0 Z" z8 T; [3 g ]$ K) k0 X' |, `% s# z. E
! Z1 f- c p# c9 F; ?@app.post( ) d n- ]4 x) `: Q2 [ "/calculate/nmftraining/topickeywordoptimization/", # N# j6 i# a4 U: O) U" O. J ? tags=["用户交互"]6 I) a! K7 A% ^7 F
) ! M% \6 T3 N* N9 T; xasync def run_topic_keyword_optimization_task(tko_params: TopicKeywordOptimizationParams,7 m. D0 W7 |" x7 t% H8 c2 p
background_task: BackgroundTasks,( t! M' A0 x7 g+ I- G, j: C
response: Response,: V7 q: K! q N3 x6 X
user_uuid: str = Cookie(None)): " h6 t2 t9 k* {# Q" ^ if not user_uuid:7 o3 x/ S) b6 W
user_uuid = create_user_uuid_and_set_cookie(response) # V! ^6 v7 W9 g6 L( `/ ~- a* d- ~/ ]! {# m* S2 m2 z7 U! L. a& J6 P& L
global topic_model_training_tasks ) _( `$ K' _/ k3 o2 T - ?' Q" y8 {+ |6 f: Z. R if user_uuid and user_uuid in topic_model_training_tasks: : \* G" x. T! }$ M+ N task = topic_model_training_tasks[user_uuid]- `9 W `: E8 W+ k- f8 j* F
if task.nmf_training_progress.status_code == 2: * |" {& ^4 H" l9 e background_task.add_task(task.topic_keyword_optimization, tko_params)8 j# X4 n. s+ X
return {"message": "已添加主题关键词优化后台任务"} ) f6 _5 _3 S( J/ J& [) R else:1 }, G3 h6 a4 V1 y% P! S
raise HTTPException(status_code=404, detail="请先等待NMF训练结束!")4 `& H% Y, c9 j
else:( Q, W8 m% Q1 N2 `( K4 |& G
raise HTTPException(status_code=404, detail="未找到相应的训练对象!") : c! i0 H4 {" F$ V n " ?4 u5 y/ Y+ C8 d( D8 @! V" F1 M% q
@app.post( & u. Y+ y; A* h) V$ T% w "/calculate/nmftraining/topicsplit/",9 @2 u. c! g d5 [9 l& i+ ^5 b; `" X
tags=["用户交互"] $ Q! i9 g. |& W! u! b) j& K# a2 u' `async def run_topic_split_task(ts_params: TopicSplitParams,, M. H- r; p1 b# m+ W2 ]4 v
background_task: BackgroundTasks, ; G- y) F! V+ |) }. | response: Response,/ ]. V9 J( [+ v0 n$ S# s* v
user_uuid: str = Cookie(None)): 4 N" y* U# b. X8 M7 Z" e4 X( k if not user_uuid: - r1 ?1 _7 d# S/ b0 Q5 I user_uuid = create_user_uuid_and_set_cookie(response)4 p- s" G6 {; k8 \2 Y* F
, b9 V% M r3 D6 @4 N: {: q- t% f global topic_model_training_tasks+ {' O0 g! g0 b
1 k3 |% f% i0 S. J' z% b5 O) d if user_uuid and user_uuid in topic_model_training_tasks: ' M- e; w3 c, A2 F; y task = topic_model_training_tasks[user_uuid] * a- h6 o( e: a1 j3 S* [ if task.nmf_training_progress.status_code == 2: " |* K! c0 ?$ A; t background_task.add_task(task.topic_split, ts_params) : R+ H5 }2 w( w+ y! g3 B2 n3 Z return {"message": "已添加主题拆分后台任务"} " [) }6 q% n) b9 J9 p0 Q( ^- B else: % E6 T7 \* H/ ?4 L/ l raise HTTPException(status_code=404, detail="请先等待NMF训练结束!")# S9 o N( Q x! N% r
else: : f0 d; V4 A/ v) @$ S raise HTTPException(status_code=404, detail="未找到相应的训练对象!")2 c4 y) K# k& i( U1 l5 P$ N" s+ q* F r
, a4 u9 b* ]7 H$ K3 k
9 `5 I, ?0 o! t% m- l4 }* i! G3 n4 ?
@app.post(+ ], T9 N7 a. p3 `
"/calculate/nmftraining/topicmerge/", : S1 V8 e9 U0 m tags=["用户交互"] 0 Z% c2 c) z& a' Z)- j# e, n0 v# J# H9 s& N( g( Y- F( d
async def run_topic_merge_task(tm_params: TopicMergeParams,. v5 i4 |7 |0 w( K P
background_task: BackgroundTasks, ^( u5 H$ |3 p/ M5 \. j7 w response: Response,5 d: c0 W1 e3 i
user_uuid: str = Cookie(None)): , f% v+ m0 C" k# ? if not user_uuid:; c& T1 X6 U9 m1 q6 m; I q
user_uuid = create_user_uuid_and_set_cookie(response) ) _- s; E! L- j7 g8 x7 e1 a% Y$ I: [) O
global topic_model_training_tasks 1 }3 i9 J0 V4 m& N: _0 H9 V5 a+ x& l
if user_uuid and user_uuid in topic_model_training_tasks:0 L+ G$ w2 Z. |6 b- i. [) r. {6 g
task = topic_model_training_tasks[user_uuid]( L1 \/ W! |' p% d& m3 y* I4 s
if task.nmf_training_progress.status_code == 2: * i! c- S% g6 G7 A* P _ background_task.add_task(task.topic_merge, tm_params)' c0 O! V5 [" p# I7 u
return {"message": "已添加主题合并后台任务"}$ Y" o; ~6 f2 Q! L' T
else: 7 J0 D6 Y M5 Y/ k n7 R raise HTTPException(status_code=404, detail="请先等待NMF训练结束!")) U0 {" ?2 E4 {$ I1 m6 W
else:; |9 Z$ Y: j: g5 s! ? l
raise HTTPException(status_code=404, detail="未找到相应的训练对象!")& H) `! f' W' @
/ e8 ^" R* i Z! v4 }" e4 `5 ^9 _& f+ }$ K' ?4 g
@app.post( + J3 o5 U- B' }1 E. f "/calculate/nmftraining/keywordinducedtopiccreate/",6 |# f- h8 Q4 z" u
tags=["用户交互"]" M6 A3 W1 b/ W5 `" l
) 2 O2 O" a" f7 S0 L' I7 Kasync def run_keyword_induced_topic_create_task(kitc_params: KeywordInducedTopicCreateParams, , U @" b# g+ F* V* W# x5 E background_task: BackgroundTasks,6 B9 X' q* F7 b, l
response: Response, 0 q W- \" o" L9 M5 U! z, E3 \) m: ? user_uuid: str = Cookie(None)):+ c8 \( w; |8 e }
if not user_uuid:8 `: {; J6 z6 F! E; A. o8 V
user_uuid = create_user_uuid_and_set_cookie(response)8 ?, A- r9 E* n: q, G" ?
/ X+ g+ x8 {+ j- z' h/ v/ j. `
global topic_model_training_tasks4 u5 Z. E! b" O6 j, V0 F
8 V$ i, \9 d& @) Z/ K if user_uuid and user_uuid in topic_model_training_tasks:# o6 a- T1 g8 d: [
task = topic_model_training_tasks[user_uuid]+ ?# N3 q0 C6 l5 c
if task.nmf_training_progress.status_code == 2: 1 ], Y6 L7 K; T7 W* ^1 | background_task.add_task(task.keyword_induced_topic_create, kitc_params)+ ?' U+ P r7 A0 o
return {"message": "已添加关键词诱导主题创建后台任务"}$ } w c# y3 J# T1 S9 h9 H
else:- w; D4 Q2 ]4 ], o% E" X, w
raise HTTPException(status_code=404, detail="请先等待NMF训练结束!") & ~9 Z' n. h" [2 J else:$ |9 m! k/ E0 V* V1 p
raise HTTPException(status_code=404, detail="未找到相应的训练对象!")5 m) _/ ~: z, U r) g0 g e
Y0 S/ W' z8 M1 {+ \( A% l
7 g$ ?5 N; N% P" T. @7 ~* [/ D
@app.post(! m" l) Y) u* d* _2 ]9 l* o1 |% J
"/calculate/nmftraining/documentinducedtopiccreate/",0 g% W) x- e4 `" Z: U7 k
tags=["用户交互"] 4 ]4 C3 a9 p) V# m9 M) z)" u/ P$ J3 M) ^2 R( i
async def run_document_induced_topic_create_task(ditc_params: DocumentInducedTopicCreateParams,9 `2 u& K! R- H+ I
background_task: BackgroundTasks,- e# m8 \6 F) ~
response: Response, $ P/ U7 S0 p& n2 T( o. H" I4 M5 N4 c [ user_uuid: str = Cookie(None)): 3 O/ g( p) o0 c* I4 T, d4 B1 e; a if not user_uuid: ( k- p0 q( l! V! }& L f' A user_uuid = create_user_uuid_and_set_cookie(response)% [% C/ e- M9 z; w3 j3 d: {' t* s
2 l4 L9 _: ]% t! P9 T2 s
global topic_model_training_tasks , h1 B( g( q5 E ?! s# } + }; L+ E& [2 [ if user_uuid and user_uuid in topic_model_training_tasks: 0 M5 E, y+ _0 b, l& e- K* p task = topic_model_training_tasks[user_uuid] ; D% k! T8 Y* O8 p$ u if task.nmf_training_progress.status_code == 2: - K# N+ T% E4 v8 L2 K background_task.add_task(task.document_induced_topic_create, ditc_params) ! A; o! e$ d- J& N8 \ return {"message": "已添加文档诱导主题创建后台任务"} 8 [- ~, ` O) b* J# T/ y) ~ else:/ P5 [5 R/ ~* K( Z; a: m' v
raise HTTPException(status_code=404, detail="请先等待NMF训练结束!") 2 C, q5 t' V O' u P2 \ else: 6 Y3 b5 ^- T0 b4 p9 D3 U% w raise HTTPException(status_code=404, detail="未找到相应的训练对象!") 4 ^4 \9 x& ?+ a n9 G4 c# E }+ G7 C4 ?0 L; r# @ Q
J+ y- a. C: Q@app.get( ; v% Y8 Z) [& S4 h6 V1 Q "/calculate/nmftraining/newdoctopicdistributionpredict/",1 b# [( S/ t! d8 j
tags=["主题预测"]" ?+ q' }1 h$ p/ J* j) V
)" X. I1 Z/ x4 k3 `
async def run_new_document_topic_distribution_predict_task( % g* Q3 T; p- t$ R+ w new_doc_text: str, 3 y& O d- G0 h- { background_task: BackgroundTasks, - r* ~5 Q0 b1 p* b- i# }( N% a/ ` response: Response,! r$ `# C( R0 s; k e
user_uuid: str = Cookie(None)):0 f8 L" ~. t# z" [8 _5 A( v! W- C
if not user_uuid:3 e3 x0 J% U, C; v, A% t
user_uuid = create_user_uuid_and_set_cookie(response), t+ c# d) y G0 T
: ~; |7 R. D2 v7 P) F global topic_model_training_tasks7 `; n" X' T! }. Y3 v3 C2 U
! V: A, W5 W3 z4 u
if user_uuid and user_uuid in topic_model_training_tasks:4 D" h; ~6 P+ U& \/ w
task = topic_model_training_tasks[user_uuid] & c) N% \0 M4 r8 y, L if task.nmf_training_progress.status_code == 2: 6 z- P: m# t u; K* Q6 `' {" h- A background_task.add_task( 3 [$ [; I1 e6 J' |. C8 A) k. I9 a task.new_doc_topic_distribution_predict,1 B* Z8 K. F) z9 Z5 m* i" j1 S
new_doc_text - U4 b) O0 _$ G3 l j l! G$ @ )4 d/ |( {* q* S5 u
return {"message": "已添加新文档主题分布预测后台任务"} 6 {: N3 ~2 H7 F4 U" g5 ~$ O" } else:$ ]' R H; `% h& p2 Z
raise HTTPException(status_code=404, detail="请先等待NMF训练结束!")% U8 a) r" g$ s" a% `" O: F- ?: m
else:/ w- P( Y* E/ g( z
raise HTTPException(status_code=404, detail="未找到相应的训练对象!") & q Q- @. o$ l( l( r2 p # e3 q( V* p: E4 N2 F+ w% H5 @) L5 ^+ ` T( A
@app.get( 5 _. m: y0 C! h1 l F3 W "/calculate/preprocessing/progress/", % O) z) C0 S( Q: n1 y tags=["计算模块数据接口"], / R! x5 q7 T& h$ Y7 P l/ K$ t; n response_model=TextPreprocessingProgress K- J) Y# w9 u0 @7 k8 }
): ~) D+ I; s* R g4 P
def get_text_preprocessing_task_progress(user_uuid: str = Cookie(None)):: D5 ^! Y- m, `/ M5 Q0 E% l- B; _
global topic_model_training_tasks . Z7 T2 Y/ C( q% R5 m& w: H3 d9 f/ e; i! s, |) U, Q
if (not user_uuid) or (user_uuid not in topic_model_training_tasks): * q" ] Q/ H$ q# Q2 ~4 J6 I9 r6 E raise HTTPException(status_code=404, detail="未找到相应的训练对象!")% U' P ?# ]3 s* n
return topic_model_training_tasks[user_uuid].text_preprocessing_progress 8 [! ?) d* M9 ?6 k4 \9 x) T 3 D9 W' S% b) w" @4 @; F9 L* m6 L7 O: X% _
@app.get(8 k* j+ i' f: V7 _- [% _
"/calculate/nmftraining/progress/", 0 x+ J/ v. m6 O, K tags=["计算模块数据接口"], ; p0 @- W- _( t! ]: r response_model=NMFTrainingProgress % C { R6 U6 m" {6 _) % z& ~, d# R3 I7 D& D1 U3 Vdef get_nmf_training_task_progress(user_uuid: str = Cookie(None)): ( s9 Q( e# R% R, z2 d9 \6 {5 e8 } global topic_model_training_tasks( Y/ I1 U. k8 k1 P* m- ?
& ~2 I2 k& \. `( s
if (not user_uuid) or (user_uuid not in topic_model_training_tasks):: G. ~* z0 ?; m* ?4 V1 ^
raise HTTPException(status_code=404, detail="未找到相应的训练对象!")9 Y1 J. }2 v0 _4 X2 p/ K4 y
/ J S% ~$ P1 _; q& B
task = topic_model_training_tasks[user_uuid] J! D+ ^$ B% v4 t( T+ e; P if task.text_preprocessing_progress.status_code == 2: ' B: L, G, n6 s& |: M) R3 k& T7 F, A return task.nmf_training_progress 2 D1 {1 `7 S$ I" C$ W1 O4 ]! ] else:4 J6 U0 ^4 C2 m8 @
raise HTTPException(status_code=404, detail="请先进行文本预处理任务!")) F* n* w2 z5 T: ^7 l
& e2 C; ~7 b5 C$ ?! `& l) T6 F" i8 ?/ r7 `. Q
@app.get( * R7 K( `7 s. d9 Z- k2 s5 y "/calculate/umap/progress/", : m: @/ A) `& W0 a tags=["计算模块数据接口"],( u' F. Q* m2 B# y
response_model=UMAPProgress) u7 P+ t% e3 J+ p5 X
)7 s; {# H9 v1 j2 ?, ^; L. z" l2 \% B _
def get_umap_task_progress(user_uuid: str = Cookie(None)): 2 t5 H; k% y% F# S, r" j: K9 v3 N global topic_model_training_tasks / U6 A3 d) m- y2 Q3 V' M% K& j/ n' f0 h4 [5 N* n: o- K* w
if (not user_uuid) or (user_uuid not in topic_model_training_tasks): , l1 K7 I u4 y Y1 u: @ raise HTTPException(status_code=404, detail="未找到相应的训练对象!")0 K, j9 @: D$ G8 q' c S) s6 t
* y3 | S1 v" D3 S8 c task = topic_model_training_tasks[user_uuid] 9 Z1 d% A. s% i5 x$ E$ A! V! N if task.nmf_training_progress.status_code == 2: 5 `# ^% M! c2 x* ]; { return task.umap_progress ! y& N; P5 G9 t! i8 z; T else: % V" j0 J* A: V raise HTTPException(status_code=404, detail="请先等待NMF训练结束!") 7 t* Y0 j$ \9 u- X3 q, @- a0 A" J4 z- q8 U) p: i' \
2 p2 @& s- l: Z ~# S8 G% t u
@app.get( . `8 r% k3 {: L4 V "/calculate/nmftraining/predict/progress/", 8 K6 J: R- n P tags=["计算模块数据接口"],* {/ q. W; J1 C& l
response_model=NewDocTopicDistributionPredictProgress , p9 r& E5 |/ n" A( w) & v) q" w" M" E: Y8 }9 vdef get_new_doc_topic_distribution_predict_task_progress(user_uuid: str = Cookie(None)): 4 i, Q# @) L- F4 q' h" t; K$ Y, [ global topic_model_training_tasks 4 n' [# \! j/ t8 V" f* n4 k$ g # _+ V8 E5 v" h2 c* o0 v if (not user_uuid) or (user_uuid not in topic_model_training_tasks): 6 L7 @: y& W4 Z& O7 I raise HTTPException(status_code=404, detail="未找到相应的训练对象!")0 s8 Q# N! i, x) Z
& r D' T# L* A2 _2 y4 h9 ^. E task = topic_model_training_tasks[user_uuid] % z {# l6 q$ f& a. s1 R if task.nmf_training_progress.status_code == 2: 7 O( {# s1 g! j return task.topic_distribution_predict_progress E2 W- |2 u; x. w7 C
else:( u& v+ F" s9 ]5 ]
raise HTTPException(status_code=404, detail="请先等待NMF训练结束!") 2 @- s! P, ^& M( q- N/ j# \4 W) n+ ^: Y
9 f3 n8 w4 B1 I6 A@app.get(9 o- o! g: ?" k1 n1 b. x) ~' j
"/calculate/details/document/",3 o. F. P5 X0 \
tags=["计算模块数据接口"]," B2 j3 R* J, I. t+ g% k+ j
response_model=DocumentDetails : @6 R5 a" h+ k$ q) : t c# d' ?' a" @4 rdef get_document_details(doc_id: int, user_uuid: str = Cookie(None)): : [8 g ^7 ~) O global topic_model_training_tasks 6 G! @4 W& P+ f: a2 ~, l1 Y6 C0 Y; }5 D8 L6 o) g) H8 d
if (not user_uuid) or (user_uuid not in topic_model_training_tasks):! e2 a. {- |4 |5 [3 V7 l/ Z# G
raise HTTPException(status_code=404, detail="未找到相应的训练对象!") $ |" Z1 j0 E7 W" R- y1 N0 p _$ c n" K
task = topic_model_training_tasks[user_uuid] 2 g/ d0 A2 ^6 q, Z1 [ A9 ]; @6 U if task.nmf_training_progress.status_code == 2: . h/ r% i* z! L: A$ V return task.get_document_details(doc_id) " F) e2 w! C7 p, h5 Y, G else:( P5 K. q2 U0 p3 Z* p. j
raise HTTPException(status_code=404, detail="请先等待NMF训练结束!"); j" V4 G- g# a, p
5 C/ m0 H+ c8 T) m9 |: j' R- ^$ i
4 V: t3 t4 p4 r2 Z Y
@app.get( * [$ ~8 h+ r/ s0 Q1 y! j "/calculate/details/topic/",* r9 B, A: c1 C4 d
tags=["计算模块数据接口"], 5 K, a5 }% D8 w) }4 R response_model=TopicDetails ' Z# a V" U" j6 J) ! U9 F }7 B/ d7 ~. c+ Z/ Odef get_topic_details(topic_id: int, user_uuid: str = Cookie(None)): 3 X3 J" N6 E( o. d4 v! q global topic_model_training_tasks: N% C4 b( ^( h H: x2 E$ }" _
+ c4 w/ z* [% Y" C1 m. y$ o if (not user_uuid) or (user_uuid not in topic_model_training_tasks): ?$ f& y" f$ f+ L. G4 |! a raise HTTPException(status_code=404, detail="未找到相应的训练对象!") 7 y( i' K' b) C0 l' V# u: I$ {9 A! m: [
task = topic_model_training_tasks[user_uuid]% B) n6 X" A+ U* _
if task.nmf_training_progress.status_code == 2:5 K1 i6 M) P- b ^0 ]
return task.get_topic_details(topic_id)% [" B3 j) N3 E3 j5 V
else: & d; |& y% `% }- U* K8 v. j raise HTTPException(status_code=404, detail="请先等待NMF训练结束!")5 O; O( A( K/ T6 i- c; J$ e
+ m7 h& h: M: `* @3 d6 S7 i9 ?: M4 `1 I& L3 u% B
@app.get( 9 r" a0 x J: f1 `2 A& I "/calculate/userinteraction/info/keyword/",3 d, g: T5 x3 o: X' ^' o! ]
tags=["计算模块数据接口"],2 n0 m6 @* _# @9 k3 r9 H$ ~
response_model=TopicKeywordInfo : l$ g- w& ?6 e) A. m m)7 A1 a( i& z: f* ~+ e: J
def get_topic_keyword_info(topic_id: int, user_uuid: str = Cookie(None)):7 ?0 ^+ V2 T% j O+ v
global topic_model_training_tasks8 C2 l( f; L* C' n& X
) v6 X! `% @' C
if (not user_uuid) or (user_uuid not in topic_model_training_tasks):; U, ?" C( b- n$ [! c4 e
raise HTTPException(status_code=404, detail="未找到相应的训练对象!") 7 J- O# Z% F f6 R- t3 ~# h6 c . l* D, s ?% U( w4 \; s% g task = topic_model_training_tasks[user_uuid]# U5 n6 s( _0 p3 u! i7 Q, E5 N, p$ ^$ X
if task.nmf_training_progress.status_code == 2:% g) i( q; U. }0 L7 J
return task.get_topic_keyword_info(topic_id)) ?3 w0 n5 Q; K( K2 H0 s5 t! ^2 q& s
else:, J/ K; X4 u4 f
raise HTTPException(status_code=404, detail="请先等待NMF训练结束!") # h& g) }2 _, V# Z; E& ` + `: L, u' ^; `+ t& f7 p5 y2 {8 V+ v7 p
@app.get() E2 I* V& K+ y5 d# @2 s/ S% y% I
"/calculate/userinteraction/info/topicmergekeyword/", 3 V, r) q( U2 z$ j6 }1 r# z+ E tags=["计算模块数据接口"],1 p8 p: d5 ?9 G+ D0 c2 P9 o- y6 v- V
response_model=TopicMergeKeywordInfo9 A! N- J- W# }6 A3 E
) - i4 A) Z0 Z) D& P. U; Ldef get_topic_merge_keyword_info(topic1_id: int, topic2_id: int, user_uuid: str = Cookie(None)):# j5 ] C) k% ~+ _; I' ?( e
global topic_model_training_tasks5 F8 s7 i/ ^" w) ~0 }6 R0 q
. q- F/ S L/ J% i if (not user_uuid) or (user_uuid not in topic_model_training_tasks): ( j, _6 s. O, M _( P raise HTTPException(status_code=404, detail="未找到相应的训练对象!") b0 P6 V! V& p' S: }, J: S x" O ) U( D# L c/ Z3 d0 ] task = topic_model_training_tasks[user_uuid]' V- ]. [' [7 U7 k% D
if task.nmf_training_progress.status_code == 2: & p' r4 E2 e! G return task.get_topic_merge_keyword_info(topic1_id, topic2_id)% x* u# ^+ ], i8 r' l2 M5 L
else:- q0 W. r0 v2 h( m
raise HTTPException(status_code=404, detail="请先等待NMF训练结束!"); s% }8 }4 k2 t+ {! C9 q% M/ D
?$ m/ Y% c7 ]$ A; Y
9 Q( u+ F# m2 T$ v# e1 / N, [0 o1 P# [6 u6 C2 ! Y. }, W. Z8 S1 C. W& R7 |1 ]) ]3 ( c3 h" O6 M) h: M3 X; S43 k' u- i; z4 b, ~* L5 x* a
5 / [% f( E* c* s9 H6, O3 y' }3 _$ T% Z+ U
7 9 f% Q! C8 G5 L( `$ n/ d8 0 Y- J% z, d: k4 v9 \9 ! B' _8 G4 q: `! \+ P10 0 s2 e) d7 w' F5 U4 \- z11 d. Z y5 |7 j. Y
12 . x, @0 i3 X D2 o13 ! l) Z9 }9 @% ~0 H* D* D140 o( c$ M- B7 V. \# r
15* C' }, c7 ]6 J$ J4 e
16 " C6 O% d0 r8 o* r8 \17" e: U/ o6 ?& r4 P5 r
18 $ E7 T+ n$ B1 Q( t. g0 {19$ j/ J& }/ k2 m( l" m% A
20( a2 D3 p3 E \$ L
214 Q& |4 Z- V7 o+ A! B
221 R$ U' G! |3 @' Y) N- z; g( B* A
23 6 g1 D: H2 Z' m3 `& V24 3 t o! {5 s% M1 h! ?255 r! ^) U W7 Z5 `: {6 J
26& T: t4 d. F5 w3 V7 b6 N# z+ J
27 & Q. e. S; Z& n& N$ B% U- k28/ ^9 N( F0 b! o* |
29 p& x0 @( i) l5 R) g
30* j. P+ i! K* Y% l) N
31 b) `6 W% h1 i( V6 B32 . q/ ?1 p, R0 u33$ x( t1 Q: ^' T( n! y& F+ a6 D! {8 B' `
347 {& I8 c3 _# w4 b1 ?
35 + j/ c2 ]6 X5 ]36. [& _! G( {! o2 J! p- E
372 ^, ~; C; F. s( L1 @3 g; ?
38" t* A7 g$ x* W3 F2 j1 \
39 ( k0 v7 Q/ n1 k! M2 h+ r5 b40* Z' g9 U5 k- {$ E1 i" l: y$ E' J
412 M. O5 Z) D1 j
42 9 a- U- j9 V* w" s! R3 R% ?43, T% f( i0 M3 }' W% o6 t2 A+ I
44 ( r" c) s9 _! }% x' @" H45 ; ?" n6 r! s h8 y46 ' x2 [4 j* i1 e47- d' ~) x7 i/ d& @! O& i
48 2 X) @% ?7 ~. x2 o! M49 3 F+ v2 p4 s2 F0 c+ v8 _* d& E50* u, m( T# h' ]. W+ q: y
514 P8 ]# x* F& g4 h
52 $ T4 h( D/ n7 t' E% V7 d2 i53! |+ z. M6 R% c
54 @5 h/ h4 k' I8 B2 J G55 ; p5 ~* J- R7 [# \7 b# f563 _+ b) a; ^9 Z+ Q
571 @% o- x" d( L2 D+ O
58 5 |4 [; L) ^4 v9 e59 2 l3 N! P: A l60 7 {: M! \% Z$ W$ x7 S/ l! k61 9 p. o o: o. L620 W1 r4 n d& X6 J# g/ t: [3 ^: r
63 $ Y( [2 ?( @- l0 `, Y64 3 R+ h) P9 y$ ^/ Q5 s+ w65 , V8 \0 N+ v" s( N7 P- @$ N667 P3 J7 j Z6 D# f! V n& T+ m
67; V+ o9 K, L. f. o
68# S1 l5 @- x: X D3 X- W
69, Y! W J) z @; W- v
701 i) d2 d4 o( Z2 O& y" X
71# ^( j! h+ Q$ W. h1 C' L4 @
72 4 _5 B! r% N' L8 `73* Y* _8 \" w& `
74 1 O C3 X! ^& o# R75+ U T$ x9 _' g9 t- }( i! |
76# N. t: D+ Z6 Y& H; y4 r4 y
77" j& Y: i: {2 U
783 j* r1 O6 l2 g' o* o. V. M
79& @1 K+ G" b+ `( h
80( ^! @4 G0 Q+ T$ ~- ^* ?+ ]3 y6 j c
81/ D; ~- a9 Y) L7 O i
82 " Y( ?! {7 W# b% z83- R; f, t# E7 e( E
84 & N: Z/ D3 F) Z3 @3 j3 R5 X; e85- Z; z4 T% G% P1 K7 o# F
86 " {& @' ]' z$ w1 D" s9 @7 J7 T2 _87 3 k: e) x- ]; A% t7 `% L88 $ H: k+ R1 T6 J& [89# t. D: h6 _- `4 j/ Z# `! X8 C* z6 _
90- ?6 b# v# A* t5 i9 ?
91 3 ~, K0 ?4 Y5 W9 O& {92; s w6 m, |% N0 ?9 R$ \
935 M8 o+ p1 T3 w1 b1 q* i
94 1 i: p5 j( H% _( N) D95 @, _0 w; x$ `# [96 : J0 ^& O) D3 o* Z0 ~( K8 D978 |! F& I7 v: {+ T# |
985 A7 W+ @, {, k; W3 k/ N
99 3 @" x4 n: t; A: I100 1 W' B. v n. S Y* J' }1017 q. Z# r8 {( G, ]* @
102/ c& w- C/ Z) O# Y/ P
103 9 J8 y* a$ q& o) r/ u/ n8 L104) }# D; h+ L4 s K# f# M; x
105 , c* |' K# Q1 A; F# n- N- V106# e, x5 r( S9 ]' t8 T3 }
1073 Y( a) B; @2 R% j3 l9 N
1089 K$ f" P* y" O# y% z
109 * V' T, @5 O' ]- x, Q# g, R110, P5 q k1 h4 |
111 0 k0 q9 t5 Q2 L6 s112 w9 t9 D& L2 e; _, f3 Z: n) L113+ U2 P' { ?! X* W3 j
114- i' O- X+ n% r! T& w
115 1 L7 u+ S$ K* x116 & i0 R) p5 `1 a, q& c0 E117 J/ R8 `- G8 L1186 d9 y. M5 w5 ?, b" s/ g
119/ x& B% k9 Y0 u: l _9 _
120 9 ~1 T9 w2 A# N3 P- v0 h: c! r121 ) J: d5 X/ C! Y1 L122' @9 }9 r/ ^) `- P5 c1 Y1 s
123 ; p* c8 S% t+ z6 A# ]124% C- n" d. j: j$ A2 g) q
125! l0 O; } T$ D) ]$ I
126 " j5 c0 s& g+ l1 K% P127 8 }+ Q' Z' c% I7 B: S, f1285 `4 H4 {4 H# @. e1 B/ x
129. t2 |# R( }, H
130/ n+ `4 {: S, {8 U8 H
131 / L. D" t8 A) w! D, i W% v132 - Z9 S( `5 X3 y2 @+ J: t9 s133$ F( S( _8 X' v- l
134" y. E3 l8 }" q I; t
135 & L% Z) y) i7 E( z2 V( p7 ]136 5 a% ~) k% N$ @- n4 F9 ^- g( x/ `" L137 3 L, D! S6 g, j- x( F: ^138 4 j9 W3 q* U) h) |' r$ i& _139$ f9 C5 Q5 v1 E" A/ |- J! V; r
1403 G+ W: p) J- `2 ]$ Y& d
141. ?( w, o* K4 X; Z) p2 \' t
142( X' u( l! p5 p% O
143 * u Q! P$ o v$ V144 a7 c( K7 y$ m, g8 j
145 4 E3 U" s7 t$ f& o146 & [+ j/ {+ s( c147 f9 F3 n# [" _/ M$ o L
1481 y: E$ X h1 q A
149 & Z& g8 e9 S F6 D) \150 - m! W. h$ s' [0 j151 3 F% I& b; \6 X152( ^; U5 Y( F0 b# x' r9 N v
153/ ?$ h4 }" X- F Q# n
154 ; @4 u" Z% i# a( C, D155 # E- V2 H) }" X0 Z. _1 p1568 K/ i3 l ?% q
157$ x8 n$ Y; a5 w
158 - ^6 d7 [8 w: e; s: O( t1592 f3 y% V% I+ `5 S$ ^8 T( t
160( v7 L: l5 d! Y; Z5 F
1617 i$ T* B9 M9 |" L1 z
162 . ]* w3 c H' E: z- g2 H# I163: m1 \4 ~. i3 y2 p
164 6 T9 \2 y( ]2 b! q# x165 # ^+ _6 ^( o* [166 3 m5 r& K0 u* V1 @- F# h7 p167 9 N* ], Q! V% i) p6 n, A# q4 M168 - A" ^7 u+ ~: Z9 q! C9 L169. R" I/ Y+ J: v' |% Q2 m0 B4 |
170 3 Q4 O( _$ a* \+ u* n/ K171! h; V T5 w4 x9 G* M* }- P8 C
172/ N6 `4 p8 X. Q0 H8 X" L: ]
173 4 e0 v8 h- P% P6 ^8 A- x174 C) { _& @! m9 F; S5 D9 _" i1751 ^( n7 M5 |( I9 Y
176) ^+ I' O, b0 ]$ f0 y3 b! U4 I+ c
177. C* W9 r8 Z" L" _7 M/ Y
178 , n! u, i' D7 Q# j, G- s179 L8 G9 f! I7 l- u1 y) r& w2 ]180! Z1 y; X4 y- i9 M
1817 e" g/ a6 e6 H2 X1 N
182 0 ?# {1 a2 t" x$ [ ~183( s# C" N+ s6 Y- q0 R2 n, j
184( v: O- ?6 {) }6 U, u% P& |5 }
185 , `3 ]# O3 D! F& G$ f$ B186 8 @6 E2 ]# B- a' V7 c187) c6 g% n# X6 K# r$ _/ M, K
188 ! G; h( c) m# h1 e# ]' t' c8 {4 [189; w' y% D2 \ K3 l4 Z( ~
190& N Q% K0 A* Z# V S0 n
191 8 A1 g( x' D( v8 g A6 b, p1926 a3 }1 a; ]5 J; y1 x( |4 C7 N$ M3 ?
1934 s" p, k) g; I
194 ( b4 p: c: W' b6 W0 A( G9 v195 / e* o6 h/ Z! z2 G+ K; T0 e196 x* i& ]' P4 V' U6 H, ^197- i' \0 c( ^9 J# s, p
1984 h/ }, u9 l6 n5 S) o
199 8 B6 g, \' U" V0 H% U" m6 B200 4 t/ ]4 v6 x% y, @. u7 p6 X4 {1 E201 6 m0 N8 n+ ^8 K0 \* v2 y4 J202 1 D- D1 v6 Q" l* X; R' N6 T203 / z b- G3 R8 }204- i. T& M8 k$ o. y1 t
205 ^3 J. _' z4 h
206' ? D% W* |1 A7 Q) W: [
207+ B4 Q' s; i ^! { O2 O+ g* {4 |
2086 o: j2 l( n4 y- q( E/ n
209# P( O d: ^! Z3 c" ^' O
210' g9 K# \# B+ b% W
211 * f0 h4 h- r3 ]+ G. q/ ~212) d; O' q7 ?0 }, d. t
213$ p! J9 t4 x3 C0 B* L
214 ' d# G. k4 l/ U i" j6 x5 ^" V215 $ C0 _3 U7 Y; i; }/ p0 @0 V2161 V r( U0 g5 }
217" w3 }; z3 \0 W) R; j6 x0 [
218 * o2 x# e8 M& C& _9 \" E2195 S4 O& } F7 ?3 w+ T. v+ z, L
220( }+ m2 f* M0 i9 J; }7 Q
2218 f- K' D2 d* m3 U% N. W$ X Q
222+ k4 _, y5 x+ X n
223 7 \) Z, I$ t* h2 E8 O0 s2240 ]: B _- J/ ^
225( z2 o4 [- P0 S' A# a1 a; W
226 / a9 C( U3 i F! P& N' y2272 g# Y* i9 t# j) h! @0 Z0 `
2281 d. z$ W7 [( a. q1 }/ a0 h9 E
2295 K$ F+ G8 {) v- _7 }) s) R" d
230 % `. @* Z: A" M0 U231 ; P3 K6 d# {! T( u) I9 W! p6 Q9 R232 6 l' b6 g H: J1 f% q8 X o; n2339 t4 c. y+ H S4 p. t8 {# n
234- }0 N, t3 a& O- S( Y$ I
235 6 P% M; R7 D* L0 x. ^236* v$ ~: U% k; s p' }' v
237) d" x% H8 Q6 n2 u9 l3 F
238 : f& K5 l: h1 [) K2 ^239/ w: ^- T. f$ X* @* s$ q7 f% H5 m
240; \- m# q% W( d8 V h" O% N
241 " H* M: f9 p# ~& l- v6 d242 6 G6 T f, K% u& Y4 s5 o4 H243. K1 A8 Z! _5 }9 K
244 $ b" T: p- `5 F245 3 P/ j! B5 A1 p" r246 4 {! C. H, E- u# G- D& \247 B5 q8 r& z) E, J
248' M `) d) \$ ]* j
249 1 k& z2 {! t! E4 ~250 / s, U* n) ~; g2 [& O251, v0 Q6 l* F8 @7 V2 z9 M& d# i5 J
2529 }+ t% g$ t+ |. T: b2 C6 X% G
253: R, b0 V5 k! d8 e' w3 F
254 ; p7 `4 Y% d* ?7 k255' e( [( W8 u2 ]1 K/ O: z
256 $ n) }& X& E4 {) E5 `257' M- N, @& j& @; k5 ]! f
258- Y# v5 ?* I% x6 ^5 z9 H+ M+ f6 l
259 & Z0 v y$ Y R, V) l x" _260' O f0 ] L# Q# T x
261 ) e4 X1 S! h0 G: P262 + ` z7 y8 ~4 B4 p+ d0 w4 [263" v7 M5 R. h3 R7 H- o& F
2645 d% |% A, h* X# A+ S, q, T
265 & m) k# s& i! i0 R7 }2665 N: q) I7 i2 R0 F9 w7 R$ Q( |; k
2671 d( l- I0 G x& V3 h( X9 a
268 $ G+ v. e& o: l" ?/ `5 P u2690 D- P. p! D& u& r- P
270. v4 F( C/ w. R2 k7 h
2713 }. Y+ V7 h6 w8 z' |- a! @+ S2 c' j
272 3 \4 O8 Y/ U" _6 A+ ]2 T273; x* d0 k2 e& n5 O5 j) U9 d
274# I6 F# S& N+ ^% q
275 , z; j D4 J. S3 f# U% m Y* S0 L2762 E- ^7 M; @7 e1 ^) K9 l
277; x1 o% o5 T0 p3 O/ g
278 : _3 j5 X0 L" t/ n& ?279 - y J( {) G# R; `( W- j280 - A2 }! _# ]7 `% v! n4 g281; a# [! x4 ?1 H. U/ \' e2 j
282' I8 V+ Y8 s4 g+ x3 h9 j. {0 r; S
283 & D% V2 y& t" D* Y2841 q: p/ l8 i/ _# A$ \; r
285 ' i# Q+ r. W. v6 U9 g286) g! f6 |( A+ r% i' Y( u$ v
2872 v" x: C8 j! i q8 Q
288 3 T' H8 f R5 s289 ; |! N5 |9 h y& @+ i290 ! z3 t7 _# e _ ?291 5 h3 ?" F+ j6 B- J- G2 }292( l7 ?. G& ?! c3 I% m" T* z
293% r) @8 U) @1 B" R
294 ' C j1 n" | U+ P3 J2955 \3 ^" P6 F* O2 R$ R* Q
296/ n& Q, ]9 a' p/ b4 e& M, [. {
297 9 a7 ^) u' @% u2 i, j298 0 z# Q7 i: z6 K* |) Q* i9 O299( } z) `) k# }, o! Z0 C
300 3 l4 V( k$ i @ p301" V: b1 S- O; b& V+ f0 p; X; a2 O
302 2 h1 K g* l7 Z( A303; z0 j+ [+ P8 A, J G
304 , e2 H I2 |, H( G' B. S3056 d% D; V/ n+ K* \, n
306- B5 e; r! \% F
307% v% u# N+ U, ~
3083 j5 t6 T, ?6 M6 o
309+ m0 U. c; d4 ^0 E8 W- ~
310) b* Z9 a' u8 Q+ ?$ h
311& Y: l/ C# `/ Q W9 l: A; y
3127 t0 B8 y9 q! M/ l: r
3136 y9 ^9 N% T" O/ V: }" _
314' z& z- S% R' P6 n; q
315 : x! W0 b1 T% u1 b4 ]" g5 j$ o316 * d: ?5 r1 S! P6 f$ I317 ( i: @6 x; U% L% g# j5 m, v, ^( u3181 v2 \1 M+ o$ C, H! B
3194 l& v& f Q2 _% Q0 F0 t
3206 x6 [3 B$ M6 X! ?! g4 ]! l
321 0 z4 L8 F' w5 R& Z3222 G* r G9 ]" M0 t
323 * L1 `7 A3 D, P: x1 Y" S324 + a. Q( K# S C325 : _0 Y8 |: }3 n( ]' Y326/ ]0 A. E* A8 c. u5 s
327% y! u. ~! ?) u; R0 h
328 . d. a! l* W2 R C; u8 |1 E329- B: l! `( L* U6 K3 |
330' I" q5 _; d1 T
331 7 F, f' w: A" R% f) g: P1 }+ [/ L$ [332 7 n- I1 I! Y0 O$ v" a333 ) B9 l) X% L9 _; d5 Q) N) c334; \ t' b( H$ D$ x9 J; a
3351 C M9 K$ m$ Q+ H9 o* P% Q
3364 |1 ^. D; N/ D! B- ]
337 2 t. E9 L! B( I% V& [) T, A338 8 {7 v" Q" t) _, f) ]- Q4 |8 l. Y+ U339 5 k4 ^) ~$ u, b! S) c& [5 W340 6 u8 E: A$ y: e9 u% i0 Y2 p) f341 5 N# y: X2 X) |7 f3420 | l- f* p8 a
3439 s# B/ r' P8 W: u5 y, M* o
344" h- b. R6 D' s/ E; j' d. Y
345 2 M/ z. d2 B; R- G346. }7 e8 |0 {4 ^ m0 p$ f# F# f0 ^5 @, b
3476 ]/ u4 E# h0 j' e
3489 ]2 u* c3 H1 e
349 ! ?$ J S3 G& \& h& T350) Q& X [- w) I) E
351 " @8 y+ b, A/ C% [% C: x352 3 T( t/ m( o% O( O8 b353 + m$ p7 f" p3 x0 H354# b& Y7 k. }2 {
355) P, x, S$ U* w9 o, q1 e
356 # W: A6 Z5 g$ [6 e* g3577 M0 j* Q' f' c2 ~
358; x, M- ]/ Z) ^# }0 \: S9 ^
359 - T3 w1 I1 Q- F# k/ h: N) `. `360! U: I. P }4 ^8 T5 ^
361 6 y6 O ~0 `* g8 l' \- C6 c362' p# R2 Q# v( W* G2 Z5 H
363 : \, _: W) k: a b" \$ t# L364* _5 L `+ |3 x. Q
365 . z1 x- f9 I# C8 \7 [366 6 ^' P4 i, w! m, r5 ~4 l5 G367 + X# C' j f' W X [/ D3680 I; P% f, ~: m9 p: [% M7 R. u- w
369 ; j7 f' U, ?; }" O# W# m, q370. |" I5 W) y0 Y0 R, B/ ]! r/ C
371" R4 h5 B7 x4 V9 C [! ~
372: C5 [) R, G; X6 I! C7 s* @* Z
3739 U8 m/ m3 z# B P* M& w o6 m/ y$ z" e
3743 a7 t& I# ]9 i1 }) v. n
3757 G! a% n$ k" e0 S4 ]1 T' \
376 ' B" J# j0 J# g377 % D( ?. g# ]2 e: h# r& H378$ G \7 `( z" g$ R% g3 b$ P
379% H, a; N7 ^; Y" S, {7 i0 \
380 5 b' Z( C% ]' w3 H1 ~381) k7 e- O- H9 f- O) w, Q- T
3824 C5 ^! j4 L4 G
3831 X- K% |) d' z; w2 ^+ s
384 * z5 a- z, a8 D7 r3 O$ Z* S385$ A, k! f4 e- @. t2 B6 `0 F
386$ u! q% c! o- d4 ?
387 " ?% h% d7 U, |& F1 \; L388 " O, q, U8 l( k3 Q3895 S& Z9 t5 }/ j# W/ Y
390 & \- w: }# n/ m* ?6 K$ k391 2 Q: L8 u: Z+ q0 X; Q392 - `, T5 R6 u4 M+ s4 m( p3933 G. v) Q8 G% ]2 W# W' ^. g
394 ) F t4 T [, t2 d# K% H395 7 y3 ?* U) m& A* g: i. Z396 ) S6 v' f; f; C. R( [/ q3 ~, L9 y! f7 V3971 i% S/ P" f& O4 t
3983 f+ A, I) b/ {, g, a5 s
3990 y n* i2 O& f; {" y/ h
400 " {6 N0 y# s# E9 L; t- X401 ( U; p1 s' R- [2 D. Z% m402; L( g) Z, | v/ r
4032 C# T8 _& b0 v, T' q
404 & y2 m( t9 a7 R405 9 h9 o* {, T8 K/ P5 M" B406 % P% `2 i1 j6 [ y2 J5 s8 P* _& Y407" `9 R/ c, ~1 W% Z# g
408 & b% `8 u& d. H9 q$ r. q409& ^# U2 h; u: r9 ?% o1 Q
410- ]1 }' `0 h7 O. R. j: ?
411# s: \* u/ u! C( ~- n i, O
412 ! P, [1 j( q" \, v. s) @413 9 p# }7 m. l9 F8 E5 F! l/ @* g4142 A/ i9 L' {+ {+ j
4157 ?2 G3 B1 R8 [; K4 j
416+ ?9 H, r% S/ f' B1 c( W. h1 H
417 . g) W! K7 q# T/ ?' b$ L$ P418 + Z' W, \9 N$ X! n3 f7 J2 p% [419 * V- L* u( A% ]" l) |/ s0 [420 ' K2 k7 b5 P; K$ q% } W# d421 - N/ |; h( X8 L2 j$ c% d4226 T6 I; p5 [% P) z; }
423! m' m. x2 j% F% u
424' z6 k! f+ Q6 }: R
425 * W6 ~! w: m* B3 C. |426 8 \* F# \/ m' X; B m! x427 ! j: t: r, }- J. n$ ?5 l428 % D+ H( ^5 ? K" `9 g. F4 ~6 i429 9 o- ~) o5 [2 p+ v& }5 h2 B1 B; a$ M430 ) ] n4 z+ [% m" E! c8 V431' x) f; u; \9 _! b8 G0 I' @
432% I( p; t7 T V! Q; J
433 l' O4 B+ P9 `+ i% m, ?
4340 J! t1 V$ n) i
435 @# }6 H: z- |& F436 $ O: @5 K: ~1 H3 B% `437 0 \" e" t. Z/ {' a' b h4 x- l2 I6 [5 U F438 ; C2 h( E( g9 u. Q7 G/ W439: W5 ^: D4 p' p- D
440; V1 m K6 `5 ]- a7 c# i. `+ N
441 ; l/ S/ c+ S* W3 f2 [442* @) m# w6 w* ]/ G" u1 A
443 1 ~9 W& J; N' ?% e( b3 T444 " Q! v/ e. d% `$ v445 ! x8 L% P7 G0 E7 d446 , Z) J1 E! i8 W3 W. c9 d+ b447 5 w; w$ l: W9 C2 ^448 & L! \! g7 ^* L, c% z* t. {449 3 Y8 j {6 v3 {6 {+ x$ E. ]8 G1 J450 4 d# F! D+ Q! F5 q. f0 l451 ; W. C) p) ]. A; r% x$ K- A- P0 @452* M! K, `% ^" C( }! E; u* v* d
4536 o) [0 t2 s* l4 j! N* u
454 1 e2 d& U4 O5 s4 Y3 X A1 D455 G7 I$ D i! p* J# H456+ F1 e9 ~) _' h4 D* v, p
4570 d1 H% n0 A) K: V- n3 z
4585 C; [/ g/ T; P. ]+ J$ X; A. q4 ~6 B
459 + G7 `1 \$ d0 Z1 S* P5 c; j& N460 + q- f% O) i; D; n! @1 F5 u( q, q461 % Q! {2 T) k4 q* o( y# V462 2 J- ~+ i: ?- I- m/ M' U463 `' p" E3 U7 `; g( @: {3 F
464 , ]7 P% s. Z: R7 B/ i465( i# L6 T; i/ W
466 ! `% q$ l# Q1 M. s; p4 m2 S- {467 * u4 ^2 J( q: J1 x# L468; s! M% F; T) z4 b+ R; W3 t" M
469 6 j8 j; X" @ K9 w+ Q3 e9 U' @4706 l8 o6 z, R2 t! n
471 $ i2 c7 f$ r" y7 T z# g' D: Z( o4720 t: X' t! B ]4 E% x2 T4 V
473 ; k( I4 S+ A" Q9 u' i" H474 - }: _$ y1 q) l% Q2 I475; L- m2 q" k- K, c: A
476% Z' y2 h1 @. t% Q2 b3 |! o
3 t& R$ t2 g6 N1 e. y0 u, ^3 g" R& D3 i" V# Y& e8 z9 e
- p- Q& T5 y) W6 i
+ l( J2 r! A4 R , b& j' k6 y/ r; a k 4 M' _9 x4 K, a* L+ H3 B & b$ P' x( t# j/ [4 m 7 z/ G& r& z0 l9 s" G, I. q5 V 3 Y: @) l6 T0 W. T) j" m# w9 o2 n! P' X7 V. O8 r0 L
( G. t9 I1 S- M2 J8 d/ U+ T" P. r
- i$ I# v0 R# B% Y3 y
; s- h8 r/ o4 q1 Z: D% e. _0 q+ l) R0 A6 x
0 m* Q9 Y, T. U/ A5 U