feat: new models, sorting fix

This commit is contained in:
2025-03-15 21:12:15 +07:00
parent db7076182e
commit 2b8df155d3
103 changed files with 16214 additions and 4048 deletions

910
internal/dal/workers.gen.go Normal file
View File

@@ -0,0 +1,910 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package dal
import (
"app/internal/models"
"context"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"gorm.io/gorm/schema"
"gorm.io/gen"
"gorm.io/gen/field"
"gorm.io/plugin/dbresolver"
)
func newWorker(db *gorm.DB, opts ...gen.DOOption) worker {
_worker := worker{}
_worker.workerDo.UseDB(db, opts...)
_worker.workerDo.UseModel(&models.Worker{})
tableName := _worker.workerDo.TableName()
_worker.ALL = field.NewAsterisk(tableName)
_worker.Id = field.NewUint(tableName, "id")
_worker.Name = field.NewString(tableName, "name")
_worker.WorkshopId = field.NewUint(tableName, "workshop_id")
_worker.Workshop = workerBelongsToWorkshop{
db: db.Session(&gorm.Session{}),
RelationField: field.NewRelation("Workshop", "models.Workshop"),
WorkAreas: struct {
field.RelationField
Workshop struct {
field.RelationField
}
PrepTasks struct {
field.RelationField
Task struct {
field.RelationField
ProductType struct {
field.RelationField
}
Order struct {
field.RelationField
ProductType struct {
field.RelationField
}
Customer struct {
field.RelationField
Orders struct {
field.RelationField
}
}
Tasks struct {
field.RelationField
}
}
PrepTasks struct {
field.RelationField
}
Workshops struct {
field.RelationField
}
}
WorkArea struct {
field.RelationField
}
}
Shifts struct {
field.RelationField
ProductType struct {
field.RelationField
}
WorkArea struct {
field.RelationField
}
}
TeamTasks struct {
field.RelationField
TeamType struct {
field.RelationField
}
TeamLeader struct {
field.RelationField
Workshop struct {
field.RelationField
}
TeamTasks struct {
field.RelationField
}
}
WorkArea struct {
field.RelationField
}
TeamMembers struct {
field.RelationField
}
}
}{
RelationField: field.NewRelation("Workshop.WorkAreas", "models.WorkArea"),
Workshop: struct {
field.RelationField
}{
RelationField: field.NewRelation("Workshop.WorkAreas.Workshop", "models.Workshop"),
},
PrepTasks: struct {
field.RelationField
Task struct {
field.RelationField
ProductType struct {
field.RelationField
}
Order struct {
field.RelationField
ProductType struct {
field.RelationField
}
Customer struct {
field.RelationField
Orders struct {
field.RelationField
}
}
Tasks struct {
field.RelationField
}
}
PrepTasks struct {
field.RelationField
}
Workshops struct {
field.RelationField
}
}
WorkArea struct {
field.RelationField
}
}{
RelationField: field.NewRelation("Workshop.WorkAreas.PrepTasks", "models.PrepTask"),
Task: struct {
field.RelationField
ProductType struct {
field.RelationField
}
Order struct {
field.RelationField
ProductType struct {
field.RelationField
}
Customer struct {
field.RelationField
Orders struct {
field.RelationField
}
}
Tasks struct {
field.RelationField
}
}
PrepTasks struct {
field.RelationField
}
Workshops struct {
field.RelationField
}
}{
RelationField: field.NewRelation("Workshop.WorkAreas.PrepTasks.Task", "models.Task"),
ProductType: struct {
field.RelationField
}{
RelationField: field.NewRelation("Workshop.WorkAreas.PrepTasks.Task.ProductType", "models.ProductType"),
},
Order: struct {
field.RelationField
ProductType struct {
field.RelationField
}
Customer struct {
field.RelationField
Orders struct {
field.RelationField
}
}
Tasks struct {
field.RelationField
}
}{
RelationField: field.NewRelation("Workshop.WorkAreas.PrepTasks.Task.Order", "models.Order"),
ProductType: struct {
field.RelationField
}{
RelationField: field.NewRelation("Workshop.WorkAreas.PrepTasks.Task.Order.ProductType", "models.ProductType"),
},
Customer: struct {
field.RelationField
Orders struct {
field.RelationField
}
}{
RelationField: field.NewRelation("Workshop.WorkAreas.PrepTasks.Task.Order.Customer", "models.Customer"),
Orders: struct {
field.RelationField
}{
RelationField: field.NewRelation("Workshop.WorkAreas.PrepTasks.Task.Order.Customer.Orders", "models.Order"),
},
},
Tasks: struct {
field.RelationField
}{
RelationField: field.NewRelation("Workshop.WorkAreas.PrepTasks.Task.Order.Tasks", "models.Task"),
},
},
PrepTasks: struct {
field.RelationField
}{
RelationField: field.NewRelation("Workshop.WorkAreas.PrepTasks.Task.PrepTasks", "models.PrepTask"),
},
Workshops: struct {
field.RelationField
}{
RelationField: field.NewRelation("Workshop.WorkAreas.PrepTasks.Task.Workshops", "models.Workshop"),
},
},
WorkArea: struct {
field.RelationField
}{
RelationField: field.NewRelation("Workshop.WorkAreas.PrepTasks.WorkArea", "models.WorkArea"),
},
},
Shifts: struct {
field.RelationField
ProductType struct {
field.RelationField
}
WorkArea struct {
field.RelationField
}
}{
RelationField: field.NewRelation("Workshop.WorkAreas.Shifts", "models.Shift"),
ProductType: struct {
field.RelationField
}{
RelationField: field.NewRelation("Workshop.WorkAreas.Shifts.ProductType", "models.ProductType"),
},
WorkArea: struct {
field.RelationField
}{
RelationField: field.NewRelation("Workshop.WorkAreas.Shifts.WorkArea", "models.WorkArea"),
},
},
TeamTasks: struct {
field.RelationField
TeamType struct {
field.RelationField
}
TeamLeader struct {
field.RelationField
Workshop struct {
field.RelationField
}
TeamTasks struct {
field.RelationField
}
}
WorkArea struct {
field.RelationField
}
TeamMembers struct {
field.RelationField
}
}{
RelationField: field.NewRelation("Workshop.WorkAreas.TeamTasks", "models.TeamTask"),
TeamType: struct {
field.RelationField
}{
RelationField: field.NewRelation("Workshop.WorkAreas.TeamTasks.TeamType", "models.TeamType"),
},
TeamLeader: struct {
field.RelationField
Workshop struct {
field.RelationField
}
TeamTasks struct {
field.RelationField
}
}{
RelationField: field.NewRelation("Workshop.WorkAreas.TeamTasks.TeamLeader", "models.Worker"),
Workshop: struct {
field.RelationField
}{
RelationField: field.NewRelation("Workshop.WorkAreas.TeamTasks.TeamLeader.Workshop", "models.Workshop"),
},
TeamTasks: struct {
field.RelationField
}{
RelationField: field.NewRelation("Workshop.WorkAreas.TeamTasks.TeamLeader.TeamTasks", "models.TeamTask"),
},
},
WorkArea: struct {
field.RelationField
}{
RelationField: field.NewRelation("Workshop.WorkAreas.TeamTasks.WorkArea", "models.WorkArea"),
},
TeamMembers: struct {
field.RelationField
}{
RelationField: field.NewRelation("Workshop.WorkAreas.TeamTasks.TeamMembers", "models.Worker"),
},
},
},
Workers: struct {
field.RelationField
}{
RelationField: field.NewRelation("Workshop.Workers", "models.Worker"),
},
Tasks: struct {
field.RelationField
}{
RelationField: field.NewRelation("Workshop.Tasks", "models.Task"),
},
}
_worker.TeamTasks = workerManyToManyTeamTasks{
db: db.Session(&gorm.Session{}),
RelationField: field.NewRelation("TeamTasks", "models.TeamTask"),
}
_worker.fillFieldMap()
return _worker
}
type worker struct {
workerDo
ALL field.Asterisk
Id field.Uint
Name field.String
WorkshopId field.Uint
Workshop workerBelongsToWorkshop
TeamTasks workerManyToManyTeamTasks
fieldMap map[string]field.Expr
}
func (w worker) Table(newTableName string) *worker {
w.workerDo.UseTable(newTableName)
return w.updateTableName(newTableName)
}
func (w worker) As(alias string) *worker {
w.workerDo.DO = *(w.workerDo.As(alias).(*gen.DO))
return w.updateTableName(alias)
}
func (w *worker) updateTableName(table string) *worker {
w.ALL = field.NewAsterisk(table)
w.Id = field.NewUint(table, "id")
w.Name = field.NewString(table, "name")
w.WorkshopId = field.NewUint(table, "workshop_id")
w.fillFieldMap()
return w
}
func (w *worker) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
_f, ok := w.fieldMap[fieldName]
if !ok || _f == nil {
return nil, false
}
_oe, ok := _f.(field.OrderExpr)
return _oe, ok
}
func (w *worker) fillFieldMap() {
w.fieldMap = make(map[string]field.Expr, 5)
w.fieldMap["id"] = w.Id
w.fieldMap["name"] = w.Name
w.fieldMap["workshop_id"] = w.WorkshopId
}
func (w worker) clone(db *gorm.DB) worker {
w.workerDo.ReplaceConnPool(db.Statement.ConnPool)
return w
}
func (w worker) replaceDB(db *gorm.DB) worker {
w.workerDo.ReplaceDB(db)
return w
}
type workerBelongsToWorkshop struct {
db *gorm.DB
field.RelationField
WorkAreas struct {
field.RelationField
Workshop struct {
field.RelationField
}
PrepTasks struct {
field.RelationField
Task struct {
field.RelationField
ProductType struct {
field.RelationField
}
Order struct {
field.RelationField
ProductType struct {
field.RelationField
}
Customer struct {
field.RelationField
Orders struct {
field.RelationField
}
}
Tasks struct {
field.RelationField
}
}
PrepTasks struct {
field.RelationField
}
Workshops struct {
field.RelationField
}
}
WorkArea struct {
field.RelationField
}
}
Shifts struct {
field.RelationField
ProductType struct {
field.RelationField
}
WorkArea struct {
field.RelationField
}
}
TeamTasks struct {
field.RelationField
TeamType struct {
field.RelationField
}
TeamLeader struct {
field.RelationField
Workshop struct {
field.RelationField
}
TeamTasks struct {
field.RelationField
}
}
WorkArea struct {
field.RelationField
}
TeamMembers struct {
field.RelationField
}
}
}
Workers struct {
field.RelationField
}
Tasks struct {
field.RelationField
}
}
func (a workerBelongsToWorkshop) Where(conds ...field.Expr) *workerBelongsToWorkshop {
if len(conds) == 0 {
return &a
}
exprs := make([]clause.Expression, 0, len(conds))
for _, cond := range conds {
exprs = append(exprs, cond.BeCond().(clause.Expression))
}
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
return &a
}
func (a workerBelongsToWorkshop) WithContext(ctx context.Context) *workerBelongsToWorkshop {
a.db = a.db.WithContext(ctx)
return &a
}
func (a workerBelongsToWorkshop) Session(session *gorm.Session) *workerBelongsToWorkshop {
a.db = a.db.Session(session)
return &a
}
func (a workerBelongsToWorkshop) Model(m *models.Worker) *workerBelongsToWorkshopTx {
return &workerBelongsToWorkshopTx{a.db.Model(m).Association(a.Name())}
}
type workerBelongsToWorkshopTx struct{ tx *gorm.Association }
func (a workerBelongsToWorkshopTx) Find() (result *models.Workshop, err error) {
return result, a.tx.Find(&result)
}
func (a workerBelongsToWorkshopTx) Append(values ...*models.Workshop) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Append(targetValues...)
}
func (a workerBelongsToWorkshopTx) Replace(values ...*models.Workshop) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Replace(targetValues...)
}
func (a workerBelongsToWorkshopTx) Delete(values ...*models.Workshop) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Delete(targetValues...)
}
func (a workerBelongsToWorkshopTx) Clear() error {
return a.tx.Clear()
}
func (a workerBelongsToWorkshopTx) Count() int64 {
return a.tx.Count()
}
type workerManyToManyTeamTasks struct {
db *gorm.DB
field.RelationField
}
func (a workerManyToManyTeamTasks) Where(conds ...field.Expr) *workerManyToManyTeamTasks {
if len(conds) == 0 {
return &a
}
exprs := make([]clause.Expression, 0, len(conds))
for _, cond := range conds {
exprs = append(exprs, cond.BeCond().(clause.Expression))
}
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
return &a
}
func (a workerManyToManyTeamTasks) WithContext(ctx context.Context) *workerManyToManyTeamTasks {
a.db = a.db.WithContext(ctx)
return &a
}
func (a workerManyToManyTeamTasks) Session(session *gorm.Session) *workerManyToManyTeamTasks {
a.db = a.db.Session(session)
return &a
}
func (a workerManyToManyTeamTasks) Model(m *models.Worker) *workerManyToManyTeamTasksTx {
return &workerManyToManyTeamTasksTx{a.db.Model(m).Association(a.Name())}
}
type workerManyToManyTeamTasksTx struct{ tx *gorm.Association }
func (a workerManyToManyTeamTasksTx) Find() (result []*models.TeamTask, err error) {
return result, a.tx.Find(&result)
}
func (a workerManyToManyTeamTasksTx) Append(values ...*models.TeamTask) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Append(targetValues...)
}
func (a workerManyToManyTeamTasksTx) Replace(values ...*models.TeamTask) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Replace(targetValues...)
}
func (a workerManyToManyTeamTasksTx) Delete(values ...*models.TeamTask) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Delete(targetValues...)
}
func (a workerManyToManyTeamTasksTx) Clear() error {
return a.tx.Clear()
}
func (a workerManyToManyTeamTasksTx) Count() int64 {
return a.tx.Count()
}
type workerDo struct{ gen.DO }
type IWorkerDo interface {
gen.SubQuery
Debug() IWorkerDo
WithContext(ctx context.Context) IWorkerDo
WithResult(fc func(tx gen.Dao)) gen.ResultInfo
ReplaceDB(db *gorm.DB)
ReadDB() IWorkerDo
WriteDB() IWorkerDo
As(alias string) gen.Dao
Session(config *gorm.Session) IWorkerDo
Columns(cols ...field.Expr) gen.Columns
Clauses(conds ...clause.Expression) IWorkerDo
Not(conds ...gen.Condition) IWorkerDo
Or(conds ...gen.Condition) IWorkerDo
Select(conds ...field.Expr) IWorkerDo
Where(conds ...gen.Condition) IWorkerDo
Order(conds ...field.Expr) IWorkerDo
Distinct(cols ...field.Expr) IWorkerDo
Omit(cols ...field.Expr) IWorkerDo
Join(table schema.Tabler, on ...field.Expr) IWorkerDo
LeftJoin(table schema.Tabler, on ...field.Expr) IWorkerDo
RightJoin(table schema.Tabler, on ...field.Expr) IWorkerDo
Group(cols ...field.Expr) IWorkerDo
Having(conds ...gen.Condition) IWorkerDo
Limit(limit int) IWorkerDo
Offset(offset int) IWorkerDo
Count() (count int64, err error)
Scopes(funcs ...func(gen.Dao) gen.Dao) IWorkerDo
Unscoped() IWorkerDo
Create(values ...*models.Worker) error
CreateInBatches(values []*models.Worker, batchSize int) error
Save(values ...*models.Worker) error
First() (*models.Worker, error)
Take() (*models.Worker, error)
Last() (*models.Worker, error)
Find() ([]*models.Worker, error)
FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*models.Worker, err error)
FindInBatches(result *[]*models.Worker, batchSize int, fc func(tx gen.Dao, batch int) error) error
Pluck(column field.Expr, dest interface{}) error
Delete(...*models.Worker) (info gen.ResultInfo, err error)
Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
Updates(value interface{}) (info gen.ResultInfo, err error)
UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
UpdateFrom(q gen.SubQuery) gen.Dao
Attrs(attrs ...field.AssignExpr) IWorkerDo
Assign(attrs ...field.AssignExpr) IWorkerDo
Joins(fields ...field.RelationField) IWorkerDo
Preload(fields ...field.RelationField) IWorkerDo
FirstOrInit() (*models.Worker, error)
FirstOrCreate() (*models.Worker, error)
FindByPage(offset int, limit int) (result []*models.Worker, count int64, err error)
ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
Scan(result interface{}) (err error)
Returning(value interface{}, columns ...string) IWorkerDo
UnderlyingDB() *gorm.DB
schema.Tabler
}
func (w workerDo) Debug() IWorkerDo {
return w.withDO(w.DO.Debug())
}
func (w workerDo) WithContext(ctx context.Context) IWorkerDo {
return w.withDO(w.DO.WithContext(ctx))
}
func (w workerDo) ReadDB() IWorkerDo {
return w.Clauses(dbresolver.Read)
}
func (w workerDo) WriteDB() IWorkerDo {
return w.Clauses(dbresolver.Write)
}
func (w workerDo) Session(config *gorm.Session) IWorkerDo {
return w.withDO(w.DO.Session(config))
}
func (w workerDo) Clauses(conds ...clause.Expression) IWorkerDo {
return w.withDO(w.DO.Clauses(conds...))
}
func (w workerDo) Returning(value interface{}, columns ...string) IWorkerDo {
return w.withDO(w.DO.Returning(value, columns...))
}
func (w workerDo) Not(conds ...gen.Condition) IWorkerDo {
return w.withDO(w.DO.Not(conds...))
}
func (w workerDo) Or(conds ...gen.Condition) IWorkerDo {
return w.withDO(w.DO.Or(conds...))
}
func (w workerDo) Select(conds ...field.Expr) IWorkerDo {
return w.withDO(w.DO.Select(conds...))
}
func (w workerDo) Where(conds ...gen.Condition) IWorkerDo {
return w.withDO(w.DO.Where(conds...))
}
func (w workerDo) Order(conds ...field.Expr) IWorkerDo {
return w.withDO(w.DO.Order(conds...))
}
func (w workerDo) Distinct(cols ...field.Expr) IWorkerDo {
return w.withDO(w.DO.Distinct(cols...))
}
func (w workerDo) Omit(cols ...field.Expr) IWorkerDo {
return w.withDO(w.DO.Omit(cols...))
}
func (w workerDo) Join(table schema.Tabler, on ...field.Expr) IWorkerDo {
return w.withDO(w.DO.Join(table, on...))
}
func (w workerDo) LeftJoin(table schema.Tabler, on ...field.Expr) IWorkerDo {
return w.withDO(w.DO.LeftJoin(table, on...))
}
func (w workerDo) RightJoin(table schema.Tabler, on ...field.Expr) IWorkerDo {
return w.withDO(w.DO.RightJoin(table, on...))
}
func (w workerDo) Group(cols ...field.Expr) IWorkerDo {
return w.withDO(w.DO.Group(cols...))
}
func (w workerDo) Having(conds ...gen.Condition) IWorkerDo {
return w.withDO(w.DO.Having(conds...))
}
func (w workerDo) Limit(limit int) IWorkerDo {
return w.withDO(w.DO.Limit(limit))
}
func (w workerDo) Offset(offset int) IWorkerDo {
return w.withDO(w.DO.Offset(offset))
}
func (w workerDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IWorkerDo {
return w.withDO(w.DO.Scopes(funcs...))
}
func (w workerDo) Unscoped() IWorkerDo {
return w.withDO(w.DO.Unscoped())
}
func (w workerDo) Create(values ...*models.Worker) error {
if len(values) == 0 {
return nil
}
return w.DO.Create(values)
}
func (w workerDo) CreateInBatches(values []*models.Worker, batchSize int) error {
return w.DO.CreateInBatches(values, batchSize)
}
// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (w workerDo) Save(values ...*models.Worker) error {
if len(values) == 0 {
return nil
}
return w.DO.Save(values)
}
func (w workerDo) First() (*models.Worker, error) {
if result, err := w.DO.First(); err != nil {
return nil, err
} else {
return result.(*models.Worker), nil
}
}
func (w workerDo) Take() (*models.Worker, error) {
if result, err := w.DO.Take(); err != nil {
return nil, err
} else {
return result.(*models.Worker), nil
}
}
func (w workerDo) Last() (*models.Worker, error) {
if result, err := w.DO.Last(); err != nil {
return nil, err
} else {
return result.(*models.Worker), nil
}
}
func (w workerDo) Find() ([]*models.Worker, error) {
result, err := w.DO.Find()
return result.([]*models.Worker), err
}
func (w workerDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*models.Worker, err error) {
buf := make([]*models.Worker, 0, batchSize)
err = w.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
defer func() { results = append(results, buf...) }()
return fc(tx, batch)
})
return results, err
}
func (w workerDo) FindInBatches(result *[]*models.Worker, batchSize int, fc func(tx gen.Dao, batch int) error) error {
return w.DO.FindInBatches(result, batchSize, fc)
}
func (w workerDo) Attrs(attrs ...field.AssignExpr) IWorkerDo {
return w.withDO(w.DO.Attrs(attrs...))
}
func (w workerDo) Assign(attrs ...field.AssignExpr) IWorkerDo {
return w.withDO(w.DO.Assign(attrs...))
}
func (w workerDo) Joins(fields ...field.RelationField) IWorkerDo {
for _, _f := range fields {
w = *w.withDO(w.DO.Joins(_f))
}
return &w
}
func (w workerDo) Preload(fields ...field.RelationField) IWorkerDo {
for _, _f := range fields {
w = *w.withDO(w.DO.Preload(_f))
}
return &w
}
func (w workerDo) FirstOrInit() (*models.Worker, error) {
if result, err := w.DO.FirstOrInit(); err != nil {
return nil, err
} else {
return result.(*models.Worker), nil
}
}
func (w workerDo) FirstOrCreate() (*models.Worker, error) {
if result, err := w.DO.FirstOrCreate(); err != nil {
return nil, err
} else {
return result.(*models.Worker), nil
}
}
func (w workerDo) FindByPage(offset int, limit int) (result []*models.Worker, count int64, err error) {
result, err = w.Offset(offset).Limit(limit).Find()
if err != nil {
return
}
if size := len(result); 0 < limit && 0 < size && size < limit {
count = int64(size + offset)
return
}
count, err = w.Offset(-1).Limit(-1).Count()
return
}
func (w workerDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
count, err = w.Count()
if err != nil {
return
}
err = w.Offset(offset).Limit(limit).Scan(result)
return
}
func (w workerDo) Scan(result interface{}) (err error) {
return w.DO.Scan(result)
}
func (w workerDo) Delete(models ...*models.Worker) (result gen.ResultInfo, err error) {
return w.DO.Delete(models)
}
func (w *workerDo) withDO(do gen.Dao) *workerDo {
w.DO = *do.(*gen.DO)
return w
}