问:
GORM and PostgreSQL: search_path is used only when doing the first request
I'm currently working on an api gateway that forwards requests to an grpc client. The routes use a middleware. Within that middleware the Validate function from the dialed grpc client is used. The function is in the last code snippet at the end.

The gateway is based on a gin router, which, as far as I understand handles each request in a separat go routine. I can send as many requests simultaneously to either to endpoint /protected/1 or to endpoint /protected/2 and they get handled correctly.

The Validate function is having problems handling request sent simultaneously to /protected/1 and /protected/2. Sending two request to both endpoints simultaneously results in that either both, none or only one of the requests is handled correctly. The error message that I receive is actually from the gorm function trying to query the user in the Validate function (ERROR: relation "users" does not exist (SQLSTATE 42P01)). I use a gorm database object that is connected to a postgres database. This behaviour suggests that some how a resource is shared. Using run -race does not give any insights.

So my questions are, why does this setup not work to send requests simultaneously to both endpoints?

I tried to make a working minimal example, but somehow I could nor reproduce the error in a minimal setting, hence I would like to share my code snippets here.

Important snippets of the the Api Gateway implementation

```<code>func main() {
  c, err := config.LoadConfig()
  ...
  r := gin.Default()
  auth.RegisterRoutes(r, &c)
  r.Run(":" + c.Port)
}
</code>```

whereas the routes are defined as

```<code>func RegisterRoutes(r *gin.Engine, c *config.Config){
  svc := &ServiceClient{
    Client: InitServiceClient(c),
  }
  a := InitAuthMiddleware(svc)

  // routes
  protected := r.Group("/protected")
  protected.Use(a.AuthRequired)
  protected.GET("/1", svc.DoStuff)
  protected.GET("/2", svc.DoStuff)

}
// dummy handler
func (svc *ServiceClient) DoStuff(ctx *gin.Context) {
  handler.DoStuff(ctx, svc.Client)
}
</code>```

The grpc client is dialed with the following function

```<code>type ServiceClient struct {
    Client pb.AuthServiceClient
}

func InitServiceClient(c *config.Config) pb.AuthServiceClient {
    // using WithInsecure() because no SSL running
    cc, err := grpc.Dial(c.AuthSvcUrl, grpc.WithInsecure())

    if err != nil {
        fmt.Println("Could not connect:", err)
    }

    return pb.NewAuthServiceClient(cc)
}
</code>```

and the middleware is implemented in the following way:

```<code>type AuthMiddlewareConfig struct {
    svc *ServiceClient
}

func InitAuthMiddleware(svc *ServiceClient) AuthMiddlewareConfig {
    return AuthMiddlewareConfig{svc}
}

func (c *AuthMiddlewareConfig) AuthRequired(ctx *gin.Context) {
    access_token, _ := ctx.Cookie("access_token")

    res, err := c.svc.Client.Validate(context.Background(), &pb.ValidateRequest{
        Token:     access_token,
        TokenType: "ACCESS_TOKEN",
        Url:       ctx.Request.URL.String(),
    })

    if err != nil || res.Status != http.StatusOK {
        ctx.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"status": http.StatusUnauthorized, "error": res.Error})
        return
    }

    ctx.Set("userId", res.UserId)

    ctx.Next()
}
</code>```

Important snippets of the Auth Service:

```<code>func serve(c *conf.Configuration) {
    /*
      Dial returns:
      type Repository struct {
        DB *gorm.DB
       }
    */
    h := storage.Dial(&c.DB)

    serviceUri := fmt.Sprintf(":%s", c.API.Port)

    lis, err := net.Listen("tcp", serviceUri)

    if err != nil {
        logrus.Fatal("Failed to listen on: ", err)
    }

    s := api.Server{
      R:   h,
      //
    }

    grpcServer := grpc.NewServer()
    pb.RegisterAuthServiceServer(grpcServer, &s)

    if err := grpcServer.Serve(lis); err != nil {
        logrus.Fatalln("Failed to serve:", err)
    }
}
</code>```

and the validate function is implemented by

```<code>type Server struct {
    R   storage.Repository
    //
    // #https://github.com/grpc/grpc-go/issues/3794:
    pb.UnimplementedAuthServiceServer
}

func (s *Server) Validate(ctx context.Context, req *pb.ValidateRequest) (*pb.ValidateResponse, error) {
     // token validation stuff works

    var user models.User

    // causes error sometimes
    if result := s.R.DB.Where(&models.User{Id: claims.Id}).First(&user); result.Error != nil {
        return &pb.ValidateResponse{
            Status: http.StatusNotFound,
            Error:  "User not found",
        }, nil
    }

    // send response
}
</code>```

EDIT

For completeness here the function that connects to the postgres client.

```<code>func openDb(c *conf.PostgresConfiguration, gormConfig *gorm.Config, database string) *gorm.DB {
    connectionString := fmt.Sprintf("postgres://%s:%s@%s:%s/%s", c.User, c.Password, c.Host, c.Port, database)
    db, err := gorm.Open(postgres.Open(connectionString), gormConfig)
    if err != nil {
        logrus.Fatal(fmt.Sprintf("Unable to connect to database '%s' given url: ", database), err)
    }
    logrus.Info(fmt.Sprintf("Connected to database %s", database))
    return db
}

func Dial(c *conf.PostgresConfiguration) Repository {
    gormDefaultConfig := &gorm.Config{}
    gormAppConfig := &gorm.Config{}

    // connect to default database
    logrus.Info(fmt.Sprintf("Use default database %s for initialization", c.DefaultDatabase))
    defaultDb := openDb(c, gormDefaultConfig, c.DefaultDatabase)

    // check if database exists and create it if necessary
    var dbexists bool
    dbSQL := fmt.Sprintf("SELECT EXISTS (SELECT FROM pg_database WHERE datname = '%s') AS dbexists;", c.AppDatabase)
    defaultDb.Raw(dbSQL).Row().Scan(&dbexists)
    if !dbexists {
        logrus.Info(fmt.Sprintf("Created database %s", c.AppDatabase))
        db := defaultDb.Exec(fmt.Sprintf("CREATE DATABASE %s;", c.AppDatabase))
        if db.Error != nil {
            logrus.Fatal("Unable to create app database: ", db.Error)
        }
    }

    // connect to app databse
    appDb := openDb(c, gormAppConfig, c.AppDatabase)

    // check if schema exists and create it if necessary
    var schemaexists bool
    schemaSQL := fmt.Sprintf("SELECT EXISTS(SELECT FROM pg_namespace WHERE nspname = '%s') AS schemaexisits;", c.AppDatabaseSchema)
    appDb.Raw(schemaSQL).Row().Scan(&schemaexists)
    // create app specfic database, if not already existing
    if !schemaexists {
        // create service specific schema
        db := appDb.Exec(fmt.Sprintf("CREATE SCHEMA %s;", c.AppDatabaseSchema))
        if db.Error != nil {
            logrus.Fatal(fmt.Sprintf("Unable to create database schema %s", c.AppDatabaseSchema), db.Error)
        }
        logrus.Info(fmt.Sprintf("Created database schema %s", c.AppDatabaseSchema))
    }

    db := appDb.Exec(fmt.Sprintf(`set search_path='%s';`, c.AppDatabaseSchema))
    logrus.Info(fmt.Sprintf("Use existing database schema %s", c.AppDatabaseSchema))
    if db.Error != nil {
        logrus.Fatal(fmt.Sprintf("Unable to set search_path for database to schema %s", c.AppDatabaseSchema), db.Error)
    }

    // migrate table
    appDb.AutoMigrate(&models.User{})

    return Repository{appDb}
}
</code>```

Edit2

Changing the connection string in the openDb function to connectionString := fmt.Sprintf("postgres://%s:%s@%s:%s/%s?search_path=%s", c.User, c.Password, c.Host, c.Port, database, c.AppDatabaseSchema) fixes the issue (see how the search_path is part of the url).
Thank you!

Body:
I'm currently working on an api gateway that forwards requests to an grpc client. The routes use a middleware. Within that middleware the Validate function from the dialed grpc client is used. The function is in the last code snippet at the end.

The gateway is based on a gin router, which, as far as I understand handles each request in a separat go routine. I can send as many requests simultaneously to either to endpoint /protected/1 or to endpoint /protected/2 and they get handled correctly.

The Validate function is having problems handling request sent simultaneously to /protected/1 and /protected/2. Sending two request to both endpoints simultaneously results in that either both, none or only one of the requests is handled correctly. The error message that I receive is actually from the gorm function trying to query the user in the Validate function (ERROR: relation "users" does not exist (SQLSTATE 42P01)). I use a gorm database object that is connected to a postgres database. This behaviour suggests that some how a resource is shared. Using run -race does not give any insights.

So my questions are, why does this setup not work to send requests simultaneously to both endpoints?

I tried to make a working minimal example, but somehow I could nor reproduce the error in a minimal setting, hence I would like to share my code snippets here.

Important snippets of the the Api Gateway implementation

func main() {
  c, err := config.LoadConfig()
  ...
  r := gin.Default()
  auth.RegisterRoutes(r, &c)
  r.Run(":" + c.Port)
}

whereas the routes are defined as

func RegisterRoutes(r *gin.Engine, c *config.Config){
  svc := &ServiceClient{
    Client: InitServiceClient(c),
  }
  a := InitAuthMiddleware(svc)

  // routes
  protected := r.Group("/protected")
  protected.Use(a.AuthRequired)
  protected.GET("/1", svc.DoStuff)
  protected.GET("/2", svc.DoStuff)

}
// dummy handler
func (svc *ServiceClient) DoStuff(ctx *gin.Context) {
  handler.DoStuff(ctx, svc.Client)
}

The grpc client is dialed with the following function

type ServiceClient struct {
    Client pb.AuthServiceClient
}

func InitServiceClient(c *config.Config) pb.AuthServiceClient {
    // using WithInsecure() because no SSL running
    cc, err := grpc.Dial(c.AuthSvcUrl, grpc.WithInsecure())

    if err != nil {
        fmt.Println("Could not connect:", err)
    }

    return pb.NewAuthServiceClient(cc)
}

and the middleware is implemented in the following way:

type AuthMiddlewareConfig struct {
    svc *ServiceClient
}

func InitAuthMiddleware(svc *ServiceClient) AuthMiddlewareConfig {
    return AuthMiddlewareConfig{svc}
}

func (c *AuthMiddlewareConfig) AuthRequired(ctx *gin.Context) {
    access_token, _ := ctx.Cookie("access_token")

    res, err := c.svc.Client.Validate(context.Background(), &pb.ValidateRequest{
        Token:     access_token,
        TokenType: "ACCESS_TOKEN",
        Url:       ctx.Request.URL.String(),
    })

    if err != nil || res.Status != http.StatusOK {
        ctx.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"status": http.StatusUnauthorized, "error": res.Error})
        return
    }

    ctx.Set("userId", res.UserId)

    ctx.Next()
}

Important snippets of the Auth Service:

func serve(c *conf.Configuration) {
    /*
      Dial returns:
      type Repository struct {
        DB *gorm.DB
       }
    */
    h := storage.Dial(&c.DB)

    serviceUri := fmt.Sprintf(":%s", c.API.Port)

    lis, err := net.Listen("tcp", serviceUri)

    if err != nil {
        logrus.Fatal("Failed to listen on: ", err)
    }

    s := api.Server{
      R:   h,
      //
    }

    grpcServer := grpc.NewServer()
    pb.RegisterAuthServiceServer(grpcServer, &s)

    if err := grpcServer.Serve(lis); err != nil {
        logrus.Fatalln("Failed to serve:", err)
    }
}

and the validate function is implemented by

type Server struct {
    R   storage.Repository
    //
    // #https://github.com/grpc/grpc-go/issues/3794:
    pb.UnimplementedAuthServiceServer
}

func (s *Server) Validate(ctx context.Context, req *pb.ValidateRequest) (*pb.ValidateResponse, error) {
     // token validation stuff works

    var user models.User

    // causes error sometimes
    if result := s.R.DB.Where(&models.User{Id: claims.Id}).First(&user); result.Error != nil {
        return &pb.ValidateResponse{
            Status: http.StatusNotFound,
            Error:  "User not found",
        }, nil
    }

    // send response
}

EDIT

For completeness here the function that connects to the postgres client.

func openDb(c *conf.PostgresConfiguration, gormConfig *gorm.Config, database string) *gorm.DB {
    connectionString := fmt.Sprintf("postgres://%s:%s@%s:%s/%s", c.User, c.Password, c.Host, c.Port, database)
    db, err := gorm.Open(postgres.Open(connectionString), gormConfig)
    if err != nil {
        logrus.Fatal(fmt.Sprintf("Unable to connect to database '%s' given url: ", database), err)
    }
    logrus.Info(fmt.Sprintf("Connected to database %s", database))
    return db
}

func Dial(c *conf.PostgresConfiguration) Repository {
    gormDefaultConfig := &gorm.Config{}
    gormAppConfig := &gorm.Config{}

    // connect to default database
    logrus.Info(fmt.Sprintf("Use default database %s for initialization", c.DefaultDatabase))
    defaultDb := openDb(c, gormDefaultConfig, c.DefaultDatabase)

    // check if database exists and create it if necessary
    var dbexists bool
    dbSQL := fmt.Sprintf("SELECT EXISTS (SELECT FROM pg_database WHERE datname = '%s') AS dbexists;", c.AppDatabase)
    defaultDb.Raw(dbSQL).Row().Scan(&dbexists)
    if !dbexists {
        logrus.Info(fmt.Sprintf("Created database %s", c.AppDatabase))
        db := defaultDb.Exec(fmt.Sprintf("CREATE DATABASE %s;", c.AppDatabase))
        if db.Error != nil {
            logrus.Fatal("Unable to create app database: ", db.Error)
        }
    }

    // connect to app databse
    appDb := openDb(c, gormAppConfig, c.AppDatabase)

    // check if schema exists and create it if necessary
    var schemaexists bool
    schemaSQL := fmt.Sprintf("SELECT EXISTS(SELECT FROM pg_namespace WHERE nspname = '%s') AS schemaexisits;", c.AppDatabaseSchema)
    appDb.Raw(schemaSQL).Row().Scan(&schemaexists)
    // create app specfic database, if not already existing
    if !schemaexists {
        // create service specific schema
        db := appDb.Exec(fmt.Sprintf("CREATE SCHEMA %s;", c.AppDatabaseSchema))
        if db.Error != nil {
            logrus.Fatal(fmt.Sprintf("Unable to create database schema %s", c.AppDatabaseSchema), db.Error)
        }
        logrus.Info(fmt.Sprintf("Created database schema %s", c.AppDatabaseSchema))
    }

    db := appDb.Exec(fmt.Sprintf(`set search_path='%s';`, c.AppDatabaseSchema))
    logrus.Info(fmt.Sprintf("Use existing database schema %s", c.AppDatabaseSchema))
    if db.Error != nil {
        logrus.Fatal(fmt.Sprintf("Unable to set search_path for database to schema %s", c.AppDatabaseSchema), db.Error)
    }

    // migrate table
    appDb.AutoMigrate(&models.User{})

    return Repository{appDb}
}

Edit2

Changing the connection string in the openDb function to connectionString := fmt.Sprintf("postgres://%s:%s@%s:%s/%s?search_path=%s", c.User, c.Password, c.Host, c.Port, database, c.AppDatabaseSchema) fixes the issue (see how the search_path is part of the url).
Thank you!


来源: stackexchange

问:
How to trigger, pragmatically and specifically, polylineMeasure leaflet control button on
I need to simply turn the control on and off.  I've tried hooking into the element displayed with js.

I need to do this with polylineMeasure plugin for leaflet.  NOT a others I've seen out there.

```

UG
×

```
```<code>jQuery('.add-ug-path-tool').click(); does not work.
jQuery('.add-ug-path-tool').trigger('click') does not work.
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I need to simply turn the control on and off.  I've tried hooking into the element displayed with js.

I need to do this with polylineMeasure plugin for leaflet.  NOT a others I've seen out there.

UG
×

jQuery('.add-ug-path-tool').click(); does not work.
jQuery('.add-ug-path-tool').trigger('click') does not work.


问:
Creating new VS Code Extension - I don't see my extension
I did yo code, the whole framework for the extension was created, in the terminal I got warning message: 'To run the extension you need to install the recommended extension 'amodio.tsl-problem-matcher'.

Then inside VS Code I did F5, then inside Extension Development Host cmd + shift + p and I can't see my default hello world command

What is going on....


问:
http.server rfile read blocking in python
Trying to build a simple python3 HTTP Server with http.server:

```<code>import http.server
from http.server import HTTPServer, BaseHTTPRequestHandler
import socketserver

class Handler(BaseHTTPRequestHandler):
  def do_PATCH(self):
    print ("do_Patch called")
    contentLength = int(self.headers['content-length'])
    res = self.rfile.read(contentLength)
    self.send_response(200)
    self.send_header('Content-type', 'text/plain')
    self.end_headers()
    self.wfile.write('Something brilliant'.encode())

httpd = HTTPServer(("127.0.0.1",33181),Handler)
httpd.serve_forever()
</code>```

Problem is that self.rfile.read() is blocking, so if I don't get the content-length exactly right I either get too little data or I hang.. Docs I've found says it's supposed to throw an exception in non-blocking mode but I've not found out how to set non-blocking mode.

I can get around this by setting the content-length as above, but I can also corrupt the content-length which hangs the thread:

```<code>import http.client

myValueableString = "Shorter than 300"

for mylen in [len(myValueableString), 300]:
  conn = http.client.HTTPConnection("127.0.0.1",33181)
  conn.request("PATCH","/test",myValueableString ,{'Content-length': mylen})
  print(conn.getresponse().read().decode())
</code>```

Is there any good way to 1) Force finding the "true" length of rfile stream, or 2) Force a timeout or 3) Enable "non-blocking" mode? I realize the code isn't recommended for production but this is the only real stumbling block I've encountered.

Body:
Trying to build a simple python3 HTTP Server with http.server:

import http.server
from http.server import HTTPServer, BaseHTTPRequestHandler
import socketserver

class Handler(BaseHTTPRequestHandler):
  def do_PATCH(self):
    print ("do_Patch called")
    contentLength = int(self.headers['content-length'])
    res = self.rfile.read(contentLength)
    self.send_response(200)
    self.send_header('Content-type', 'text/plain')
    self.end_headers()
    self.wfile.write('Something brilliant'.encode())

httpd = HTTPServer(("127.0.0.1",33181),Handler)
httpd.serve_forever()

Problem is that self.rfile.read() is blocking, so if I don't get the content-length exactly right I either get too little data or I hang.. Docs I've found says it's supposed to throw an exception in non-blocking mode but I've not found out how to set non-blocking mode.

I can get around this by setting the content-length as above, but I can also corrupt the content-length which hangs the thread:

import http.client

myValueableString = "Shorter than 300"

for mylen in [len(myValueableString), 300]:
  conn = http.client.HTTPConnection("127.0.0.1",33181)
  conn.request("PATCH","/test",myValueableString ,{'Content-length': mylen})
  print(conn.getresponse().read().decode())

Is there any good way to 1) Force finding the "true" length of rfile stream, or 2) Force a timeout or 3) Enable "non-blocking" mode? I realize the code isn't recommended for production but this is the only real stumbling block I've encountered.


问:
Theme FINALSKINFILE cannot be found in the application or global theme directories
I am getting this error

Configuration Error
Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.

Parser Error Message: Theme 'FinalSkinFile' cannot be found in the application or global theme directories.

while running a site using IIS, although finalskinfile exists and I downloaded ASP.net features and roles.
Microsoft .NET framework version: 4.0.30319 ; ASP.NET version:4.7.3930.0


问:
How to fix Cannot find module './xhr-sync-worker.js' in AWS lambda
I have a lambda function that does a bit of server side rendering. I am using lambda's esbuild config. Here is a look at the config. I guess its similar to this issue but different since I am not using Meteor. I am wondering if anyone knows how to solve this issue in the context of a Lambda function or even using webpack. I get this error at runtime.</p>
```<code>bundling: {
    externalModules: ['canvas'],
    loader: {
        '.woff': 'text',
        '.svg': 'text',
        '.js': 'jsx'
      },
}
</code>```

Body:
I have a lambda function that does a bit of server side rendering. I am using lambda's esbuild config. Here is a look at the config. I guess its similar to this issue but different since I am not using Meteor. I am wondering if anyone knows how to solve this issue in the context of a Lambda function or even using webpack. I get this error at runtime.

bundling: {
    externalModules: ['canvas'],
    loader: {
        '.woff': 'text',
        '.svg': 'text',
        '.js': 'jsx'
      },
}


问:
CSS background color not reflecting
So I am following along with a youtube tutorial to set up my VSCode on front-end development for beginners. Heres the link to the video. https://www.youtube.com/watch?v=aydFCQiUW44&list=WL&index=10&ab_channel=CoderCoder

My issue is that as I follow along step by step when it's time to check my page to ensure that everything is showing live, everything is showing except the background color.  The uploader has her comments turned off so I can't ask what I am missing so I am searching here for help.  Here's the code. I am using the live sass compiler by Glenn Marks. the Live sasscompiler by Ritwick Dey prompts me to use that one instead, and I am also using the Live server by Ritwick Dey.

```<code>html {
    font-size: 100%;
    box-sizing: border-box;
}

*, *::before, *::after {
    box-sizing: inherit;
}

body {
    font-family: Arial, Helvetica, sans-serif;
    line-height: 1.3;
    margin: 0px;
    padding: 0px;
    background-color: #202020;
    color: #ffffff;
}
</code>```

was expecting to see the background in black (dark grey) with white text. but instead its just white background with black text.

Title: CSS background color not reflecting

Body:
So I am following along with a youtube tutorial to set up my VSCode on front-end development for beginners. Heres the link to the video. https://www.youtube.com/watch?v=aydFCQiUW44&list=WL&index=10&ab_channel=CoderCoder

My issue is that as I follow along step by step when it's time to check my page to ensure that everything is showing live, everything is showing except the background color.  The uploader has her comments turned off so I can't ask what I am missing so I am searching here for help.  Here's the code. I am using the live sass compiler by Glenn Marks. the Live sasscompiler by Ritwick Dey prompts me to use that one instead, and I am also using the Live server by Ritwick Dey.

html {
    font-size: 100%;
    box-sizing: border-box;
}

*, *::before, *::after {
    box-sizing: inherit;
}

body {
    font-family: Arial, Helvetica, sans-serif;
    line-height: 1.3;
    margin: 0px;
    padding: 0px;
    background-color: #202020;
    color: #ffffff;
}

was expecting to see the background in black (dark grey) with white text. but instead its just white background with black text.


问:
I have an error with the eas-cli package when using it
I saw that the expo build:android command no longer works and instead it recommends me to use eas build -p android but when using the command I get the following error:

install the -g eas-cli package and verify that everything was in order

The error that throws in the terminal

any idea what is going on?


问:
Mono Slam scale consistency
When running mono Slam how is scale consistency achieved between frames? One short tutorial ran the 5point algorithm repeatedly and used a motion model for consistency of scale between frames but that is clearly not done in the general case.

I think I read something once about how the 5 point algorithm is used initially to estimate motion between first two frames then features are tracked over time using reprojection loss and 3d projection.

How is it done?

Title: Mono Slam scale consistency


问:
Adding plotshape to existing pinescript indicator
Initial Script:

TV Original Author Link

The goal is to add a visual indicator shape whenever the close is within a certain dollar amount(0.5,1) of the support or resistance levels. Original indicator works fine for plotting, and I'm just looking to add a visual indicator for ease of use.

```<code>linegood(i) =>

        // get value of each level from OM Levels text block (if used)
    level_rw   = array.get(level_resistance,     i)
    level_sw   = array.get(level_support,        i)
    strong_rw  = array.get(strong_resistance,    i)
    strong_sw  = array.get(strong_support,       i)
    x = if close >= level_rw - 0.5 and close <= level_rw + 0.5
        true
    else if strong_rw and close >= level_rw - 0.75 and close <= level_rw + 0.75
        true
    else if close >= level_sw - 0.5 and close <= level_sw + 0.5
        true
    else if strong_sw and open >= level_rw - 0.75 and open <= level_rw + 0.75
        true
    else
        false

plotshape(linegood(0), style=shape.arrowdown)
plotshape(linegood(1), style=shape.arrowdown)
plotshape(linegood(2), style=shape.arrowdown)
plotshape(linegood(3), style=shape.arrowdown)
plotshape(linegood(4), style=shape.arrowdown)
plotshape(linegood(5), style=shape.arrowdown)
plotshape(linegood(6), style=shape.arrowdown)
plotshape(linegood(7), style=shape.arrowdown)
plotshape(linegood(8), style=shape.arrowdown)
</code>```

I've tried defining a function to sort through the various arrays that represent the support/resistance block code input. There isn't an error message, but it seems the arrays are set above in a different scope than the global plotshape() function, so there is no array to check. I am unsure how to implement this visual indicator.

Body:
Initial Script:

TV Original Author Link

The goal is to add a visual indicator shape whenever the close is within a certain dollar amount(0.5,1) of the support or resistance levels. Original indicator works fine for plotting, and I'm just looking to add a visual indicator for ease of use.

linegood(i) =>

        // get value of each level from OM Levels text block (if used)
    level_rw   = array.get(level_resistance,     i)
    level_sw   = array.get(level_support,        i)
    strong_rw  = array.get(strong_resistance,    i)
    strong_sw  = array.get(strong_support,       i)
    x = if close >= level_rw - 0.5 and close <= level_rw + 0.5
        true
    else if strong_rw and close >= level_rw - 0.75 and close <= level_rw + 0.75
        true
    else if close >= level_sw - 0.5 and close <= level_sw + 0.5
        true
    else if strong_sw and open >= level_rw - 0.75 and open <= level_rw + 0.75
        true
    else
        false

plotshape(linegood(0), style=shape.arrowdown)
plotshape(linegood(1), style=shape.arrowdown)
plotshape(linegood(2), style=shape.arrowdown)
plotshape(linegood(3), style=shape.arrowdown)
plotshape(linegood(4), style=shape.arrowdown)
plotshape(linegood(5), style=shape.arrowdown)
plotshape(linegood(6), style=shape.arrowdown)
plotshape(linegood(7), style=shape.arrowdown)
plotshape(linegood(8), style=shape.arrowdown)

I've tried defining a function to sort through the various arrays that represent the support/resistance block code input. There isn't an error message, but it seems the arrays are set above in a different scope than the global plotshape() function, so there is no array to check. I am unsure how to implement this visual indicator.


问:
pages build and deployment fails
I have a github site, an RStudio project, generating web pages for a course,
https://github.com/friendly/psy6136
It is set up with a `docs/' folder and github action to deploy to my site https://friendly.github.io/psy6136

It has always worked flawlessly.  But not today.

I recently re-built the site and pushed some updates. I get an error,
https://github.com/friendly/psy6136/actions/runs/3885227416
I have no idea how to figure out where / what the problem is.  The only thing I can see is the diff for the most recent commit, but nothing there strikes me as unusual.

Questions:

What can I do to find where the problem arises from what I can see in this error report?

RStudio uses a large collection of JS & CSS files to render the site as static HTML.  Is there anything I can look at here that might show up as a cause of this error?

Follow-up:

Following this question, GitHub pages are not updating
I slightly edited my index.Rmd file, re-built the web pages (rmarkdown::render_site(encoding = 'UTF-8')) and pushed again. I got the same error report.

A solution:
I don't know why, but I finally got it to deploy by removing one line from
the header of my schedule.html file and moving the CSS contents inline.

<link rel="stylesheet" type="text/css" target="_blank" href="assets/styles.css">

Note added later:
Now I know why:  A stupid error-- the file styles.css was missing the lines

```<code><style type="text/css">
...
</style>
</code>```

I'm still perplexed that the GitHub error report contains essentially no information to determine why a failure to deploy occurs.

Title: pages build and deployment fails

Body:
I have a github site, an RStudio project, generating web pages for a course,
https://github.com/friendly/psy6136
It is set up with a `docs/' folder and github action to deploy to my site https://friendly.github.io/psy6136

It has always worked flawlessly.  But not today.

I recently re-built the site and pushed some updates. I get an error,
https://github.com/friendly/psy6136/actions/runs/3885227416
I have no idea how to figure out where / what the problem is.  The only thing I can see is the diff for the most recent commit, but nothing there strikes me as unusual.

Questions:

What can I do to find where the problem arises from what I can see in this error report?

RStudio uses a large collection of JS & CSS files to render the site as static HTML.  Is there anything I can look at here that might show up as a cause of this error?

Follow-up:

Following this question, GitHub pages are not updating
I slightly edited my index.Rmd file, re-built the web pages (rmarkdown::render_site(encoding = 'UTF-8')) and pushed again. I got the same error report.

A solution:
I don't know why, but I finally got it to deploy by removing one line from
the header of my schedule.html file and moving the CSS contents inline.

<link rel="stylesheet" type="text/css" target="_blank" href="assets/styles.css">

Note added later:
Now I know why:  A stupid error-- the file styles.css was missing the lines

I'm still perplexed that the GitHub error report contains essentially no information to determine why a failure to deploy occurs.


问:
Vaadin 23 and ONE ROUTE for All Access Denied Exceptions
I have Vaadin 23 app. I want ONE ROUTE for all errors/exceptions and especially for all ACCESS DENIED exceptions.... how can I accimplish that withough refefinding

```<code>@Override
public void beforeEnter(BeforeEnterEvent event) {
</code>```

from BeforeEnterObserver interface?

It used to be that you cold define with a tag an error route for a page... now I cannot find it

I di not want to have to redefine

@Override
public void beforeEnter(BeforeEnterEvent event) {

in every BeforeEnterObserver interface. this is too much clutter

Body:
I have Vaadin 23 app. I want ONE ROUTE for all errors/exceptions and especially for all ACCESS DENIED exceptions.... how can I accimplish that withough refefinding

@Override
public void beforeEnter(BeforeEnterEvent event) {

from BeforeEnterObserver interface?

It used to be that you cold define with a tag an error route for a page... now I cannot find it

I di not want to have to redefine

@Override
public void beforeEnter(BeforeEnterEvent event) {

in every BeforeEnterObserver interface. this is too much clutter


问:
Tab suppression callback
I have a tab app and I'd like to know if there is a way to get a notification or to setup a callback for when a user suppress the tab from his Facebook page? Because I noticed that even if you remove the tab, you don't necessarily  deauthorize the application (and for me it's not the same operation at all).

Thank you for helping me.

ContentLicense: CC BY-SA 3.0

Title: Tab suppression callback


问:
How can i run webdriver from my assets folder using webdriver package?(Windows)
I tried these codes but none of them worked. I don't want to use environment variables,i want to use local file.</p>
```<code>Uri fpath= Uri.file('assets/msedgedriver.exe',);
await launchUrl(fpath);
WebDriver driver = await createDriver(desired: Capabilities.chrome,uri: Uri.parse('assets/msedgedriver.exe'));
driver.driver.get('https://www.google.com');
</code>```

Body:
I tried these codes but none of them worked. I don't want to use environment variables,i want to use local file.

Uri fpath= Uri.file('assets/msedgedriver.exe',);
await launchUrl(fpath);
WebDriver driver = await createDriver(desired: Capabilities.chrome,uri: Uri.parse('assets/msedgedriver.exe'));
driver.driver.get('https://www.google.com');


问:
Read file Hibernate.cfg.xml
I need to extract the configuration file from a folder external to the project(C:/Propertiesexample/hibernateexample.cfg.xml), but it doesn't work for me, this is what I currently have and it works perfect when the configuration file is in the src/main of the project, but it's not what I'm looking for

public SessionFactory getSessionFactory() {
    if (sessionFactory == null) {
        try {
            // Create registry
            registry = new StandardServiceRegistryBuilder().configure(configFileName) .build();

            // Create MetadataSources
            MetadataSources sources = new MetadataSources(registry);

            // Create Metadata
            Metadata metadata = sources.getMetadataBuilder().build();
            // Create SessionFactory
            sessionFactory = metadata.getSessionFactoryBuilder().build();
            sessionFactory.getStatistics().setStatisticsEnabled(true);
        } catch (Exception e) {
            e.printStackTrace();
            if (registry != null) {
                StandardServiceRegistryBuilder.destroy(registry);
            }
        }
    }
    return sessionFactory;
}
```
<p>I implemented this, but it doesn't work:</p>
<pre class="lang-java prettyprint-override"><code>String hibernatePropsFilePath = "C:/exampleFolder/example.cfg.xml";

File hibernatePropsFile = new File(hibernatePropsFilePath);

Configuration configuration = new Configuration();
configuration.configure(hibernatePropsFile);

StandardServiceRegistryBuilder serviceRegistryBuilder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());

StandardServiceRegistry serviceRegistry = serviceRegistryBuilder.build();
// Create registry

//Create MetadataSources
MetadataSources sources = new MetadataSources(serviceRegistry);

// Create Metadata
Metadata metadata = sources.getMetadataBuilder().build();
// Create SessionFactory
sessionFactory = metadata.getSessionFactoryBuilder().build();
sessionFactory.getStatistics().setStatisticsEnabled(true);
</code>```

Title: Read file Hibernate.cfg.xml

Body:
I need to extract the configuration file from a folder external to the project(C:/Propertiesexample/hibernateexample.cfg.xml), but it doesn't work for me, this is what I currently have and it works perfect when the configuration file is in the src/main of the project, but it's not what I'm looking for

public SessionFactory getSessionFactory() {
    if (sessionFactory == null) {
        try {
            // Create registry
            registry = new StandardServiceRegistryBuilder().configure(configFileName) .build();

            // Create MetadataSources
            MetadataSources sources = new MetadataSources(registry);

            // Create Metadata
            Metadata metadata = sources.getMetadataBuilder().build();
            // Create SessionFactory
            sessionFactory = metadata.getSessionFactoryBuilder().build();
            sessionFactory.getStatistics().setStatisticsEnabled(true);
        } catch (Exception e) {
            e.printStackTrace();
            if (registry != null) {
                StandardServiceRegistryBuilder.destroy(registry);
            }
        }
    }
    return sessionFactory;
}

I implemented this, but it doesn't work:

String hibernatePropsFilePath = "C:/exampleFolder/example.cfg.xml";

File hibernatePropsFile = new File(hibernatePropsFilePath);

Configuration configuration = new Configuration();
configuration.configure(hibernatePropsFile);

StandardServiceRegistryBuilder serviceRegistryBuilder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());

StandardServiceRegistry serviceRegistry = serviceRegistryBuilder.build();
// Create registry

//Create MetadataSources
MetadataSources sources = new MetadataSources(serviceRegistry);

// Create Metadata
Metadata metadata = sources.getMetadataBuilder().build();
// Create SessionFactory
sessionFactory = metadata.getSessionFactoryBuilder().build();
sessionFactory.getStatistics().setStatisticsEnabled(true);


问:
How to use pyautogui to locate multiple images?
I have this piece of code in a while

```<code>   if pyautogui.locateCenterOnScreen('image.png', confidence=0.8) is not None:
            if pyautogui.locateCenterOnScreen('item_selected.png', confidence=0.9) is None:
                x, y = pyautogui.locateOnScreen('item.png', confidence=0.6)
                pyautogui.moveTo(x, y)
                pyautogui.click()
</code>```

My idea is to run the code and when I open a image and the item is not selected, then my code should find the item and click on then, but I'm getting the following error:

```<code>Traceback (most recent call last):
  File "C:\Users\Luis\PycharmProjects\item_finder.py", line 42, in image_f
    x, y = pyautogui.locateOnScreen('item.png', confidence=0.6)
ValueError: too many values to unpack (expected 2)
</code>```

What I want to know is how can I change my code to make it work (Find if a item is not selected, then find the item and select then)

Body:
I have this piece of code in a while

   if pyautogui.locateCenterOnScreen('image.png', confidence=0.8) is not None:
            if pyautogui.locateCenterOnScreen('item_selected.png', confidence=0.9) is None:
                x, y = pyautogui.locateOnScreen('item.png', confidence=0.6)
                pyautogui.moveTo(x, y)
                pyautogui.click()

My idea is to run the code and when I open a image and the item is not selected, then my code should find the item and click on then, but I'm getting the following error:

Traceback (most recent call last):
  File "C:\Users\Luis\PycharmProjects\item_finder.py", line 42, in image_f
    x, y = pyautogui.locateOnScreen('item.png', confidence=0.6)
ValueError: too many values to unpack (expected 2)

What I want to know is how can I change my code to make it work (Find if a item is not selected, then find the item and select then)


问:
URL gives information to API/Backend
So let's say I have my registered domain hosted on Apache 2. Right.
Let's say

```<code>cool-domain.com
</code>```

Now, I make a script which has the functionality to show all my users the same kind of background and frame and stuff, but each one gets a different picture of a cat or a dog.
So, if my user wants to see a dalmatian, he would enter:

```<code>cool-domain.com/dogs/dalmatian
</code>```

Right, and if my user wants to see an orange cat, he would enter the following URL:

```<code>cool-domain.com/cats/orange
</code>```

Now, I don't want to make a different HTML page for each cat and each dog. I want one html which changes the image source according to the URL.
So my PHP backend would remeber something among the lines of:

```<code>$species = "cats";
$type = "orange";
</code>```

and would check these through the database.

But even if I go to "cool-domain.com" I still go to the same HTML page but the variables are left NULL.

Title: URL gives information to API/Backend

Body:
So let's say I have my registered domain hosted on Apache 2. Right.
Let's say

cool-domain.com

Now, I make a script which has the functionality to show all my users the same kind of background and frame and stuff, but each one gets a different picture of a cat or a dog.
So, if my user wants to see a dalmatian, he would enter:

cool-domain.com/dogs/dalmatian

Right, and if my user wants to see an orange cat, he would enter the following URL:

cool-domain.com/cats/orange

Now, I don't want to make a different HTML page for each cat and each dog. I want one html which changes the image source according to the URL.
So my PHP backend would remeber something among the lines of:

$species = "cats";
$type = "orange";

and would check these through the database.

But even if I go to "cool-domain.com" I still go to the same HTML page but the variables are left NULL.


问:
How to tell resteasy-reactive client that a @PathParam is already encoded?
I am using quarkus resteasy-reactive and setting up clients declaratively.

I need to put base64 (which works fine as URL path segments) data into  the path but the / chars get encoded into %2F causing the receiving application to fail parsing the data.

This PR: https://github.com/resteasy/resteasy/pull/945/files seems to allow @PathParam annotated client arguments to be annotated as @Encoded in order to deactivate their url encoding. But trying to use this in quarkus with resteasy-reactive seems to break. The below client definition will always encode / to %2F, whether @Encoded is there or not.

@RegisterRestClient(configKey = "urlpreview")
interface UrlPreviewClient {

  @GET
  @Path("/{b64url}.jpg")
  fun getImage(@Encoded b64url: String): Response
}
```
<p>I also tried the following client declarations:</p>
<pre class="lang-kotlin prettyprint-override"><code>@GET
@Path("/{b64url}.jpg")
fun getImage(b64url: String): Response
</code>```

@GET
@Path("/{b64url}.jpg")
fun getImage(@PathParam("b64url") @Encoded b64url: String): Response
```
<pre class="lang-kotlin prettyprint-override"><code>@GET
@Path("/{b64url:.*}.jpg")
fun getImage(@PathParam("b64url") @Encoded b64url: String): Response
</code>```

All encode / chars in b64url as %2F.

Body:
I am using quarkus resteasy-reactive and setting up clients declaratively.

I need to put base64 (which works fine as URL path segments) data into  the path but the / chars get encoded into %2F causing the receiving application to fail parsing the data.

This PR: https://github.com/resteasy/resteasy/pull/945/files seems to allow @PathParam annotated client arguments to be annotated as @Encoded in order to deactivate their url encoding. But trying to use this in quarkus with resteasy-reactive seems to break. The below client definition will always encode / to %2F, whether @Encoded is there or not.

@RegisterRestClient(configKey = "urlpreview")
interface UrlPreviewClient {

  @GET
  @Path("/{b64url}.jpg")
  fun getImage(@Encoded b64url: String): Response
}

I also tried the following client declarations:

@GET
@Path("/{b64url}.jpg")
fun getImage(b64url: String): Response

@GET
@Path("/{b64url}.jpg")
fun getImage(@PathParam("b64url") @Encoded b64url: String): Response

@GET
@Path("/{b64url:.*}.jpg")
fun getImage(@PathParam("b64url") @Encoded b64url: String): Response

All encode / chars in b64url as %2F.


问:
MC3050 - DataProtectionScope not found in System.Security.Cryptography in XAML
I'm designing a small encoding/decoding application that uses System.Configuration.Cryptography.ProtectedData methods at its core.

To let the user select the data protection scope, I've included radio buttons such as this one:

<RadioButton x:Name="rbtMachineScope"
             GroupName="rbgProtectionScope"
             IsChecked="{Binding Path=ProtectionScope, Converter={StaticResource EnumToBoolean}, ConverterParameter={x:Static crypto:DataProtectionScope.LocalMachine}}"
             Content="_Machine"/>
```
<p>Obviously, the XAML file begins like this:</p>
<pre class="lang-xml prettyprint-override"><code><Window x:Class="DecodeEncodeApp.MainWindow"
        xmlns:crypto="clr-namespace:System.Security.Cryptography;assembly=System.Core"
        DataContext="{Binding Path=EncryptionModule}">

    <Window.Resources>
        <!-- Converters -->
        <conv:EnumToBooleanConversion x:Key="EnumToBoolean" />
    </Window.Resources>
</code>```

(edited for brevity)

EncryptionModule is an object of the type TextEncryption:

    public class TextEncryption : INotifyPropertyChanged
    {
        public DataProtectionScope ProtectionScope;
    }
```

(In the interest of saving more space, trust me that ProtectionScope comes with a private field that is duly used in its get and set methods in such a way that bindings are possible. I've checked that.)

(Also, that EnumToBooleanConversion implements IValueConverter quite banally.)

Compiling gets the following message:
"Unknown build error, MC3050: type 'DataProtectionScope' not found." (Translated back from the local French, sorry if inaccurate.)

Except that in TextEncryption (that has using System.Security.Cryptography;), DataProtectionScope is found.

I use VS2019 and my project uses .Net 5.0.

What did I do wrong?

Body:
I'm designing a small encoding/decoding application that uses System.Configuration.Cryptography.ProtectedData methods at its core.

To let the user select the data protection scope, I've included radio buttons such as this one:

<RadioButton x:Name="rbtMachineScope"
             GroupName="rbgProtectionScope"
             IsChecked="{Binding Path=ProtectionScope, Converter={StaticResource EnumToBoolean}, ConverterParameter={x:Static crypto:DataProtectionScope.LocalMachine}}"
             Content="_Machine"/>

Obviously, the XAML file begins like this:

<Window x:Class="DecodeEncodeApp.MainWindow"
        xmlns:crypto="clr-namespace:System.Security.Cryptography;assembly=System.Core"
        DataContext="{Binding Path=EncryptionModule}">

    <Window.Resources>

        <conv:EnumToBooleanConversion x:Key="EnumToBoolean" />
    </Window.Resources>

(edited for brevity)

EncryptionModule is an object of the type TextEncryption:

    public class TextEncryption : INotifyPropertyChanged
    {
        public DataProtectionScope ProtectionScope;
    }

(In the interest of saving more space, trust me that ProtectionScope comes with a private field that is duly used in its get and set methods in such a way that bindings are possible. I've checked that.)

(Also, that EnumToBooleanConversion implements IValueConverter quite banally.)

Compiling gets the following message:
"Unknown build error, MC3050: type 'DataProtectionScope' not found." (Translated back from the local French, sorry if inaccurate.)

Except that in TextEncryption (that has using System.Security.Cryptography;), DataProtectionScope is found.

I use VS2019 and my project uses .Net 5.0.

What did I do wrong?


问:
How to make a Interactive NPC in C# console?
I have the code shown here, and I would like to make a Interactive NPC.

Basically end the player was like next to the NPC/letter, the player would be able to interact with it either by pressing a key for example "E" or just by being close to it and show some text in the console.

How could I do it? I'm new to C# so I don't have much knowledge about it. If anyone has any tutorial or could explain with coding I would appreciate it.

The code is:

```<code>namespace SoulfulDungeon
{
    class World
    {
        private string[,] Grid;
        private int Rows;
        private int Cols;

        public World(string[,] grid)
        {
            Grid = grid;
            Rows = Grid.GetLength(0);
            Cols = Grid.GetLength(1);
        }

        public void Draw()
        {
            for (int y = 0; y < Rows; y++)
            {
                for (int x = 0; x < Cols; x++)
                {
                    string element = Grid[y, x];
                    Console.SetCursorPosition(x, y);
                    Console.Write(element);
                }
            }

        }

        public string GetElementAt(int x, int y)
        {
            return Grid[y, x];
        }

        public string Trap(int x, int y)
        {
            return Grid[y, x];
        }

        public bool IsPositionWalkable(int x, int y)
        {
            //Verificar Limites
            if (x < 0 || y < 0 || x >= Cols || y >= Rows)
            {
                return false;
            }

            if (Lever.LeverMarker == "K")
            {
                    return Grid[y, x] == "(" || Grid[y, x] == " " || Grid[y, x] == "X" || Grid[y, x] == "T";

            }
            else if(Lever.LeverMarker != "K")
            {
                //Verificar locais de passagem
                return Grid[y, x] == " " || Grid[y, x] == "X" || Grid[y, x] == "T";
            }

            return false;
        }
    }

    public class SwitchDeath //metodo escolhas switch
    {
        public static int Variavel1;
        public static int Variavel2;

        public static void Choices()
        {
            bool Key = false; //escolha atravÃ©s de keys

            do
            {
                ConsoleKeyInfo keyReaded = Console.ReadKey(true);

                switch (keyReaded.Key)
                {
                    case ConsoleKey.Q:
                         Variavel1 = 1;
                         Key = true;
                         Console.WriteLine("You pulled the lever");
                         break;

                    case ConsoleKey.E:
                         Variavel2 = 1;
                         Key = true;
                         Console.WriteLine("You turned on the switch... a rain of arrows fell in your head...");
                         break;

                    default:
                         Console.WriteLine("You chose to stay still... The darkness consumed you and your conscience was washed away");
                         Variavel2 = 1;
                         Key = true;
                         break;
                }
            } while(!Key);

            if (Variavel1 == 1)
            {
                 Console.WriteLine("The room");
            }

            if (Variavel2 == 1)
            {
                Console.WriteLine("you died");
                Environment.Exit(0);
            }
        }
    }

    class Variables
    {
        public int X { get; set;}
        public int Y { get; set;}
        public static string? EnemyMarker;
        public static ConsoleColor EnemyColor;
        public static string? PlayerMarker;
        public static ConsoleColor PlayerColor;
        public static string? LeverMarker;
        public static ConsoleColor LeverColor;
        public static string? DoorMarker;
    }

    class Player : Variables
    {
        public Player( int initialX, int initialY)
        {
            X = initialX;
            Y = initialY;
            PlayerMarker = "0";
            PlayerColor = ConsoleColor.Blue;
        }

        public void Draw()
        {
            Console.ForegroundColor = PlayerColor;
            Console.SetCursorPosition(X, Y);
            Console.Write(PlayerMarker);
            Console.ResetColor();
        }
    }

    class Enemy : Variables
    {
        public Enemy( int initialX, int initialY)
        {
            X = initialX;
            Y = initialY;
            EnemyMarker = "5";
            EnemyColor = ConsoleColor.Red;
        }

        public void Draw()
        {
            Console.ForegroundColor = EnemyColor;
            Console.SetCursorPosition(X, Y);
            Console.Write(EnemyMarker);
            Console.ResetColor();
        }
    }

    class Lever : Variables
    {
        public Lever( int initialX, int initialY)
        {
            X = initialX;
            Y = initialY;
            LeverMarker = "k";
            LeverColor = ConsoleColor.Yellow;
        }

        public void Draw()
        {
            Console.ForegroundColor = LeverColor;
            Console.SetCursorPosition(X, Y);
            Console.Write(LeverMarker);
            Console.ResetColor();
        }
    }

    class Door : Variables
    {
        public Door( int initialX, int initialY)
        {
            X = initialX;
            Y = initialY;
            DoorMarker = " ";
        }

        public void Draw()
        {
            Console.SetCursorPosition(X, Y);
            Console.Write(DoorMarker);
        }
    }

    class Program
    {
        private static World?  MyWorld;
        private static Player? CurrentPlayer;
        private static Enemy? CurrentEnemy;
        private static Lever? CurrentLever;
        private static Door? CurrentDoor;

        public static void Main(string[] args)
        {
            Console.CursorVisible = false;
            Console.WriteLine("You found a lever and a switch :O");
            System.Threading.Thread.Sleep(150);
            Console.WriteLine("Choose: Press 'Q' to pull the lever | Press 'E' to turn the switch");
            SwitchDeath.Choices();

            string [,] grid = LevelParser.ParseFileToArray("Level0.txt");

            MyWorld = new World(grid);

            CurrentPlayer = new Player(0, 5);

            //CurrentEnemy = new Enemy(2, 1);

            CurrentLever = new Lever (11, 3);
            CurrentDoor = new Door (11, 6);

            RunGameLoop();
        }

        private static void DrawFrame()
        {
            Console.Clear();
            MyWorld!.Draw();
            CurrentPlayer!.Draw();
            CurrentLever!.Draw();

            if (Lever.LeverMarker == "K")
            {
                    CurrentDoor!.Draw();
                    CurrentPlayer!.Draw();
                    CurrentLever!.Draw();
            }
        }

        class Detection
        {
                public static void DetectionLever()
                {
                    if (CurrentPlayer is not null)
                    if (CurrentLever is not null)

                    if (CurrentPlayer.Y == CurrentLever.Y)
                    {
                        if (CurrentPlayer.X == CurrentLever.X)
                        {
                            Lever.LeverMarker = "K";
                            Lever.LeverColor = ConsoleColor.DarkYellow;
                        }
                    }
                }

                public static void DetectionEnemy()
                {
                    if (CurrentPlayer is not null)
                    if (CurrentEnemy is not null)
                    if (CurrentPlayer.Y == CurrentEnemy.Y)
                    {
                        if (CurrentPlayer.X == CurrentEnemy.X)
                        {
                            Console.Clear();
                            Console.WriteLine("You died... Don't touch the ghouls...");
                            CurrentPlayer = new Player(0, 5);
                            CurrentPlayer!.Draw();
                        }
                    }
                }
            }

            private static void HandlePlayerInput()
            {
                ConsoleKeyInfo keyInfo = Console.ReadKey(true);
                ConsoleKey key = keyInfo.Key;

                if (MyWorld is not null)
                if (CurrentPlayer is not null)

                switch (key)
                {
                    case ConsoleKey.UpArrow:
                        if (MyWorld.IsPositionWalkable(CurrentPlayer.X, CurrentPlayer.Y - 1))
                        {
                        CurrentPlayer.Y -= 1;
                        }
                        break;
                    case ConsoleKey.DownArrow:
                        if (MyWorld.IsPositionWalkable(CurrentPlayer.X, CurrentPlayer.Y + 1))
                        {
                        CurrentPlayer.Y += 1;
                        }
                        break;
                    case ConsoleKey.LeftArrow:
                        if (MyWorld.IsPositionWalkable(CurrentPlayer.X - 1 , CurrentPlayer.Y))
                        {
                        CurrentPlayer.X -= 1;
                        }
                        break;
                    case ConsoleKey.RightArrow:
                        if (MyWorld.IsPositionWalkable(CurrentPlayer.X + 1, CurrentPlayer.Y))
                        {
                        CurrentPlayer.X += 1;
                        }
                        break;
                    case ConsoleKey.E:
                        Console.Clear();
                        Environment.Exit(0);
                        break;
                    default:
                        break;
                }
            }

            private static void RunGameLoopEnemy()
            {
                if (MyWorld is not null)
                if(CurrentPlayer is not null)
                while(true)
                {
                    DrawFrame();

                    HandlePlayerInput();

                    Detection.DetectionLever();
                    Detection.DetectionEnemy();

                    string elementAtPlayerPros = MyWorld.GetElementAt(CurrentPlayer.X, CurrentPlayer.Y);
                    if (elementAtPlayerPros == "X")
                    {
                        Console.Clear();
                        break;
                    }
                     string Traps = MyWorld.Trap(CurrentPlayer.X, CurrentPlayer.Y);
                    if (Traps == "T")
                    {
                        Console.Clear();
                        break;
                    }

                    System.Threading.Thread.Sleep(20);
                }
            }
            private static void RunGameLoop()
            {
                if (MyWorld is not null)
                if(CurrentPlayer is not null)
                while(true)
                {
                    DrawFrame();

                    HandlePlayerInput();

                    Detection.DetectionLever();

                    string elementAtPlayerPros = MyWorld.GetElementAt(CurrentPlayer.X, CurrentPlayer.Y);
                    if (elementAtPlayerPros == "X")
                    {
                        Console.Clear();
                        break;
                    }
                     string Traps = MyWorld.Trap(CurrentPlayer.X, CurrentPlayer.Y);
                    if (Traps == "T")
                    {
                        Console.Clear();
                        break;
                    }

                    System.Threading.Thread.Sleep(20);
                }
            }
    }
}
</code>```

Didn't try anything yet because I don't really know how I could do it

Body:
I have the code shown here, and I would like to make a Interactive NPC.

Basically end the player was like next to the NPC/letter, the player would be able to interact with it either by pressing a key for example "E" or just by being close to it and show some text in the console.

How could I do it? I'm new to C# so I don't have much knowledge about it. If anyone has any tutorial or could explain with coding I would appreciate it.

The code is:

namespace SoulfulDungeon
{
    class World
    {
        private string[,] Grid;
        private int Rows;
        private int Cols;

        public World(string[,] grid)
        {
            Grid = grid;
            Rows = Grid.GetLength(0);
            Cols = Grid.GetLength(1);
        }

        public void Draw()
        {
            for (int y = 0; y < Rows; y++)
            {
                for (int x = 0; x < Cols; x++)
                {
                    string element = Grid[y, x];
                    Console.SetCursorPosition(x, y);
                    Console.Write(element);
                }
            }

        }

        public string GetElementAt(int x, int y)
        {
            return Grid[y, x];
        }

        public string Trap(int x, int y)
        {
            return Grid[y, x];
        }

        public bool IsPositionWalkable(int x, int y)
        {
            //Verificar Limites
            if (x < 0 || y < 0 || x >= Cols || y >= Rows)
            {
                return false;
            }

            if (Lever.LeverMarker == "K")
            {
                    return Grid[y, x] == "(" || Grid[y, x] == " " || Grid[y, x] == "X" || Grid[y, x] == "T";

            }
            else if(Lever.LeverMarker != "K")
            {
                //Verificar locais de passagem
                return Grid[y, x] == " " || Grid[y, x] == "X" || Grid[y, x] == "T";
            }

            return false;
        }
    }

    public class SwitchDeath //metodo escolhas switch
    {
        public static int Variavel1;
        public static int Variavel2;

        public static void Choices()
        {
            bool Key = false; //escolha atravÃ©s de keys

            do
            {
                ConsoleKeyInfo keyReaded = Console.ReadKey(true);

                switch (keyReaded.Key)
                {
                    case ConsoleKey.Q:
                         Variavel1 = 1;
                         Key = true;
                         Console.WriteLine("You pulled the lever");
                         break;

                    case ConsoleKey.E:
                         Variavel2 = 1;
                         Key = true;
                         Console.WriteLine("You turned on the switch... a rain of arrows fell in your head...");
                         break;

                    default:
                         Console.WriteLine("You chose to stay still... The darkness consumed you and your conscience was washed away");
                         Variavel2 = 1;
                         Key = true;
                         break;
                }
            } while(!Key);

            if (Variavel1 == 1)
            {
                 Console.WriteLine("The room");
            }

            if (Variavel2 == 1)
            {
                Console.WriteLine("you died");
                Environment.Exit(0);
            }
        }
    }

    class Variables
    {
        public int X { get; set;}
        public int Y { get; set;}
        public static string? EnemyMarker;
        public static ConsoleColor EnemyColor;
        public static string? PlayerMarker;
        public static ConsoleColor PlayerColor;
        public static string? LeverMarker;
        public static ConsoleColor LeverColor;
        public static string? DoorMarker;
    }

    class Player : Variables
    {
        public Player( int initialX, int initialY)
        {
            X = initialX;
            Y = initialY;
            PlayerMarker = "0";
            PlayerColor = ConsoleColor.Blue;
        }

        public void Draw()
        {
            Console.ForegroundColor = PlayerColor;
            Console.SetCursorPosition(X, Y);
            Console.Write(PlayerMarker);
            Console.ResetColor();
        }
    }

    class Enemy : Variables
    {
        public Enemy( int initialX, int initialY)
        {
            X = initialX;
            Y = initialY;
            EnemyMarker = "5";
            EnemyColor = ConsoleColor.Red;
        }

        public void Draw()
        {
            Console.ForegroundColor = EnemyColor;
            Console.SetCursorPosition(X, Y);
            Console.Write(EnemyMarker);
            Console.ResetColor();
        }
    }

    class Lever : Variables
    {
        public Lever( int initialX, int initialY)
        {
            X = initialX;
            Y = initialY;
            LeverMarker = "k";
            LeverColor = ConsoleColor.Yellow;
        }

        public void Draw()
        {
            Console.ForegroundColor = LeverColor;
            Console.SetCursorPosition(X, Y);
            Console.Write(LeverMarker);
            Console.ResetColor();
        }
    }

    class Door : Variables
    {
        public Door( int initialX, int initialY)
        {
            X = initialX;
            Y = initialY;
            DoorMarker = " ";
        }

        public void Draw()
        {
            Console.SetCursorPosition(X, Y);
            Console.Write(DoorMarker);
        }
    }

    class Program
    {
        private static World?  MyWorld;
        private static Player? CurrentPlayer;
        private static Enemy? CurrentEnemy;
        private static Lever? CurrentLever;
        private static Door? CurrentDoor;

        public static void Main(string[] args)
        {
            Console.CursorVisible = false;
            Console.WriteLine("You found a lever and a switch :O");
            System.Threading.Thread.Sleep(150);
            Console.WriteLine("Choose: Press 'Q' to pull the lever | Press 'E' to turn the switch");
            SwitchDeath.Choices();

            string [,] grid = LevelParser.ParseFileToArray("Level0.txt");

            MyWorld = new World(grid);

            CurrentPlayer = new Player(0, 5);

            //CurrentEnemy = new Enemy(2, 1);

            CurrentLever = new Lever (11, 3);
            CurrentDoor = new Door (11, 6);

            RunGameLoop();
        }

        private static void DrawFrame()
        {
            Console.Clear();
            MyWorld!.Draw();
            CurrentPlayer!.Draw();
            CurrentLever!.Draw();

            if (Lever.LeverMarker == "K")
            {
                    CurrentDoor!.Draw();
                    CurrentPlayer!.Draw();
                    CurrentLever!.Draw();
            }
        }

        class Detection
        {
                public static void DetectionLever()
                {
                    if (CurrentPlayer is not null)
                    if (CurrentLever is not null)

                    if (CurrentPlayer.Y == CurrentLever.Y)
                    {
                        if (CurrentPlayer.X == CurrentLever.X)
                        {
                            Lever.LeverMarker = "K";
                            Lever.LeverColor = ConsoleColor.DarkYellow;
                        }
                    }
                }

                public static void DetectionEnemy()
                {
                    if (CurrentPlayer is not null)
                    if (CurrentEnemy is not null)
                    if (CurrentPlayer.Y == CurrentEnemy.Y)
                    {
                        if (CurrentPlayer.X == CurrentEnemy.X)
                        {
                            Console.Clear();
                            Console.WriteLine("You died... Don't touch the ghouls...");
                            CurrentPlayer = new Player(0, 5);
                            CurrentPlayer!.Draw();
                        }
                    }
                }
            }

            private static void HandlePlayerInput()
            {
                ConsoleKeyInfo keyInfo = Console.ReadKey(true);
                ConsoleKey key = keyInfo.Key;

                if (MyWorld is not null)
                if (CurrentPlayer is not null)

                switch (key)
                {
                    case ConsoleKey.UpArrow:
                        if (MyWorld.IsPositionWalkable(CurrentPlayer.X, CurrentPlayer.Y - 1))
                        {
                        CurrentPlayer.Y -= 1;
                        }
                        break;
                    case ConsoleKey.DownArrow:
                        if (MyWorld.IsPositionWalkable(CurrentPlayer.X, CurrentPlayer.Y + 1))
                        {
                        CurrentPlayer.Y += 1;
                        }
                        break;
                    case ConsoleKey.LeftArrow:
                        if (MyWorld.IsPositionWalkable(CurrentPlayer.X - 1 , CurrentPlayer.Y))
                        {
                        CurrentPlayer.X -= 1;
                        }
                        break;
                    case ConsoleKey.RightArrow:
                        if (MyWorld.IsPositionWalkable(CurrentPlayer.X + 1, CurrentPlayer.Y))
                        {
                        CurrentPlayer.X += 1;
                        }
                        break;
                    case ConsoleKey.E:
                        Console.Clear();
                        Environment.Exit(0);
                        break;
                    default:
                        break;
                }
            }

            private static void RunGameLoopEnemy()
            {
                if (MyWorld is not null)
                if(CurrentPlayer is not null)
                while(true)
                {
                    DrawFrame();

                    HandlePlayerInput();

                    Detection.DetectionLever();
                    Detection.DetectionEnemy();

                    string elementAtPlayerPros = MyWorld.GetElementAt(CurrentPlayer.X, CurrentPlayer.Y);
                    if (elementAtPlayerPros == "X")
                    {
                        Console.Clear();
                        break;
                    }
                     string Traps = MyWorld.Trap(CurrentPlayer.X, CurrentPlayer.Y);
                    if (Traps == "T")
                    {
                        Console.Clear();
                        break;
                    }

                    System.Threading.Thread.Sleep(20);
                }
            }
            private static void RunGameLoop()
            {
                if (MyWorld is not null)
                if(CurrentPlayer is not null)
                while(true)
                {
                    DrawFrame();

                    HandlePlayerInput();

                    Detection.DetectionLever();

                    string elementAtPlayerPros = MyWorld.GetElementAt(CurrentPlayer.X, CurrentPlayer.Y);
                    if (elementAtPlayerPros == "X")
                    {
                        Console.Clear();
                        break;
                    }
                     string Traps = MyWorld.Trap(CurrentPlayer.X, CurrentPlayer.Y);
                    if (Traps == "T")
                    {
                        Console.Clear();
                        break;
                    }

                    System.Threading.Thread.Sleep(20);
                }
            }
    }
}

Didn't try anything yet because I don't really know how I could do it


问:
Connection refused (error 502) while adding SSH to the php-fpm
I'm using Docker for my Laravel application and now I have to add an SSH connection to the PHP-fpm container to set up Xdebug.

In the PHP docker file in the end if it's added CMD ["/usr/sbin/sshd","-D"] then I'm getting error 502 Bad Gateway.

This is the log:

```<code>2023-01-11 00:09:38 2023/01/10 23:09:38 [error] 22#22: *2 connect() failed (111: Connection refused) while connecting to upstream, client: 172.20.0.1, server: 127.0.0.1, request: "GET / HTTP/1.1", upstream: "fastcgi://172.20.0.2:9000", host: "localhost:8000"
</code>```

Also if I try to make an SSH connection from the CMD, then I'm getting next error:

```<code>kex_exchange_identification: Connection closed by remote host
</code>```

It looks like some collision with the ports, but I'm not sure.

docker-compose.yml

```<code>version: '3.8'

services:
  server:
    build:
      context: .
      dockerfile: dockerfiles/nginx.dockerfile
    ports:
      - '8000:80'
    volumes:
      - ./src:/var/www/html
      - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
    depends_on:
      - php
      - mysql
  php:
    build:
      context: .
      dockerfile: dockerfiles/php.dockerfile
    volumes:
      - ./src:/var/www/html
      - ./php/php-dev.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
  mysql:
    platform: linux/x86_64
    image: mysql:8.0
    ports:
      - '3306:3306'
    env_file:
      - ./env/mysql.env
  composer:
    build:
      context: ./dockerfiles
      dockerfile: composer.dockerfile
    volumes:
      - ./src:/var/www/html
  artisan:
    build:
      context: .
      dockerfile: dockerfiles/php.dockerfile
    volumes:
      - ./src:/var/www/html
    entrypoint: ["php", "/var/www/html/artisan"]
  npm:
    image: node:14
    working_dir: /var/www/html
    entrypoint: ["npm"]
    volumes:
      - ./src:/var/www/html
</code>```

php.dockerfile

```<code>FROM php:8.1-fpm-alpine

WORKDIR /var/www/html

COPY src .

RUN docker-php-ext-install pdo pdo_mysql

RUN apk add --update linux-headers \
    && apk add --no-cache $PHPIZE_DEPS \
    && pecl install xdebug \
    && docker-php-ext-enable xdebug

RUN apk --update add --no-cache openssh bash \
  && sed -i s/#PermitRootLogin.*/PermitRootLogin\ yes/ /etc/ssh/sshd_config \
  && echo "root:root" | chpasswd \
  && rm -rf /var/cache/apk/* \
  && sed -ie 's/#Port 22/Port 2000/g' /etc/ssh/sshd_config \
  && sed -ri 's/#HostKey \/etc\/ssh\/ssh_host_key/HostKey \/etc\/ssh\/ssh_host_key/g' /etc/ssh/sshd_config \
  && sed -ir 's/#HostKey \/etc\/ssh\/ssh_host_rsa_key/HostKey \/etc\/ssh\/ssh_host_rsa_key/g' /etc/ssh/sshd_config \
  && sed -ir 's/#HostKey \/etc\/ssh\/ssh_host_dsa_key/HostKey \/etc\/ssh\/ssh_host_dsa_key/g' /etc/ssh/sshd_config \
  && sed -ir 's/#HostKey \/etc\/ssh\/ssh_host_ecdsa_key/HostKey \/etc\/ssh\/ssh_host_ecdsa_key/g' /etc/ssh/sshd_config \
  && sed -ir 's/#HostKey \/etc\/ssh\/ssh_host_ed25519_key/HostKey \/etc\/ssh\/ssh_host_ed25519_key/g' /etc/ssh/sshd_config \
  && /usr/bin/ssh-keygen -A \
  && ssh-keygen -t rsa -b 4096 -f  /etc/ssh/ssh_host_key

CMD ["/usr/sbin/sshd","-D"]

#RUN sed -i 's/127.0.0.1:9000/0.0.0.0:9000/g' /usr/local/etc/php-fpm.d/www.conf
</code>```

ngingx.dockerfile

```<code>FROM nginx:stable-alpine

WORKDIR /etc/nginx/conf.d

COPY nginx/nginx.conf .

RUN mv nginx.conf default.conf

WORKDIR /var/www/html

COPY src .
</code>```

ngingx.conf

```<code>server {
    listen 80;
    index index.php index.html;
    server_name 127.0.0.1;
    root /var/www/html/public;
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}
</code>```

Body:
I'm using Docker for my Laravel application and now I have to add an SSH connection to the PHP-fpm container to set up Xdebug.

In the PHP docker file in the end if it's added CMD ["/usr/sbin/sshd","-D"] then I'm getting error 502 Bad Gateway.

This is the log:

2023-01-11 00:09:38 2023/01/10 23:09:38 [error] 22#22: *2 connect() failed (111: Connection refused) while connecting to upstream, client: 172.20.0.1, server: 127.0.0.1, request: "GET / HTTP/1.1", upstream: "fastcgi://172.20.0.2:9000", host: "localhost:8000"

Also if I try to make an SSH connection from the CMD, then I'm getting next error:

kex_exchange_identification: Connection closed by remote host

It looks like some collision with the ports, but I'm not sure.

docker-compose.yml

version: '3.8'

services:
  server:
    build:
      context: .
      dockerfile: dockerfiles/nginx.dockerfile
    ports:
      - '8000:80'
    volumes:
      - ./src:/var/www/html
      - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
    depends_on:
      - php
      - mysql
  php:
    build:
      context: .
      dockerfile: dockerfiles/php.dockerfile
    volumes:
      - ./src:/var/www/html
      - ./php/php-dev.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
  mysql:
    platform: linux/x86_64
    image: mysql:8.0
    ports:
      - '3306:3306'
    env_file:
      - ./env/mysql.env
  composer:
    build:
      context: ./dockerfiles
      dockerfile: composer.dockerfile
    volumes:
      - ./src:/var/www/html
  artisan:
    build:
      context: .
      dockerfile: dockerfiles/php.dockerfile
    volumes:
      - ./src:/var/www/html
    entrypoint: ["php", "/var/www/html/artisan"]
  npm:
    image: node:14
    working_dir: /var/www/html
    entrypoint: ["npm"]
    volumes:
      - ./src:/var/www/html

php.dockerfile

FROM php:8.1-fpm-alpine

WORKDIR /var/www/html

COPY src .

RUN docker-php-ext-install pdo pdo_mysql

RUN apk add --update linux-headers \
    && apk add --no-cache $PHPIZE_DEPS \
    && pecl install xdebug \
    && docker-php-ext-enable xdebug

RUN apk --update add --no-cache openssh bash \
  && sed -i s/#PermitRootLogin.*/PermitRootLogin\ yes/ /etc/ssh/sshd_config \
  && echo "root:root" | chpasswd \
  && rm -rf /var/cache/apk/* \
  && sed -ie 's/#Port 22/Port 2000/g' /etc/ssh/sshd_config \
  && sed -ri 's/#HostKey \/etc\/ssh\/ssh_host_key/HostKey \/etc\/ssh\/ssh_host_key/g' /etc/ssh/sshd_config \
  && sed -ir 's/#HostKey \/etc\/ssh\/ssh_host_rsa_key/HostKey \/etc\/ssh\/ssh_host_rsa_key/g' /etc/ssh/sshd_config \
  && sed -ir 's/#HostKey \/etc\/ssh\/ssh_host_dsa_key/HostKey \/etc\/ssh\/ssh_host_dsa_key/g' /etc/ssh/sshd_config \
  && sed -ir 's/#HostKey \/etc\/ssh\/ssh_host_ecdsa_key/HostKey \/etc\/ssh\/ssh_host_ecdsa_key/g' /etc/ssh/sshd_config \
  && sed -ir 's/#HostKey \/etc\/ssh\/ssh_host_ed25519_key/HostKey \/etc\/ssh\/ssh_host_ed25519_key/g' /etc/ssh/sshd_config \
  && /usr/bin/ssh-keygen -A \
  && ssh-keygen -t rsa -b 4096 -f  /etc/ssh/ssh_host_key

CMD ["/usr/sbin/sshd","-D"]

#RUN sed -i 's/127.0.0.1:9000/0.0.0.0:9000/g' /usr/local/etc/php-fpm.d/www.conf

ngingx.dockerfile

FROM nginx:stable-alpine

WORKDIR /etc/nginx/conf.d

COPY nginx/nginx.conf .

RUN mv nginx.conf default.conf

WORKDIR /var/www/html

COPY src .

ngingx.conf

server {
    listen 80;
    index index.php index.html;
    server_name 127.0.0.1;
    root /var/www/html/public;
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}


问:
Why does mapOf() with multiple types of keys return a Map with an `out` key parameter?
In Kotlin 1.7.0,

```<code>mapOf("s" to "s2", 0 to 5)
</code>```

gives this response in the ki REPL:

```<code>res1: Map<out Any, Any> = {s=s2, 0=5}
</code>```

My question is, why is the key parameter out (covariant)? Normally I might not care, but I'm trying to understand Kotlin generics, and specifically how variance works.

According to the docs, the signature for mapOf() is

```<code>fun <K, V> mapOf(vararg pairs: Pair<K, V>): Map<K, V>
</code>```

I can understand that in order to cover both String and Int types, the K type parameter has to be Any. But why out? And why out for K and not for V?

If we try a mutable map, we get out for both:

```<code>mutableMapOf("s" to "s2", 0 to 5)
</code>```

gives

```<code>MutableMap<out Any, out Any>
</code>```

This makes even less sense to me. At least K is consistent with V in both being out. But now we can't add or change any of the mappings in our mutable map, because keys and values are both of a "producer" type:

```<code>val m2  = mutableMapOf("s" to "s2", 0 to 5)
[10] m2.put(3 to 6)
ERROR Type mismatch: inferred type is Pair<Int, Int> but Nothing was expected (Line_11.kts:1:8)
ERROR No value passed for parameter 'value' (Line_11.kts:1:14)
[15] m2[3] = "fi"
ERROR The integer literal does not conform to the expected type CapturedType(out Any) (Line_16.kts:1:4)
ERROR Type mismatch: inferred type is String but CapturedType(out Any) was expected (Line_16.kts:1:9)
</code>```

We can fixed this by explicitly specifying the type parameters of our mutable map:

```<code>val m3: MutableMap<Any, Any> = mutableMapOf(3 to 4, "a" to "b")
</code>```

But I'm wondering why these parameters in the inferred type are out. Is this intentional, or is it an unfortunate side effect of the generics system?

Update:

When I try something similar in the IDE, the out annotation is apparently not generated:

```<code>val myMap = mutableMapOf("s" to "s2", 0 to 5)
myMap[3] = 7
</code>```

The IDE says the type of myMap is MutableMap<{Comparable*> & java.io.Serializable}, {Comparable*> & java.io.Serializable}>, as Tenfour04 also said in the comments. The ability to assign myMap[3] = 7 shows that the key is not annotated out. So I'm guessing that the out comes from something unique to the ki shell, or from Kotlin 1.7.0 (whereas the IDE seems to be running Kotlin 1.7.20).

Update 2:

I've now run this in a Kotlin scratch file in Android Studio (under Kotlin 1.7.20, on JVM). The following are local variables in main():

```<code>val m = mapOf("s" to "s2", 0 to 5)
printType(m)
val mm = mutableMapOf("s" to "s2", 0 to 5)
mm[3] = 7
printType(mm)
</code>```

I'm using the printType() function that @broot linked to in comments:

```<code>import kotlin.reflect.typeOf
inline fun <reified T> printType(obj: T) {
    println(typeOf<T>())
}
</code>```

The results:

```<code>res1: Map<out Any, Any> = {s=s2, 0=5}
</code>```0

These are the same results I described at the beginning of the question.

This seems to me to show that the out annotation is not coming from something specific to the ki shell, nor from Kotlin 1.7.0.

Body:
In Kotlin 1.7.0,

mapOf("s" to "s2", 0 to 5)

gives this response in the ki REPL:

res1: Map<out Any, Any> = {s=s2, 0=5}

My question is, why is the key parameter out (covariant)? Normally I might not care, but I'm trying to understand Kotlin generics, and specifically how variance works.

According to the docs, the signature for mapOf() is

fun <K, V> mapOf(vararg pairs: Pair<K, V>): Map<K, V>

I can understand that in order to cover both String and Int types, the K type parameter has to be Any. But why out? And why out for K and not for V?

If we try a mutable map, we get out for both:

mutableMapOf("s" to "s2", 0 to 5)

gives

MutableMap<out Any, out Any>

This makes even less sense to me. At least K is consistent with V in both being out. But now we can't add or change any of the mappings in our mutable map, because keys and values are both of a "producer" type:

val m2  = mutableMapOf("s" to "s2", 0 to 5)
[10] m2.put(3 to 6)
ERROR Type mismatch: inferred type is Pair<Int, Int> but Nothing was expected (Line_11.kts:1:8)
ERROR No value passed for parameter 'value' (Line_11.kts:1:14)
[15] m2[3] = "fi"
ERROR The integer literal does not conform to the expected type CapturedType(out Any) (Line_16.kts:1:4)
ERROR Type mismatch: inferred type is String but CapturedType(out Any) was expected (Line_16.kts:1:9)

We can fixed this by explicitly specifying the type parameters of our mutable map:

val m3: MutableMap<Any, Any> = mutableMapOf(3 to 4, "a" to "b")

But I'm wondering why these parameters in the inferred type are out. Is this intentional, or is it an unfortunate side effect of the generics system?

Update:

When I try something similar in the IDE, the out annotation is apparently not generated:

val myMap = mutableMapOf("s" to "s2", 0 to 5)
myMap[3] = 7

The IDE says the type of myMap is MutableMap<{Comparable*> & java.io.Serializable}, {Comparable*> & java.io.Serializable}>, as Tenfour04 also said in the comments. The ability to assign myMap[3] = 7 shows that the key is not annotated out. So I'm guessing that the out comes from something unique to the ki shell, or from Kotlin 1.7.0 (whereas the IDE seems to be running Kotlin 1.7.20).

Update 2:

I've now run this in a Kotlin scratch file in Android Studio (under Kotlin 1.7.20, on JVM). The following are local variables in main():

val m = mapOf("s" to "s2", 0 to 5)
printType(m)
val mm = mutableMapOf("s" to "s2", 0 to 5)
mm[3] = 7
printType(mm)

I'm using the printType() function that @broot linked to in comments:

import kotlin.reflect.typeOf
inline fun <reified T> printType(obj: T) {
    println(typeOf<T>())
}

The results:

kotlin.collections.Map<out kotlin.Any, kotlin.Any>
kotlin.collections.MutableMap<out kotlin.Any, out kotlin.Any>

These are the same results I described at the beginning of the question.

This seems to me to show that the out annotation is not coming from something specific to the ki shell, nor from Kotlin 1.7.0.


问:
Custom Post Type rewrite rules and category slug
I am using a plugin that registers a CPT with the following args.

```<code>$event_category_args = array(
        'label'                 => __( 'Event categories'),
        'labels'                => $event_category_labels,
        'show_in_rest'          => true,
        'public'                => true,
        'show_in_nav_menus'     => true,
        'show_ui'               => true,
        'show_in_menu'          => false,
        'show_tagcloud'         => true,
        'hierarchical'          => true,
        'update_count_callback' => '',
        'rewrite'               => array(
            'slug'         => $permalinks['event_category_base'], //'plugin/category'
            'with_front'   => false,
            'hierarchical' => true
        ),
        'capabilities'          => array(),
        'meta_box_cb'           => null,
        'show_admin_column'     => false,
        '_builtin'              => false,
        'show_in_quick_edit'    => null,
    );

$event_tag_args = array(
        'label'                 => __( 'Event tags' ),
        'labels'                => $event_tag_labels,
        'show_in_rest'          => true,
        'public'                => true,
        'show_in_nav_menus'     => true,
        'show_ui'               => true,
        'show_in_menu'          => false,
        'show_tagcloud'         => true,
        'hierarchical'          => false,
        'update_count_callback' => '',
        'rewrite'               => array(
            'slug'         => $permalinks['event_tag_base'], //'plugin/tag'
            'with_front'   => false,
            'hierarchical' => true
        ),
        'capabilities'          => array(),
        'meta_box_cb'           => null,
        'show_admin_column'     => false,
        '_builtin'              => false,
        'show_in_quick_edit'    => null,
    );

  $event_args = array(
    'labels'                => $event_labels,
    'public'            => true,
                'show_in_rest'      => true,
                'show_ui'           => true,
                'show_in_menu'      => false,
                'show_in_nav_menus' => true,
                'capability_type'   => 'post',
                'menu_position'     => 21,
                'hierarchical'      => false,
                'has_archive'       => true,
                'rewrite'           => array(
                    'slug'         => $permalinks['event_base'], //'plugin/event'
                    'with_front'   => false,
                    'hierarchical' => true
                ),
                'supports'          => array( 'title', 'editor', 'comments', 'excerpt', 'author', 'thumbnail', 'page-attributes' ),
                'show_in_admin_bar' => true
);

$column_args = array(
    'labels'                => $column_labels,
    'public'            => true,
                'show_in_rest'      => true,
                'show_ui'           => true,
                'show_in_menu'      => false,
                'show_in_nav_menus' => true,
                'capability_type'   => 'post',
                'menu_position'     => 21,
                'hierarchical'      => false,
                'has_archive'       => true,
                'rewrite'           => array(
                    'slug'         => $permalinks['column_base'], //'plugin/column'
                    'with_front'   => false,
                    'hierarchical' => true
                ),
                'supports'          => array( 'title', 'editor', 'comments', 'excerpt', 'author', 'thumbnail', 'page-attributes' ),
                'show_in_admin_bar' => true
);
</code>```

The plugin is forcing me to use the following permalink base structure in order to work.

Column base => shows/day  (the structure: plugin/column, for example mydomain.com/shows/day/monday)

Event base => shows/show (the structure: plugin/event for example mydomain.com/shows/show/letsrock)

Event Category base =>shows/category (the structure: plugin/category)

Event Tag base => shows/tag (the structure: plugin/tag)

I also have a simple WordPress page with slug mydomain.com/shows/

What i am trying to archive is how can i have this base result working in my CPT permalinks structure

Column base => shows/day

Event base => shows

Event Category base =>shows/category

Event Tag base => shows/tag

I am trying to change the 'rewrite' rules in all args registrations, but i am struggling to get it working. Could someone please help me.

Body:
I am using a plugin that registers a CPT with the following args.

$event_category_args = array(
        'label'                 => __( 'Event categories'),
        'labels'                => $event_category_labels,
        'show_in_rest'          => true,
        'public'                => true,
        'show_in_nav_menus'     => true,
        'show_ui'               => true,
        'show_in_menu'          => false,
        'show_tagcloud'         => true,
        'hierarchical'          => true,
        'update_count_callback' => '',
        'rewrite'               => array(
            'slug'         => $permalinks['event_category_base'], //'plugin/category'
            'with_front'   => false,
            'hierarchical' => true
        ),
        'capabilities'          => array(),
        'meta_box_cb'           => null,
        'show_admin_column'     => false,
        '_builtin'              => false,
        'show_in_quick_edit'    => null,
    );

$event_tag_args = array(
        'label'                 => __( 'Event tags' ),
        'labels'                => $event_tag_labels,
        'show_in_rest'          => true,
        'public'                => true,
        'show_in_nav_menus'     => true,
        'show_ui'               => true,
        'show_in_menu'          => false,
        'show_tagcloud'         => true,
        'hierarchical'          => false,
        'update_count_callback' => '',
        'rewrite'               => array(
            'slug'         => $permalinks['event_tag_base'], //'plugin/tag'
            'with_front'   => false,
            'hierarchical' => true
        ),
        'capabilities'          => array(),
        'meta_box_cb'           => null,
        'show_admin_column'     => false,
        '_builtin'              => false,
        'show_in_quick_edit'    => null,
    );

  $event_args = array(
    'labels'                => $event_labels,
    'public'            => true,
                'show_in_rest'      => true,
                'show_ui'           => true,
                'show_in_menu'      => false,
                'show_in_nav_menus' => true,
                'capability_type'   => 'post',
                'menu_position'     => 21,
                'hierarchical'      => false,
                'has_archive'       => true,
                'rewrite'           => array(
                    'slug'         => $permalinks['event_base'], //'plugin/event'
                    'with_front'   => false,
                    'hierarchical' => true
                ),
                'supports'          => array( 'title', 'editor', 'comments', 'excerpt', 'author', 'thumbnail', 'page-attributes' ),
                'show_in_admin_bar' => true
);

$column_args = array(
    'labels'                => $column_labels,
    'public'            => true,
                'show_in_rest'      => true,
                'show_ui'           => true,
                'show_in_menu'      => false,
                'show_in_nav_menus' => true,
                'capability_type'   => 'post',
                'menu_position'     => 21,
                'hierarchical'      => false,
                'has_archive'       => true,
                'rewrite'           => array(
                    'slug'         => $permalinks['column_base'], //'plugin/column'
                    'with_front'   => false,
                    'hierarchical' => true
                ),
                'supports'          => array( 'title', 'editor', 'comments', 'excerpt', 'author', 'thumbnail', 'page-attributes' ),
                'show_in_admin_bar' => true
);

The plugin is forcing me to use the following permalink base structure in order to work.

Column base => shows/day  (the structure: plugin/column, for example mydomain.com/shows/day/monday)

Event base => shows/show (the structure: plugin/event for example mydomain.com/shows/show/letsrock)

Event Category base =>shows/category (the structure: plugin/category)

Event Tag base => shows/tag (the structure: plugin/tag)

I also have a simple WordPress page with slug mydomain.com/shows/

What i am trying to archive is how can i have this base result working in my CPT permalinks structure

Column base => shows/day

Event base => shows

Event Category base =>shows/category

Event Tag base => shows/tag

I am trying to change the 'rewrite' rules in all args registrations, but i am struggling to get it working. Could someone please help me.


问:
VSCode highlight color for {braces} in python non-f-string (often an error)?
Editing Python source in VSCode, I notice some color themes highlight use of {braces like this} in non-f-strings. Others don't.

Such highlighting is useful - it often marks error where the string was supposed be an f-string but isn't.

The "Dark+ (default dark)" theme looks like this:

The "Dark (Visual Studio)" theme looks like this (same color for plain string and brace):

How can I change the highlight color for {foo2} in the color theme? I want to make it much more prominent so I'll notice it.

I think changing this requires something in editor.tokenColorCustomizations in settings.json, but what setting in there corresponds to the {foo2} syntax?


问:
Segmentation fault when cross compiling Windows compatible .exe from Linux development env
I use a Linux environment for code development and testing of a program and now I want to compile an Windows ".exe" file so that my program can run on Windows OS, after some internet research I tried to modified my makefile to use x86_64-w64-mingw32-g++ instead of g++ as its compiler but now I get a segmentation fault at the end of the compilation and I am not sure how to debug this. My makefile is below:

```<code>PROGRAM=output.exe
COMPILER=x86_64-w64-mingw32-g++
# PROGRAM=output
# COMPILER=g++
#BIN_FOLDER=bin

DEPS += Defs.h Structs.h

CXXFLAGS+=`sdl2-config --cflags`
CXXFLAGS+=-DVERSION=$(VERSION) -DREVISION=$(REVISION) -DDATA_DIR=\"$(DATA_DIR)\"
CXXFLAGS+=-Wall -Wempty-body -Werror -Werror=maybe-uninitialized -Warray-bounds
CXXFLAGS+=-g -lefence -std=c++20 -fopenmp

LDFLAGS+=-L/usr/local/lib -lSDL2 -lSDL2_mixer -lSDL2_image -lSDL2_ttf -fopenmp src/ECS/*.cpp #-pg

FILENAME:=  $(patsubst %.cpp,%.o,$(wildcard src/*.cpp))

$(PROGRAM):$(FILENAME)
    $(COMPILER) $(FILENAME) -o $@ $(LDFLAGS)

clean:
    rm src/*.o
</code>```

this compiles without a problem in g++ but when using the mingw32 compiler I get this error:

```<code>x86_64-w64-mingw32-g++ src/ActionManager.o src/AStar.o ...[a bunch of .o files] -o output.exe
collect2: fatal error: ld terminated with signal 11 [Segmentation fault], core dumped
compilation terminated.
make: *** [makefile:26: output.exe] Error 1
</code>```

I tried compiling a simple helloWorld.cpp program using x86_64-w64-mingw32-g++ like this: x86_64-w64-mingw32-g++ 01_hello_world.c -o windowshello.exe and that works fine.

I also tried deleting all my LDFLAGS just to see what would happen and I get the same result.

Could anyone point me into the right direction as to how I might debug this? Is this a particular part of my code that is causing this or am I going about this entirely wrong?

Body:
I use a Linux environment for code development and testing of a program and now I want to compile an Windows ".exe" file so that my program can run on Windows OS, after some internet research I tried to modified my makefile to use x86_64-w64-mingw32-g++ instead of g++ as its compiler but now I get a segmentation fault at the end of the compilation and I am not sure how to debug this. My makefile is below:

PROGRAM=output.exe
COMPILER=x86_64-w64-mingw32-g++
# PROGRAM=output
# COMPILER=g++
#BIN_FOLDER=bin

DEPS += Defs.h Structs.h

CXXFLAGS+=`sdl2-config --cflags`
CXXFLAGS+=-DVERSION=$(VERSION) -DREVISION=$(REVISION) -DDATA_DIR=\"$(DATA_DIR)\"
CXXFLAGS+=-Wall -Wempty-body -Werror -Werror=maybe-uninitialized -Warray-bounds
CXXFLAGS+=-g -lefence -std=c++20 -fopenmp

LDFLAGS+=-L/usr/local/lib -lSDL2 -lSDL2_mixer -lSDL2_image -lSDL2_ttf -fopenmp src/ECS/*.cpp #-pg

FILENAME:=  $(patsubst %.cpp,%.o,$(wildcard src/*.cpp))

$(PROGRAM):$(FILENAME)
    $(COMPILER) $(FILENAME) -o $@ $(LDFLAGS)

clean:
    rm src/*.o

this compiles without a problem in g++ but when using the mingw32 compiler I get this error:

x86_64-w64-mingw32-g++ src/ActionManager.o src/AStar.o ...[a bunch of .o files] -o output.exe
collect2: fatal error: ld terminated with signal 11 [Segmentation fault], core dumped
compilation terminated.
make: *** [makefile:26: output.exe] Error 1

I tried compiling a simple helloWorld.cpp program using x86_64-w64-mingw32-g++ like this: x86_64-w64-mingw32-g++ 01_hello_world.c -o windowshello.exe and that works fine.

I also tried deleting all my LDFLAGS just to see what would happen and I get the same result.

Could anyone point me into the right direction as to how I might debug this? Is this a particular part of my code that is causing this or am I going about this entirely wrong?